Imported Upstream version 3.3.2 upstream/3.3.2
authorBdale Garbee <bdale@gag.com>
Mon, 8 Oct 2012 23:45:26 +0000 (17:45 -0600)
committerBdale Garbee <bdale@gag.com>
Mon, 8 Oct 2012 23:45:26 +0000 (17:45 -0600)
501 files changed:
ChangeLog
FULL_VERSION
Makefile.am
Makefile.in
NEWS
ReleaseNotes
VERSION
aclocal.m4
amandad-src/Makefile.in
amandad-src/amandad.c
amandad-src/amandad.h
amar-src/Makefile.in
amar-src/amar.c
amar-src/amar.h
amar-src/amarchiver.c
amplot/Makefile.in
application-src/Makefile.in
application-src/amgtar.c
application-src/amlog-script.pl
application-src/ampgsql.pl
application-src/amraw.pl
application-src/amsamba.pl
application-src/amstar.c
application-src/amsuntar.pl
application-src/amzfs-sendrecv.pl
application-src/amzfs-snapshot.pl
application-src/script-email.pl
changer-src/Makefile.in
client-src/Makefile.in
client-src/amdump_client.pl
client-src/calcsize.c
client-src/client_util.c
client-src/client_util.h
client-src/selfcheck.c
client-src/sendbackup-dump.c
client-src/sendbackup-gnutar.c
client-src/sendbackup.c
client-src/sendsize.c
common-src/Makefile.am
common-src/Makefile.in
common-src/am_sl.c [new file with mode: 0644]
common-src/am_sl.h [new file with mode: 0644]
common-src/amaespipe.sh
common-src/amcryptsimple.pl
common-src/amflock.c
common-src/amgetconf.pl
common-src/amgpgcrypt.pl
common-src/amsemaphore-test.c
common-src/amsemaphore.c
common-src/amsemaphore.h
common-src/amxml.c
common-src/amxml.h
common-src/conffile.c
common-src/conffile.h
common-src/directtcp.h
common-src/event-test.c
common-src/event.c
common-src/fileheader-test.c
common-src/fileheader.c
common-src/glib-util.c
common-src/glib-util.h
common-src/ipc-binary.c
common-src/ipc-binary.h
common-src/match-test.c
common-src/match.c
common-src/match.h
common-src/quoting-test.c
common-src/security-util.c
common-src/simpleprng.c
common-src/simpleprng.h
common-src/sl.c [deleted file]
common-src/sl.h [deleted file]
common-src/sockaddr-util.c
common-src/sockaddr-util.h
common-src/ssh-security.c
common-src/svn-info.h
common-src/testutils.c
common-src/testutils.h
common-src/timestamp.c
common-src/util.c
common-src/util.h
config/Makefile.in
config/amanda/libs.m4
config/amanda/progs.m4
config/amanda/version.m4
config/automake/scripts.am
config/automake/vars.am
config/config.h.in
config/macro-archive/docbook-dtd.m4
config/macro-archive/docbook-xslt-min.m4
config/macro-archive/docbook-xslt.m4
config/macro-archive/xsltproc.m4
configure
configure.in
device-src/Makefile.in
device-src/amdevcheck.pl
device-src/amtapetype.pl
device-src/device.c
device-src/device.h
device-src/directtcp-connection.c
device-src/directtcp-connection.h
device-src/ndmp-device.c
device-src/null-device.c
device-src/property.c
device-src/property.h
device-src/rait-device.c
device-src/s3-device.c
device-src/s3-util.c
device-src/s3-util.h
device-src/s3.c
device-src/s3.h
device-src/tape-device.c
device-src/vfs-device.c
device-src/vfs-device.h
device-src/xfer-dest-device.c
device-src/xfer-dest-taper-cacher.c
device-src/xfer-dest-taper-directtcp.c
device-src/xfer-dest-taper-splitter.c
device-src/xfer-dest-taper.c
device-src/xfer-dest-taper.h
device-src/xfer-device.h
device-src/xfer-source-device.c
device-src/xfer-source-recovery.c
example/Makefile.in
gnulib/Makefile.in
installcheck/=setupcache.pl
installcheck/Amanda_Archive.pl
installcheck/Amanda_Changer.pl
installcheck/Amanda_Changer_compat.pl
installcheck/Amanda_Changer_disk.pl
installcheck/Amanda_Changer_multi.pl
installcheck/Amanda_Changer_ndmp.pl
installcheck/Amanda_Changer_null.pl
installcheck/Amanda_Changer_rait.pl
installcheck/Amanda_Changer_robot.pl
installcheck/Amanda_Changer_single.pl
installcheck/Amanda_ClientService.pl
installcheck/Amanda_Cmdline.pl
installcheck/Amanda_Config.pl
installcheck/Amanda_Config_FoldingHash.pl
installcheck/Amanda_Curinfo.pl
installcheck/Amanda_DB_Catalog.pl
installcheck/Amanda_Debug.pl
installcheck/Amanda_Device.pl
installcheck/Amanda_Disklist.pl
installcheck/Amanda_Feature.pl
installcheck/Amanda_Header.pl
installcheck/Amanda_Holding.pl
installcheck/Amanda_IPC_Binary.pl
installcheck/Amanda_IPC_LineProtocol.pl
installcheck/Amanda_Logfile.pl
installcheck/Amanda_MainLoop.pl
installcheck/Amanda_NDMP.pl
installcheck/Amanda_Process.pl
installcheck/Amanda_Recovery_Clerk.pl
installcheck/Amanda_Recovery_Planner.pl
installcheck/Amanda_Recovery_Scan.pl
installcheck/Amanda_Report.pl
installcheck/Amanda_Tapelist.pl
installcheck/Amanda_Taper_Scan_lexical.pl
installcheck/Amanda_Taper_Scan_oldest.pl
installcheck/Amanda_Taper_Scan_traditional.pl
installcheck/Amanda_Taper_Scribe.pl
installcheck/Amanda_Util.pl
installcheck/Amanda_Xfer.pl
installcheck/Installcheck.pm
installcheck/Installcheck/Application.pm
installcheck/Installcheck/Catalogs.pm
installcheck/Installcheck/Changer.pm
installcheck/Installcheck/ClientService.pm
installcheck/Installcheck/Config.pm
installcheck/Installcheck/Dumpcache.pm
installcheck/Installcheck/Mock.pm
installcheck/Installcheck/Run.pm
installcheck/Makefile.in
installcheck/amadmin.pl
installcheck/amarchiver.pl
installcheck/amcheck-device.pl
installcheck/amcheck.pl
installcheck/amcheckdump.pl
installcheck/amdevcheck.pl
installcheck/amdump.pl
installcheck/amdump_client.pl
installcheck/amfetchdump.pl
installcheck/amflush.pl
installcheck/amgetconf.pl
installcheck/amgtar.pl
installcheck/amidxtaped.pl
installcheck/amlabel.pl
installcheck/amoverview.pl
installcheck/ampgsql.pl
installcheck/amraw.pl
installcheck/amrecover.pl
installcheck/amreport.pl
installcheck/amrestore.pl
installcheck/amrmtape.pl
installcheck/amserverconfig.pl
installcheck/amservice.pl
installcheck/amstatus.pl
installcheck/amtape.pl
installcheck/amtapetype.pl
installcheck/amvault.pl
installcheck/bigint.pl
installcheck/catalogs/bigdb.cat
installcheck/catalogs/bigestimate.cat
installcheck/catalogs/doublefailure.cat
installcheck/catalogs/filesystemstaped.cat
installcheck/catalogs/longstrange.cat
installcheck/catalogs/multi-taper.cat
installcheck/catalogs/normal.cat
installcheck/catalogs/plannerfail.cat
installcheck/catalogs/resultsmissing.cat
installcheck/catalogs/retried-nofinish.cat
installcheck/catalogs/retried-strange.cat
installcheck/catalogs/retried.cat
installcheck/catalogs/shortstrange.cat
installcheck/catalogs/skipped.cat
installcheck/catalogs/spanned.cat
installcheck/catalogs/strontium.cat
installcheck/chunker.pl
installcheck/example.pl
installcheck/gnutar.pl
installcheck/mock/lpr.pl
installcheck/mock/mail.pl
installcheck/mock/mtx.pl
installcheck/mock_mtx.pl
installcheck/noop.pl
installcheck/pp-scripts.pl
installcheck/run-ndmp.pl
installcheck/taper.pl
man/Makefile.in
man/amaddclient.8
man/amadmin.8
man/amaespipe.8
man/amanda-applications.7
man/amanda-archive-format.5
man/amanda-auth.7
man/amanda-changers.7
man/amanda-client.conf.5
man/amanda-compatibility.7
man/amanda-devices.7
man/amanda-interactivity.7
man/amanda-match.7
man/amanda-scripts.7
man/amanda-taperscan.7
man/amanda.8
man/amanda.conf.5
man/amarchiver.8
man/amcheck.8
man/amcheckdb.8
man/amcheckdump.8
man/amcleanup.8
man/amcleanupdisk.8
man/amcrypt-ossl-asym.8
man/amcrypt-ossl.8
man/amcrypt.8
man/amcryptsimple.8
man/amdevcheck.8
man/amdump.8
man/amdump_client.8
man/amfetchdump.8
man/amflush.8
man/amgetconf.8
man/amgpgcrypt.8
man/amgtar.8
man/amlabel.8
man/amoverview.8
man/ampgsql.8
man/amplot.8
man/amraw.8
man/amrecover.8
man/amreport.8
man/amrestore.8
man/amrmtape.8
man/amsamba.8
man/amserverconfig.8
man/amservice.8
man/amstar.8
man/amstatus.8
man/amsuntar.8
man/amtape.8
man/amtapetype.8
man/amtoc.8
man/amvault.8
man/amzfs-sendrecv.8
man/amzfs-snapshot.8
man/disklist.5
man/script-email.8
man/tapelist.5
man/xml-source/amadmin.8.xml
man/xml-source/amanda-devices.7.xml
man/xml-source/amanda.conf.5.xml
man/xml-source/amfetchdump.8.xml
man/xml-source/amgtar.8.xml
man/xml-source/amzfs-sendrecv.8.xml
man/xml-source/disklist.5.xml
ndmp-src/Makefile.in
ndmp-src/ndmjob_args.c
ndmp-src/ndmos.h
ndmp-src/ndmos_glib.h
ndmp-src/ndmp4_translate.c
ndmp-src/ndmp_translate.h
ndmp-src/ndmpconnobj.c
ndmp-src/ndmpconnobj.h
oldrecover-src/Makefile.in
packaging/Makefile.in
packaging/common/common_functions.sh
packaging/common/mock_utils.sh
packaging/common/post_inst_functions.sh
packaging/common/post_rm_functions.sh
packaging/common/pre_inst_functions.sh
packaging/common/test_sh_libs.sh
packaging/deb/amanda-backup-client.postinst
packaging/deb/amanda-backup-client.postrm
packaging/deb/amanda-backup-server.postinst
packaging/deb/amanda-backup-server.postrm
packaging/deb/buildpkg
packaging/deb/postinst.src [new file with mode: 0644]
packaging/deb/postrm [deleted file]
packaging/deb/postrm.src [new file with mode: 0755]
packaging/deb/preinst [deleted file]
packaging/deb/preinst.src [new file with mode: 0755]
packaging/deb/rules
packaging/rpm/amanda.spec.src
packaging/rpm/buildpkg
packaging/sun-pkg/buildpkg
packaging/sun-pkg/client/postinstall.src
packaging/sun-pkg/client/postremove.src
packaging/sun-pkg/client/preinstall.src
packaging/sun-pkg/server/postinstall.src
packaging/sun-pkg/server/postremove.src
packaging/sun-pkg/server/preinstall.src
perl/Amanda/Application.pm
perl/Amanda/Application.pod
perl/Amanda/Application.swg
perl/Amanda/Application/Zfs.pm
perl/Amanda/Archive.pod
perl/Amanda/Archive.swg
perl/Amanda/BigIntCompat.pm
perl/Amanda/Changer.pm
perl/Amanda/Changer/aggregate.pm
perl/Amanda/Changer/compat.pm
perl/Amanda/Changer/disk.pm
perl/Amanda/Changer/multi.pm
perl/Amanda/Changer/ndmp.pm
perl/Amanda/Changer/null.pm
perl/Amanda/Changer/rait.pm
perl/Amanda/Changer/robot.pm
perl/Amanda/Changer/single.pm
perl/Amanda/ClientService.pm
perl/Amanda/Cmdline.pod
perl/Amanda/Cmdline.swg
perl/Amanda/Config.c
perl/Amanda/Config.pm
perl/Amanda/Config.pod
perl/Amanda/Config.swg
perl/Amanda/Constants.pm.in
perl/Amanda/Curinfo.pm
perl/Amanda/Curinfo/Info.pm
perl/Amanda/DB/Catalog.pm
perl/Amanda/Debug.pod
perl/Amanda/Debug.swg
perl/Amanda/Device.c
perl/Amanda/Device.pm
perl/Amanda/Device.pod
perl/Amanda/Device.swg
perl/Amanda/Disklist.pod
perl/Amanda/Disklist.swg
perl/Amanda/Feature.pod
perl/Amanda/Feature.swg
perl/Amanda/Header.c
perl/Amanda/Header.pm
perl/Amanda/Header.pod
perl/Amanda/Header.swg
perl/Amanda/Holding.pm
perl/Amanda/IPC/Binary.pod
perl/Amanda/IPC/Binary.swg
perl/Amanda/IPC/LineProtocol.pm
perl/Amanda/Interactivity.pm
perl/Amanda/Interactivity/email.pm
perl/Amanda/Interactivity/stdin.pm
perl/Amanda/Interactivity/tty.pm
perl/Amanda/Interactivity/tty_email.pm
perl/Amanda/Logfile.pod
perl/Amanda/Logfile.swg
perl/Amanda/MainLoop.pod
perl/Amanda/MainLoop.swg
perl/Amanda/NDMP.pod
perl/Amanda/NDMP.swg
perl/Amanda/Paths.pm.in
perl/Amanda/Process.pm
perl/Amanda/Recovery/Clerk.pm
perl/Amanda/Recovery/Planner.pm
perl/Amanda/Recovery/Scan.pm
perl/Amanda/Report.pm
perl/Amanda/Report/human.pm
perl/Amanda/Report/postscript.pm
perl/Amanda/Report/xml.pm
perl/Amanda/ScanInventory.pm
perl/Amanda/Script.pm
perl/Amanda/Script_App.pm
perl/Amanda/Tapelist.c
perl/Amanda/Tapelist.pod
perl/Amanda/Tapelist.swg
perl/Amanda/Taper/Controller.pm
perl/Amanda/Taper/Protocol.pm
perl/Amanda/Taper/Scan.pm
perl/Amanda/Taper/Scan/lexical.pm
perl/Amanda/Taper/Scan/oldest.pm
perl/Amanda/Taper/Scan/traditional.pm
perl/Amanda/Taper/Scribe.pm
perl/Amanda/Taper/Worker.pm
perl/Amanda/Tests.pod
perl/Amanda/Tests.swg
perl/Amanda/Util.c
perl/Amanda/Util.pod
perl/Amanda/Util.swg
perl/Amanda/Xfer.pod
perl/Amanda/Xfer.swg
perl/Amanda/XferServer.c
perl/Amanda/XferServer.pm
perl/Amanda/XferServer.pod
perl/Amanda/XferServer.swg
perl/Makefile.am
perl/Makefile.in
perl/amglue/Makefile.in
perl/amglue/amglue.h
perl/amglue/amglue.swg
perl/amglue/bigint.c
perl/amglue/constants.swg
perl/amglue/directtcp.swg
perl/amglue/dumpspecs.swg
perl/amglue/exports.swg
perl/amglue/filehandles.swg
perl/amglue/ghashtable.c
perl/amglue/glib.swg
perl/amglue/integers.swg
perl/amglue/objwrap.c
perl/amglue/source.c
perl/amglue/xferwrap.c
po/Makefile.in
recover-src/Makefile.in
recover-src/extract_list.c
server-src/Makefile.in
server-src/amaddclient.pl
server-src/amadmin.c
server-src/amcheck-device.pl
server-src/amcheckdump.pl
server-src/amcleanup.pl
server-src/amcleanupdisk.pl
server-src/amdump.pl
server-src/amdumpd.pl
server-src/amfetchdump.pl
server-src/amidxtaped.pl
server-src/amindexd.c
server-src/amlabel.pl
server-src/amlogroll.pl
server-src/amoverview.pl
server-src/amreport.pl
server-src/amrestore.pl
server-src/amrmtape.pl
server-src/amserverconfig.pl
server-src/amstatus.pl
server-src/amtape.pl
server-src/amvault.pl
server-src/cmdline.c
server-src/cmdline.h
server-src/diskfile.c
server-src/diskfile.h
server-src/driver.c
server-src/driverio.c
server-src/dumper.c
server-src/find.c
server-src/planner.c
server-src/tapefile.c
server-src/taper.pl
server-src/xfer-server.h
server-src/xfer-source-holding.c
xfer-src/Makefile.in
xfer-src/amxfer.h
xfer-src/dest-buffer.c
xfer-src/dest-directtcp-connect.c
xfer-src/dest-directtcp-listen.c
xfer-src/dest-fd.c
xfer-src/dest-null.c
xfer-src/element-glue.c
xfer-src/element-glue.h
xfer-src/filter-process.c
xfer-src/filter-xor.c
xfer-src/source-directtcp-connect.c
xfer-src/source-directtcp-listen.c
xfer-src/source-fd.c
xfer-src/source-pattern.c
xfer-src/source-random.c
xfer-src/xfer-element.c
xfer-src/xfer-element.h
xfer-src/xfer-test.c
xfer-src/xfer.c
xfer-src/xfer.h
xfer-src/xmsg.c
xfer-src/xmsg.h

index d7f5466d31e3f7af2aa52ba02e3b9a02c99c3316..743f5638673e317353c73ec0669d5f7298552934 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,809 @@
+2012-07-24  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: New REUSE-CONNECTION property.
+       * device-src/s3.c: Do not reuse connection if REUSE-CONNECTION is
+         FALSE.
+       * device-src/s3.h (s3_open): New reuse_connection argument.
+       * man/xml-source/amanda-devices.7.xml: Document REUSE-CONNECTION
+         property.
+       * ReleaseNotes, NEWS: Add REUSE-CONNECTION.
+
+2012-07-24  Jean-Louis Martineau <martineau@zmanda.com>
+       * VERSION: 3.3.2
+
+2012-07-24  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: Fix a big memory leak.
+
+2012-07-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amanda.conf.5.xml: Typo.
+
+2012-07-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * ReleaseNotes, NEWS: Add new features in 3.3.2.
+
+2012-07-20 Dan Locks <dwlocks@zmanda.com>
+       * perl/Amanda/Feature.pod, perl/Amanda/MainLoop.swg,
+         perl/Amanda/Script.pm, perl/Amanda/NDMP.pod,
+         perl/Amanda/Logfile.swg, perl/Amanda/Curinfo.pm,
+         perl/Amanda/Changer.pm, perl/Amanda/Tests.pod,
+         perl/Amanda/Application.pod, perl/Amanda/Debug.swg,
+         perl/Amanda/Disklist.swg, perl/Amanda/Report.pm,
+         perl/Amanda/Config.pod, perl/Amanda/Header.swg,
+         perl/Amanda/Feature.swg, perl/Amanda/BigIntCompat.pm,
+         perl/Amanda/NDMP.swg, perl/Amanda/Recovery/Scan.pm,
+         perl/Amanda/Recovery/Planner.pm, perl/Amanda/Recovery/Clerk.pm,
+         perl/Amanda/Util.pod, perl/Amanda/Tests.swg,
+         perl/Amanda/Archive.pod, perl/Amanda/Application.swg,
+         perl/Amanda/Config.swg, perl/Amanda/Curinfo/Info.pm,
+         perl/Amanda/Tapelist.pod, perl/Amanda/Changer/disk.pm,
+         perl/Amanda/Changer/multi.pm, perl/Amanda/Changer/null.pm,
+         perl/Amanda/Changer/ndmp.pm, perl/Amanda/Changer/rait.pm,
+         perl/Amanda/Changer/single.pm, perl/Amanda/Changer/compat.pm,
+         perl/Amanda/Changer/robot.pm, perl/Amanda/Changer/aggregate.pm,
+         perl/Amanda/Report/human.pm, perl/Amanda/Report/postscript.pm,
+         perl/Amanda/Report/xml.pm, perl/Amanda/IPC/Binary.swg,
+         perl/Amanda/IPC/LineProtocol.pm, perl/Amanda/IPC/Binary.pod,
+         perl/Amanda/XferServer.pod, perl/Amanda/Util.swg,
+         perl/Amanda/ScanInventory.pm, perl/Amanda/Script_App.pm,
+         perl/Amanda/Device.pod, perl/Amanda/Archive.swg,
+         perl/Amanda/Tapelist.swg, perl/Amanda/Xfer.pod,
+         perl/Amanda/DB/Catalog.pm, perl/Amanda/Process.pm,
+         perl/Amanda/XferServer.swg, perl/Amanda/Constants.pm.in,
+         perl/Amanda/Cmdline.pod, perl/Amanda/Device.swg,
+         perl/Amanda/Interactivity/stdin.pm,
+         perl/Amanda/Interactivity/email.pm,
+         perl/Amanda/Interactivity/tty_email.pm,
+         perl/Amanda/Interactivity/tty.pm, perl/Amanda/MainLoop.pod,
+         perl/Amanda/Holding.pm, perl/Amanda/Paths.pm.in,
+         perl/Amanda/Logfile.pod, perl/Amanda/Application/Zfs.pm,
+         perl/Amanda/Xfer.swg, perl/Amanda/Debug.pod,
+         perl/Amanda/Disklist.pod, perl/Amanda/Interactivity.pm,
+         perl/Amanda/Header.pod, perl/Amanda/Cmdline.swg,
+         perl/Amanda/ClientService.pm, perl/Amanda/Taper/Protocol.pm,
+         perl/Amanda/Taper/Controller.pm, perl/Amanda/Taper/Scan.pm,
+         perl/Amanda/Taper/Scribe.pm, perl/Amanda/Taper/Scan/oldest.pm,
+         perl/Amanda/Taper/Scan/traditional.pm,
+         perl/Amanda/Taper/Scan/lexical.pm,
+         perl/Amanda/Taper/Worker.pm, perl/amglue/objwrap.c,
+         perl/amglue/bigint.c, perl/amglue/amglue.h,
+         perl/amglue/dumpspecs.swg, perl/amglue/exports.swg,
+         perl/amglue/amglue.swg, perl/amglue/constants.swg,
+         perl/amglue/glib.swg, perl/amglue/filehandles.swg,
+         perl/amglue/integers.swg, perl/amglue/xferwrap.c,
+         perl/amglue/directtcp.swg, perl/amglue/source.c,
+         perl/amglue/ghashtable.c, perl/make_html.pl,
+         installcheck/amoverview.pl, installcheck/Amanda_Holding.pl,
+         installcheck/Amanda_Disklist.pl,
+         installcheck/Amanda_Taper_Scan_oldest.pl,
+         installcheck/amlabel.pl, installcheck/Amanda_NDMP.pl,
+         installcheck/amflush.pl, installcheck/Amanda_ClientService.pl,
+         installcheck/run-ndmp.pl, installcheck/amstatus.pl,
+         installcheck/Amanda_Taper_Scribe.pl,
+         installcheck/Amanda_Recovery_Scan.pl,
+         installcheck/Amanda_Curinfo.pl, installcheck/Amanda_Changer.pl,
+         installcheck/Amanda_Changer_single.pl,
+         installcheck/Amanda_Taper_Scan_traditional.pl,
+         installcheck/bigint.pl, installcheck/Amanda_Cmdline.pl,
+         installcheck/Amanda_Changer_robot.pl, installcheck/amservice.pl,
+         installcheck/Amanda_Recovery_Clerk.pl,
+         installcheck/Amanda_Taper_Scan_lexical.pl,
+         installcheck/amarchiver.pl, installcheck/amrecover.pl,
+         installcheck/Amanda_Changer_ndmp.pl,
+         installcheck/Installcheck/ClientService.pm,
+         installcheck/Installcheck/Application.pm,
+         installcheck/Installcheck/Run.pm,
+         installcheck/Installcheck/Config.pm,
+         installcheck/Installcheck/Changer.pm,
+         installcheck/Installcheck/Dumpcache.pm,
+         installcheck/Installcheck/Mock.pm,
+         installcheck/Installcheck/Catalogs.pm, installcheck/example.pl,
+         installcheck/gnutar.pl, installcheck/amrestore.pl,
+         installcheck/amgetconf.pl, installcheck/pp-scripts.pl,
+         installcheck/Amanda_IPC_LineProtocol.pl, installcheck/amtape.pl,
+         installcheck/amraw.pl, installcheck/amserverconfig.pl,
+         installcheck/amgtar.pl, installcheck/taper.pl,
+         installcheck/Amanda_Util.pl,
+         installcheck/Amanda_Recovery_Planner.pl,
+         installcheck/mock/mail.pl, installcheck/mock/mtx.pl,
+         installcheck/mock/lpr.pl, installcheck/Amanda_IPC_Binary.pl,
+         installcheck/=setupcache.pl, installcheck/amcheckdump.pl,
+         installcheck/amdump_client.pl, installcheck/Amanda_Tapelist.pl,
+         installcheck/Amanda_Debug.pl, installcheck/Amanda_Changer_rait.pl,
+         installcheck/amcheck-device.pl, installcheck/Amanda_Header.pl,
+         installcheck/amdevcheck.pl, installcheck/Amanda_Device.pl,
+         installcheck/Amanda_Changer_null.pl, installcheck/ampgsql.pl,
+         installcheck/Installcheck.pm, installcheck/amadmin.pl,
+         installcheck/amvault.pl, installcheck/Amanda_Changer_compat.pl,
+         installcheck/Amanda_Report.pl, installcheck/amidxtaped.pl,
+         installcheck/mock_mtx.pl, installcheck/Amanda_Changer_disk.pl,
+         installcheck/Amanda_Logfile.pl,
+         installcheck/Amanda_Changer_multi.pl,
+         installcheck/amdump.pl, installcheck/catalogs/bigdb.cat,
+         installcheck/amreport.pl, installcheck/amcheck.pl,
+         installcheck/Amanda_Feature.pl, installcheck/amfetchdump.pl,
+         installcheck/chunker.pl, installcheck/Amanda_Xfer.pl,
+         installcheck/amrmtape.pl, installcheck/Amanda_Config.pl,
+         installcheck/amtapetype.pl, installcheck/noop.pl,
+         installcheck/Amanda_Config_FoldingHash.pl,
+         installcheck/Amanda_Process.pl,
+         installcheck/Amanda_MainLoop.pl, installcheck/Amanda_DB_Catalog.pl,
+         installcheck/Amanda_Archive.pl, amar-src/amar.c,
+         amar-src/amarchiver.c, amar-src/amar.h,
+         config/automake/scripts.am, config/automake/vars.am,
+         config/macro-archive/docbook-xslt.m4,
+         config/macro-archive/docbook-dtd.m4,
+         config/macro-archive/docbook-xslt-min.m4,
+         config/macro-archive/xsltproc.m4,
+         common-src/directtcp.h, common-src/amgetconf.pl,
+         common-src/sockaddr-util.c, common-src/sockaddr-util.h,
+         common-src/glib-util.c, common-src/glib-util.h,
+         common-src/ipc-binary.c, common-src/event-test.c,
+         common-src/ipc-binary.h, common-src/match-test.c,
+         common-src/amsemaphore-test.c, common-src/simpleprng.c,
+         common-src/simpleprng.h, common-src/amsemaphore.c,
+         common-src/quoting-test.c, common-src/fileheader-test.c,
+         common-src/amsemaphore.h, common-src/amcryptsimple.pl,
+         common-src/amaespipe.sh, common-src/testutils.c,
+         common-src/match.h, common-src/testutils.h,
+         common-src/amgpgcrypt.pl, application-src/script-email.pl,
+         application-src/amsuntar.pl, application-src/amzfs-snapshot.pl,
+         application-src/amlog-script.pl, application-src/amsamba.pl,
+         application-src/ampgsql.pl, application-src/amraw.pl,
+         application-src/amzfs-sendrecv.pl, contrib/amreport.rnc,
+         client-src/amdump_client.pl, ndmp-src/ndmpconnobj.c,
+         ndmp-src/ndmpconnobj.h, device-src/xfer-device.h,
+         device-src/s3-device.c, device-src/property.c,
+         device-src/s3.c, device-src/property.h,
+         device-src/xfer-dest-taper-directtcp.c, device-src/s3.h,
+         device-src/rait-device.c, device-src/device.c,
+         device-src/amtapetype.pl, device-src/device.h,
+         device-src/null-device.c, device-src/xfer-dest-taper.c,
+         device-src/directtcp-connection.c,
+         device-src/xfer-dest-taper-splitter.c,
+         device-src/xfer-dest-taper.h, device-src/amdevcheck.pl,
+         device-src/directtcp-connection.h, device-src/tape-device.c,
+         device-src/ndmp-device.c, device-src/vfs-device.c,
+         device-src/xfer-dest-taper-cacher.c, device-src/xfer-dest-device.c,
+         device-src/xfer-source-recovery.c, device-src/xfer-source-device.c,
+         device-src/s3-util.c, device-src/vfs-device.h,
+         device-src/s3-util.h, packaging/rpm/amanda.spec.src,
+         xfer-src/xfer-element.h, xfer-src/filter-process.c,
+         xfer-src/xfer.c, xfer-src/dest-directtcp-connect.c,
+         xfer-src/dest-buffer.c, xfer-src/source-directtcp-connect.c,
+         xfer-src/dest-null.c, xfer-src/xfer.h,
+         xfer-src/dest-directtcp-listen.c, xfer-src/source-pattern.c,
+         xfer-src/source-directtcp-listen.c, xfer-src/source-random.c,
+         xfer-src/xmsg.c, xfer-src/xfer-test.c,
+         xfer-src/xmsg.h, xfer-src/element-glue.c,
+         xfer-src/dest-fd.c, xfer-src/amxfer.h,
+         xfer-src/source-fd.c, xfer-src/element-glue.h,
+         xfer-src/filter-xor.c, xfer-src/xfer-element.c,
+         server-src/amcheckdump.pl, server-src/amoverview.pl,
+         server-src/amdumpd.pl, server-src/amcheck-device.pl,
+         server-src/amlogroll.pl, server-src/xfer-source-holding.c,
+         server-src/amlabel.pl, server-src/amvault.pl,
+         server-src/amcleanupdisk.pl, server-src/amidxtaped.pl,
+         server-src/cmdline.c, server-src/amdump.pl,
+         server-src/xfer-server.h, server-src/cmdline.h,
+         server-src/amreport.pl, server-src/amfetchdump.pl,
+         server-src/amrestore.pl, server-src/amcleanup.pl,
+         server-src/amaddclient.pl, server-src/amrmtape.pl,
+         server-src/amtape.pl, server-src/amserverconfig.pl,
+         server-src/taper.pl: update copyright dates
+
+2012-07-20  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/timestamp.c (get_time_from_timestamp): Initialize to 0.
+
+2012-07-19  Jean-Louis Martineau <martineau@zmanda.com>
+       Patch by crocket
+       * perl/Makefile.am: Fix cygwin build.
+
+2012-07-18  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Parse application/json reply from cloudena.
+
+2012-07-18  Jean-Louis Martineau <martineau@zmanda.com>
+       * installcheck/Amanda_IPC_LineProtocol.pl: Add synchonization to fix
+         race.
+
+2012-07-17  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amcheckdump.pl: Wait for all filters to terminate before
+         going to next image.  Do not use '--ignore-zeros' for SMBCLIENT
+         backup.  Pass the dump size to $xfer->start().
+       * server-src/amfetchdump.pl: Wait for all filters to terminate before
+         going to next image.
+
+2012-07-16  Dan Locks <dwlocks@zmanda.com>
+       * packaging/sun-pkg/buildpkg:
+       * packaging/sun-pkg/client/postremove.src,
+         packaging/sun-pkg/server/postremove.src: remove redundant usage of
+         basedir.
+       * packaging/sun-pkg/client/postinstall.src,
+         packaging/sun-pkg/server/postinstall.src: same as above, plus fix
+         case statement.
+       * packaging/sun-pkg/server/preinstall.src,
+         packaging/sun-pkg/client/preinstall.src: remove redundant basedir,
+         use new check_user_* functions.
+
+2012-07-16  Dan Locks <dwlocks@zmanda.com>
+       * packaging/rpm/amanda.spec.src: refactor to use common functions
+       * packaging/rpm/buildpkg: check for ./configure, and exit if
+         substitute.pl fails.
+
+2012-07-16  Dan Locks <dwlocks@zmanda.com>
+       * packaging/deb/rules: use FULL_VERSION file to fill AMVER var, use
+       * concatenation trick for postinst, rm trailing whitespace
+       * packaging/deb/buildpkg: process postinst.src postrm.src preinst.src with substitute.pl
+       * packaging/deb/postinst.src: refactor to use common functions.
+       * packaging/deb/amanda-backup-server.postrm,
+         packaging/deb/amanda-backup-client.postrm,
+         packaging/deb/amanda-backup-client.postinst,
+         packaging/deb/amanda-backup-server.postinst: delete everything, add
+         variables pkg_type and other_pkg_type.
+       * packaging/deb/preinst: moved to...
+       * packaging/deb/preinst.src: here. refactor using common functions
+       * packaging/deb/postrm: moved to...
+       * packaging/deb/postrm.src: here. refactor using common functions.
+
+2012-07-16  Dan Locks <dwlocks@zmanda.com>
+       * packaging/common/common_functions.sh: remove trailing whitespace,
+         remove redundant usage of ${BASEDIR} in solaris functions, avoid
+         potentially non-portable test invocations.
+       * packaging/common/test_sh_libs.sh: fix some log messages, redirect
+         some unused output, split check_user_* tests into shorter testsr,
+         add tests for supplemental groups, fix running single test.
+       * packaging/common/mock_utils.sh: change id to error if any flags are
+         given, add mock for groups.
+       * packaging/common/post_inst_functions.sh: remove redundant leading /
+       * packaging/common/post_rm_functions.sh: rm trailing whitespace.
+       * packaging/common/pre_inst_functions.sh: use variable for user
+         shell, clarify log messages regarding user accounts, split
+         check_user into separate functions, mostly to ease testing, add
+         check_user_supplemental_group.
+
+2012-07-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: Do not free ca_info if use_ssl is not set.
+       * device-src/s3.c:: Set CURLOPT_CAINFO even if use_ssl is not set.
+
+2012-07-10  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amstatus.pl: Print 'dump done' if the dump succeeded.
+
+2012-07-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/conffile.c (val_t_display_strs): Add a print_unit argument.
+       * common-src/conffile.h (val_t_display_strs): Change prototype.
+       * perl/Amanda/Config.swg (getconf_byname_strs): Use val_t_display_strs
+         with a FALSE print_unit.
+
+2012-07-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/conffile.c: Correctly parse byte suffix.
+       * common-src/conffile.h: Add confunit_t.
+       * installcheck/amgetconf.pl: Fix for byte parsing.
+
+2012-07-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driver.c (tape_action): Fix for flush_*.
+         Change debug level.
+
+2012-06-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Taper/Scan/traditional.pm,
+         perl/Amanda/Taper/Scribe.pm: Correctly report error.
+
+2012-06-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/glib-util.c: Add initialization code for openssl and
+         gnutls.
+       * config/amanda/libs.m4: Detect ssl library used by libcurl.
+
+2012-06-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Fix compiler warning.
+
+2012-06-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Renew swift v2 x-auth-token before it expires, use
+         glib if >= 2.26.
+
+2012-06-27 Dan Locks <dwlocks@zmanda.com>
+       * configure.in: update ac_prereq to 2.64
+
+2012-06-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: remove code to Renew swift v2 x-auth-token, it
+         require glib 2.26.
+
+2012-06-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: New CREATE-BUCKET property.
+       * device-src/s3.c: Improving error message parsing.
+       * man/xml-source/amanda-devices.7.xml: document new CREATE-BUCKET
+         property.
+
+2012-06-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Remove bogus code.
+
+2012-06-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Renew swift v2 x-auth-token before it expires.
+
+2012-06-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/conffile.c: Fix crash when parsing an invalid config file.
+
+2012-06-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Cloudena do not have xml_version of html tag in
+         their reply.
+
+2012-06-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Renew OAUTH2 token.
+
+2012-06-21  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Report/human.pm: Change the default columspec to: HostName=0:-12:12,Disk=1:-11:11,Level=1:-1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1
+       * man/xml-source/amanda.conf.5.xml: Document new default columnspec.
+       * installcheck/catalogs/bigestimate.cat,
+         installcheck/catalogs/doublefailure.cat,
+         installcheck/catalogs/filesystemstaped.cat,
+         installcheck/catalogs/longstrange.cat,
+         installcheck/catalogs/multi-taper.cat,
+         installcheck/catalogs/normal.cat,
+         installcheck/catalogs/plannerfail.cat,
+         installcheck/catalogs/resultsmissing.cat,
+         installcheck/catalogs/retried-nofinish.cat,
+         installcheck/catalogs/retried-strange.cat,
+         installcheck/catalogs/retried.cat,
+         installcheck/catalogs/shortstrange.cat,
+         installcheck/catalogs/skipped.cat,
+         installcheck/catalogs/spanned.cat,
+         installcheck/catalogs/strontium.cat: fix for new default columnspec.
+
+2012-06-21  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: OAUTH2 use 'max-keys'.
+
+2012-06-20  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Taper/Worker.pm: Fix update of the status file.
+
+2012-06-20  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c: Fix memory corruption.
+
+2012-06-20  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Taper/Scribe.pm: Cancel call dump_cb.
+       * perl/Amanda/Taper/Worker.pm: Cancel the header xfer.
+
+2012-06-20  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/planner.c: Fix 32 bits overflow.
+
+2012-06-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c, common-src/amxml.c,
+         common-src/security-util.c, common-src/util.c,
+         server-src/tapefile.c: Fix small memory leak.
+       * perl/Amanda/Config.swg: Mark amandaify_property_name as %newobject
+       * perl/Amanda/Header.swg: Mark C_from_string as %newobject
+       * perl/Amanda/Tapelist.swg: Mark list_new_tapes as %newobject
+       * perl/Amanda/Util.swg: Mark sanitise_filename, quote_string,
+         unquote_string and split_quoted_strings as %newobject
+       * xfer-src/xfer-element.c: lock elt->xfer->status_mutex before looking
+         at elt->xfer->status.
+       * device-src/device.h (Device): Add a GMutex device_mutex to protect
+         method with concurent access.
+       * device-src/device.c, device-src/ndmp-device.c,
+         device-src/null-device.c, device-src/rait-device.c,
+         device-src/s3-device.c, device-src/tape-device.c,
+         device-src/vfs-device.c: Use the mutex to protext some Device field.
+
+2012-06-18  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/planner.c: Coorectly delay full dump if it doesn't fit in
+         the schedule.
+
+2012-06-14 Dan Locks <dwlocks@zmanda.com>
+       * packaging/common/mock_utils.sh: update id mock to handle -Gn flags,
+         add groupadd mock, add usermod mock, correct silent errors in inetd
+         and install mocks
+       * packaging/common/pre_inst_functions.sh: add_group now attempts to
+         create a potentially missing suppmemental group, add_group does not
+         use -A or -a, instead generates a list of current groups from id -Gn,
+         update error_group_member to use the name of the group passed to
+         add_group.
+       * packaging/common/test_sh_libs.sh: add 2 add_group unit tests, update
+         check_user_group test.
+
+2012-06-13  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amgtar.c: Check gtar support --no-check-device.
+
+2012-06-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Changer/aggregate.pm, perl/Amanda/Changer/disk.pm,
+         perl/Amanda/Changer/ndmp.pm perl/Amanda/Changer/rait.pm,
+         perl/Amanda/Changer/robot.pm, perl/Amanda/Changer/single.pm,
+         perl/Amanda/Chunker/Controller.pm, perl/Amanda/Chunker/Scribe.pm,
+         perl/Amanda/Recovery/Clerk.pm, perl/Amanda/Recovery/Planner.pm,
+         perl/Amanda/Recovery/Scan.pm, perl/Amanda/Report/human.pm,
+         perl/Amanda/Taper/Scribe.pm,
+         perl/Amanda/Taper/Worker.pm: Change many die by confess.
+
+2012-06-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Parse message attribute in cloudena error reply.
+         Parse details in HP error reply.
+
+2012-06-04  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amrestore.pl: Typo.
+
+2012-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amrestore.pl: Use the blocksize argument.
+
+2012-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Changer/robot.pm: Print to debug if bc2lb change the
+         label for a barcode. Print to debug the mtx output.
+       * perl/Amanda/Taper/Scribe.pm: Do not use a tape if the barcode from
+         tapelist differ from the changer.
+
+2012-05-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amzfs-sendrecv.pl: fix print_to_server argument.
+
+2012-05-24  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amsamba.pl: Do not send a chomped line to index.
+
+2012-05-24  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Application.swg: Use IO::Handle to open mesgout.
+
+2012-05-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: Add project_id.
+       * device-src/s3.c: Add project_id. Add x-goog-project-id and
+         x-goo-api-version to headers.
+       * device-src/s3.h (s3_make_bucket, s3_is_bucket_exists) Add project_id
+         argument.
+       * man/xml-source/amanda-devices.7.xml: Document project-id property.
+
+2012-05-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: Call s3_open2 after setting properties.
+       * device-src/s3.c (s3_open2): New function.
+       * device-src/s3.h (s3_open2): Prototype.
+
+2012-05-17 Dan Locks <dwlocks@zmanda.com>
+       * packaging/sun-pkg/buildpkg: add missing --with-libcurl= for server
+
+2012-05-17  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/event.c: Add missing "\n" in debugging.
+       * perl/Amanda/Application.swg: Make mesgout autoflush.
+
+2012-05-15  Jean-Louis Martineau <martineau@zmanda.com>
+       * installcheck/Amanda_Device.pl: Correctly count NDMP test.
+
+2012-05-15  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amvault.pl: Abort if log file already exists.
+
+2012-05-15  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/find.c: Fix crash when log are corrupted.
+
+2012-05-15  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Recovery/Planner.pm (make_plan_from_filelist): Use the
+         changer inventory to try to use an already available dump.
+       * server-src/amidxtaped.pl: Pass the changer to make_plan.
+
+2012-05-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c, device-src/s3.c: Fix for pragma and gcc-4.5.2.
+
+2012-05-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Taper/Worker.pm (FAILED): Do it correctly.
+
+2012-05-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amstatus.pl: Improve output on taper error.
+
+2012-05-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Taper/Worker.pm (FAILED): Ignore if dump is already
+         cancelled.
+
+2012-05-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/event.c: Improve debugging.
+       * server-src/dumper.c: Close data output in stop_dump.
+
+2012-05-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * config/amanda/progs.m4: Define AMANDA_PROG_NC, set NC, NC6 and
+         NETCAT.
+       * configure.in: use AMANDA_PROG_NC.
+       * installcheck/Amanda_Device.pl: Use them.
+       * perl/Amanda/Constants.pm.in: Add NC, NC6 and NETCAT.
+
+2012-05-10 Dan Locks <dwlocks@zmanda.com>
+       * configure.in: update AC_INIT usage, specify tar-ustar and minimum
+         automake version.
+       * config/amanda/version.m4: create new AMANDA_INIT_VERSION macro to
+         read FULL_VERSION or VERSION before AC_INIT.
+
+2012-05-10 Dan Locks <dwlocks@zmanda.com>
+       * Makefile.am: update required automake version
+
+2012-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * installcheck/Amanda_Device.pl: sleep to allow other process the time
+         to start listening.
+
+2012-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amflock.c, common-src/match.c, common-src/util.c,
+         device-src/s3.c: Fix for deprecated G_STATIC_MUTEX_INIT.
+
+2012-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * installcheck/Amanda_Device.pl: Fix indirect tcp.
+
+2012-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/sendbackup.c: Handle indirect tcp.
+       * device-src/ndmp-device.c: Add INDIRECT property.
+       * installcheck/Amanda_Device.pl: Test indirect tcp.
+       * man/xml-source/amanda-devices.7.xml: Document INDIRECT property.
+       * ndmp-src/ndmp4_translate.c: remove debugging statement.
+
+2012-05-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amfetchdump.8.xml: Add --decrypt, --no-decrypt,
+         --server-decrypt, --client-decrypt, --compress, --no-compress,
+         --server-compress, --client-compress.
+       * server-src/amfetchdump.pl: Document new options.
+
+2012-04-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * ndmp-src/ndmos.h: Define NDMOS_MACRO_FREE
+       * ndmp-src/ndmos_glib.h: Define NDMOS_MACRO_FREE
+       * ndmp-src/ndmp_translate.h: define CNVT_FREE.
+       * ndmp-src/ndmp4_translate.c:#Add many free function.
+
+2012-04-20  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amfetchdump.pl: Fix.
+
+2012-04-20  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amadmin.c: Fix handling of optional arguments.
+       * installcheck/amadmin.pl: Check it.
+
+2012-04-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/amdump_client.pl: Fix warning.
+
+2012-04-18  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amfetchdump.pl: add --decompress and --decrypt options.
+       * man/xml-source/amfetchdump.8.xml: Document new options.
+
+2012-04-18  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/conffile.c: Parse MAX_WARNINGS in dumptype.
+       * common-src/conffile.h: Add DUMPTYPE_MAX_WARNINGS and
+         dumptype_get_max_warnings
+       * man/xml-source/amanda.conf.5.xml: Document max_warning in dumptype.
+       * perl/Amanda/Config.swg: Add DUMPTYPE_MAX_WARNINGS.
+       * server-src/diskfile.c (add_disk): Copy max_warnings from dumptype.
+       * server-src/diskfile.h: Add max_warnings in disk_t.
+       * server-src/driverio.c (dumper_cmd): Send max_warnings to dumper.
+       * server-src/dumper.c: Use max_warnings.
+
+2012-04-18  Jean-Louis Martineau <martineau@zmanda.com>
+       * ndmp-src/ndmpconnobj.c: Remove useless g_source_is_destroyed check.
+
+2012-04-17  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amgetconf.pl: Read the disklist.
+       * common-src/conffile.h (seen_t): Add block.
+       * common-src/conffile.c: Set seen.block
+       * common-src/conffile.c (dump_configuration): New print_default and
+         print_source arguments.
+       * installcheck/Amanda_Config.pl: Fix dump_configuration call.
+       * server-src/amadmin.c: Add --no-default and --print-source arguments
+         for config and disklist command.
+       * man/xml-source/amadmin.8.xml: Document new arguments.
+       * perl/Amanda/Config.swg: Fix for new dump_configuration arguments.
+
+2012-04-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amstar.c: Remove spurious space on directory entry.
+
+2012-04-13  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/conffile.c: Add TMPDIR.
+       * common-src/conffile.h: Add CNF_TMPDIR.
+       * man/xml-source/amanda.conf.5.xml: Document TMPDIR.
+       * perl/Amanda/Config.swg: Add CNF_TMPDIR.
+       * server-src/amindexd.c: Use CNF_TMPDIR.
+
+2012-04-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amsamba.pl: Create incremental empty archive.
+
+2012-04-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Changer.pm (make_new_tape_label): Fix error return.
+       * perl/Amanda/Taper/Scribe.pm ($_user_msg_fn): Improve message if tape
+         is relabeled with a new label.
+       * perl/Amanda/ScanInventory.pm: Set relabeled.
+       * installcheck/Amanda_Changer.pl: Fix for new message.
+
+2012-04-11  Jean-Louis Martineau <martineau@zmanda.com>
+       Patch by Nathan Stratton Treadway
+       * device-src/vfs-device.c: Improve message for MAX_VOLUME_USAGE.
+       * installcheck/taper.pl: Fix.
+
+2012-04-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amgtar.8.xml: s/APPLCIATION/APPLICATION/
+
+2012-04-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/ampgsql.pl: psql /could not connect to server/
+         message result in STRANGE.
+
+2012-04-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/ScanInventory.pm: Fix for label not matching labelstr.
+
+2012-04-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/device.c (device_get_bytes_written): New function.
+       * device-src/device.h (device_get_bytes_written): New prototype.
+       * device-src/ndmp-device.c, device-src/rait-device.c,
+         device-src/s3-device.c, device-src/tape-device.c,
+         device-src/vfs-device.c: Implement get_bytes_written.
+       * device-src/xfer-dest-taper-cacher.c,
+         device-src/xfer-dest-taper-splitter.c: Use device_get_bytes_written.
+       * perl/Amanda/Device.swg: Swig device_get_bytes_written.
+
+2012-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: New CLIENT_ID, CLIENT_SECRET and
+         REFRESH_TOKEN properties. Handle OAUTH2.
+       * device-src/s3.c: Handle OAUTH2.
+       * device-src/s3.h (S3_api): Add S3_API_OAUTH2.
+       * man/xml-source/amanda-devices.7.xml: Document new CLIENT_ID,
+         CLIENT_SECRET and REFRESH_TOKEN properties.
+
+2012-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amfetchdump.8.xml: Document -l do not unencrypt.
+
+2012-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/device.c (device_accept_with_cond,
+         device_connect_with_cond): New functions.
+       * device-src/device.h (device_accept_with_cond,
+         device_connect_with_cond): New prototypes.
+       * device-src/ndmp-device.c (accept_with_cond_impl,
+         connect_with_cond_impl): new functions.
+       * device-src/xfer-dest-taper-directtcp.c: Use device_accept_with_cond.
+       * ndmp-src/ndmpconnobj.c (ndmp_connection_wait_for_notify_with_cond):
+         new function.
+       * ndmp-src/ndmpconnobj.h (ndmp_connection_wait_for_notify_with_cond):
+         new prototype.
+       * perl/Amanda/Device.swg: swig accept_with_cond and connect_with_cond.
+       * perl/Amanda/Taper/Worker.pm: Ignore duplicate DONe message.
+       * server-src/driver.c (handle_dumper_result): Always send dumper
+         result to taper.
+       * server-src/dumper.c: Remove debugging statement.
+       * xfer-src/element-glue.c: Add debugging statement.
+       * xfer-src/xfer.c (xfer_cancel): Ignore duplicate cancel.
+       * xfer-src/xfer.h (struct Xfer): Add cancelled field.
+
+2012-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amcryptsimple.pl: Use gpg if available.
+       * common-src/amgpgcrypt.pl: Use gpg-agent and/or gpg2 if available.
+       * server-src/dumper.c: Log compression/encryption executed.
+
+2012-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: New S3_MULTI_DELETE property.
+       * device-src/s3.c: New S3_MULTI_DELETE property.
+       * device-src/s3.h (s3_multi_delete): New prototype.
+       * man/xml-source/amanda-devices.7.xml: Document new S3_MULTI_DELETE s3
+         device property.
+
+2012-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: New PASSWORD, USERNAME, TENANT_ID,
+         TENANT_NAME and STORAGE_API property. Handle SWIFT-2.
+       * device-src/s3.c: Handle SWIFT-2.
+       * device-src/s3.h (s3_open): New prototype.
+       * device-src/s3.h (S3_api): New enum.
+       * man/xml-source/amanda-devices.7.xml: Document new PASSWORD,
+         USERNAME, TENANT_ID, TENANT_NAME and STORAGE_API S3 device
+         properties.
+
+2012-04-02  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amsamba.pl: Do not set unc prematurely.
+
+2012-04-02  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/ndmp-device.c (listen_impl): Set the window offset and
+         length to blocksize when reading.
+
+2012-03-29 Dan Locks <dwlocks@zmanda.com>
+       * packaging/sun-pkg/buildpkg: add missing GLIB_LIBS variable to intel
+         builds. Add flags to make invocation to reduce output.
+
+2012-03-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driver.c: Fix hang if taper crash.
+
+2012-03-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3.c: Retry on {500, S3_ERROR_None} error.
+         Improving debugging.
+
+2012-03-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amadmin.c: Fix bumpsize.
+
+2012-03-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/fileheader.c: header type for non-amanda header is
+         F_WEIRD.
+       * server-src/amcheck-device.pl,
+         server-src/amtape.pl: Improve output for non-Amanda volume.
+
+2012-03-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amgtar.c: Use "TAR-BLOCKSIZE" on restore.
+
+2012-03-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/ampgsql.pl: Use statefile to find end_wal on
+         estimate.
+
+2012-03-15  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amgtar.c: Add IGNORE-ZEROS property.
+       * man/xml-source/amgtar.8.xml: Document IGNORE-ZEROS property.
+
+2012-03-13  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/ampgsql.pl: Do not Execute pg_start_backup for
+         estimate.
+
+2012-03-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/glib-util.c: g_thread_supported always return TRUE on
+         newer version.
+
+2012-03-10  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/glib-util.c, common-src/glib-util.h: Remove
+         g_queue_free_full.
+
+2012-03-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/client_util.c, common-src/Makefile.am, common-src/am_sl.c,
+         common-src/amxml.c: typo.
+
+2012-03-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/client_util.c, client-src/selfcheck.c,
+         client-src/sendbackup-dump.c, client-src/sendbackup-gnutar.c,
+         client-src/sendbackup.c, client-src/sendsize.c,
+         common-src/amxml.c, common-src/amxml.h,
+         recover-src/extract_list.c: s/level_t/am_level_t/g
+       * client-src/calcsize.c, common-src/amxml.h,
+         common-src/conffile.c, common-src/conffile.h,
+         common-src/sl.c, common-src/sl.h,
+         perl/Amanda/Header.swg: s/sl_t/am_sl_t/g
+       * amandad-src/amandad.h, client-src/calcsize.c,
+         client-src/client_util.h, common-src/Makefile.am: s/sl.h/am_sl.h
+       * common-src/am_sl.h: renamed from common-src/sl.h
+       * common-src/am_sl.c: renamed from common-src/sl.c
+
+2012-03-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amfetchdump.pl: Print progress.
+       * device-src/device.c (device_get_bytes_read ): New API method.
+       * device-src/device.h (Device): Add bytes_read.
+       * device-src/device.h (_DeviceClass): Add get_bytes_read.
+       * device-src/device.h (device_get_bytes_read): Add prototype.
+       * device-src/ndmp-device.c: Set bytes_read.
+       * device-src/rait-device.c: Set bytes_read.
+       * device-src/s3-device.c: Use curl progress callback to set bytes_read.
+       * device-src/s3.c: Set a progress callback.
+       * device-src/tape-device.c: Set bytes_read.
+       * device-src/vfs-device.c: Set bytes_read.
+       * device-src/xfer-device.h (xfer_source_recovery_get_bytes_read): Add
+         prototype.
+       * device-src/xfer-source-recovery.c
+         (xfer_source_recovery_get_bytes_read): new function.
+       * perl/Amanda/Device.swg (device_get_bytes_read): New function.
+       * perl/Amanda/Recovery/Clerk.pm: Call get_bytes_read.
+       * perl/Amanda/XferServer.swg: (xfer_source_holding_get_bytes_read,
+       * xfer_source_recovery_get_bytes_read): New prototypes.
+       * server-src/xfer-server.h (xfer_source_holding_get_bytes_read):
+         New protoype.
+       * server-src/xfer-source-holding.c (xfer_source_holding_get_bytes_read):
+         New function.
+
+2012-03-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Recovery/Scan.pm: Do not rescan the same slot
+         indefinitely.
+
+2012-03-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Changer/multi.pm: Fix warning.
+
+2012-03-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * device-src/s3-device.c: New PROXY property.
+       * device-src/s3.c: Set CURLOPT_PROXY from PROXY property.
+       * device-src/s3.h (s3_open): Add proxy argument.
+       * man/xml-source/amanda-devices.7.xml: Document PROXY property.
+
+2012-03-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * perl/Amanda/Header.swg (get_dle): Return undef if not set.
+       * server-src/amidxtaped.pl: Check dle is set.
+
+2012-03-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amvault.pl: Use the write-timestamp, not the
+         dump-timestamp.
+
+2012-03-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/ssh-security.c: use default port if client-port is not
+         set.
+
+2012-03-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/amsamba.pl:  Fix use of subdir for restore,
+         prepend subdir on include for restore.
+
+2012-03-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * ndmp-src/ndmjob_args.c: Add '-o D-agent-fd' argument.
+
+2012-03-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * application-src/ampgsql.pl: Do not execute pg_start_backup and
+         pg_stop_backup on selfcheck.
+
+2012-02-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amzfs-sendrecv.8.xml: Typo.
+
+2012-02-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/disklist.5.xml: Document includefile directive.
+
 2012-02-21  Jean-Louis Martineau <martineau@zmanda.com>
        * perl/make_html.pl: Add link at top, better list display.
        * perl/Makefile.am: Execute make_html with a --homeurl argument.
index bea438e9ade7708f8a0fc26bdacda06231f4a434..4772543317946fcd286c6d5f8e39a61dc241df07 100644 (file)
@@ -1 +1 @@
-3.3.1
+3.3.2
index 7e8d4c280aafeac1156dc83aec3694f76afb0561..81589acec423f115687acc24e96885df843599fd 100644 (file)
@@ -1,5 +1,5 @@
 ## Process this file with automake to produce Makefile.in
-AUTOMAKE_OPTIONS = 1.4 foreign
+AUTOMAKE_OPTIONS = 1.10 foreign
 
 include $(top_srcdir)/config/automake/vars.am
 include $(top_srcdir)/config/automake/installperms.am
index 8a973bcc3bc22c7989f9910421ec9bb953181a0b..f6defc69648746e1575d968ba8e5fa5ace77c280 100644 (file)
@@ -16,7 +16,7 @@
 @SET_MAKE@
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -261,7 +261,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
@@ -855,6 +856,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
@@ -1151,7 +1155,7 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = 1.4 foreign
+AUTOMAKE_OPTIONS = 1.10 foreign
 SUFFIXES = 
 EXTRA_DIST = $(SNAPSHOT_STAMP) $(pkgdata_DATA) autogen contrib/README \
        contrib/dbbackup.README contrib/dbbackup.ksh \
diff --git a/NEWS b/NEWS
index 48f53ef266a4fcd99b9a14d0819339d8d499b851..5f5c570d8fe70031131ed9960c47bedb339738ed 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,36 @@
+Changes in release 3.3.2
+
+   * amgtar
+       o New IGNORE-ZEROS property.
+   * amsamba
+       o Fix use of subdir for restore.
+   * s3 device
+       o New PROXY property.
+       o New PASSWORD, USERNAME, TENANT_ID, TENANT_NAME properties.
+       o New STORAGE_API property.
+       o New S3_MULTI_DELETE property
+       o New CLIENT_ID, CLIENT_SECRET and REFRESH_TOKEN properties.
+       o New CREATE-BUCKET property.
+       o New PROJECT-ID property.
+       o New REUSE-CONNECTION property.
+       o Works with swift and google storage.
+   * NDMP device
+       o Add INDIRECT property.
+   * amanda.conf
+       o Add 'max-warnings', The maximum number of warning lines in the report.
+       o Default 'columspec' changed to: HostName=0:-12:12,Disk=1:-11:11,Level=1:-1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1
+   * amadmin
+       o Add --no-default and --print-source arguments for config and
+         disklist command.
+   * amfetchdump
+       o Print progress.
+       o Add --decrypt, --no-decrypt, --server-decrypt, --client-decrypt,
+         --compress, --no-compress, --server-compress and --client-compress
+         options.
+   * fix for compilation with newer glib.
+   * fix for compilation on cigwin.
+   * Many bug fix.
+
 Changes in release 3.3.1
 
    * amrecover
index d4f5e8c69972e086e26857f93b9a24171192e786..d3286fd3f2169d376d7ceec2d234401af9eb0fb9 100644 (file)
@@ -1,3 +1,37 @@
+               Release Notes for amanda-3.3.2
+
+* amgtar
+    o New IGNORE-ZEROS property.
+* amsamba
+    o Fix use of subdir for restore.
+* s3 device
+    o New PROXY property.
+    o New PASSWORD, USERNAME, TENANT_ID, TENANT_NAME properties.
+    o New STORAGE_API property.
+    o New S3_MULTI_DELETE property
+    o New CLIENT_ID, CLIENT_SECRET and REFRESH_TOKEN properties.
+    o New CREATE-BUCKET property.
+    o New PROJECT-ID property.
+    o New REUSE-CONNECTION property.
+    o Works with swift and google storage.
+* NDMP device
+    o Add INDIRECT property.
+* amanda.conf
+    o Add 'max-warnings', The maximum number of warning lines in the report.
+    o Default 'columspec' changed to: HostName=0:-12:12,Disk=1:-11:11,Level=1:-1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1
+* amadmin
+    o Add --no-default and --print-source arguments for config and
+      disklist command.
+* amfetchdump
+    o Print progress.
+    o Add --decrypt, --no-decrypt, --server-decrypt, --client-decrypt,
+      --compress, --no-compress, --server-compress and --client-compress
+      options.
+* fix for compilation with newer glib.
+* fix for compilation on cigwin.
+* Many bug fix.
+
+
                Release Notes for amanda-3.3.1
 
 * amrecover
diff --git a/VERSION b/VERSION
index bea438e9ade7708f8a0fc26bdacda06231f4a434..4772543317946fcd286c6d5f8e39a61dc241df07 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.3.1
+3.3.2
index f5a2ff74d84593bba5139b95cc29af5971499353..258a742cca54c89a4e2fb0de994fbd99cbbdeaf6 100644 (file)
@@ -1167,6 +1167,23 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
index 7f309a0f45cdf8478936ac90847764c676628b12..f57f64f87a8c659755fd75b23e44fccbe600a19e 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda client programs.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -268,7 +268,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -835,6 +836,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index e3f11a0f38465b5ccf97bad02694deb1310b1ccd..11009d854ef405fbbfd443427c61e2bfba83e9ab 100644 (file)
@@ -564,6 +564,7 @@ protocol_accept(
     char *service_path = NULL;
     GSList *errlist = NULL;
     int i;
+    char *peer_name;
 
     pkt_out.body = NULL;
 
@@ -600,7 +601,9 @@ protocol_accept(
        return;
     }
 
-    g_debug("authenticated peer name is '%s'", security_get_authenticated_peer_name(handle));
+    peer_name = security_get_authenticated_peer_name(handle);
+    g_debug("authenticated peer name is '%s'", peer_name);
+    amfree(peer_name);
 
     /*
      * If pkt is NULL, then there was a problem with the new connection.
index d58eaf37d8e3652ae8d4fe8e2644eccb8d73caad..2bbf72726084bc55154168c50a4390a70de5d9e3 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "amanda.h"
 #include "amfeatures.h"
-#include "sl.h"
+#include "am_sl.h"
 #include "util.h"              /* for bstrncmp() */
 
 typedef struct g_option_s {
index 1bea528058c52dea23e301b98e1afcd77eb759ac..e508a17c7fcf02600455af5d28a67e5be3ab5175 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda archive library
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -270,7 +270,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -843,6 +844,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 67cc109ac7e0492df4e3931cda45fedee1640f51..f237fe536718f29aa6963939765aae3ad0ad791f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 527802d398dd3d24b2b3e30b136a167c467fd2dd..9ba1c7c8d57d1c7dcb55de0c05f471e061e32d23 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 2147929df953a0ec1574a0b5f201f3e1604c3f92..71821e7f2d2b1160c0e6be6af93eb4a664f7a6a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 9fd64b969fd42c80fc0e5e1e2b3193f79bb99764..914cd1c4bf7cb35f0bdc6b6053694e2ee9d88d94 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for amplot.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -40,7 +40,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -337,7 +337,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -877,6 +878,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index c73b974ddb283bd0608f1a2045315aa97ec3bb85..fa340681012755a0ac2c62752bdde6babc69d952 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda wrapper programs.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -40,7 +40,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -339,7 +339,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -914,6 +915,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 7cf28a1ffce292a70c68b0bd3a31d4f1036eb130..47103ad45a466f0f248ce5ce47944e0c518b851b 100644 (file)
@@ -122,6 +122,7 @@ typedef struct application_argument_s {
     int        argc;
     char     **argv;
     int        verbose;
+    int        ignore_zeros;
 } application_argument_t;
 
 enum { CMD_ESTIMATE, CMD_BACKUP };
@@ -137,6 +138,7 @@ static void amgtar_build_exinclude(dle_t *dle, int verbose,
                                   int *nb_include, char **file_include);
 static char *amgtar_get_incrname(application_argument_t *argument, int level,
                                 FILE *mesgstream, int command);
+static void check_no_check_device(void);
 static GPtrArray *amgtar_build_argv(application_argument_t *argument,
                                char *incrname, char **file_exclude,
                                char **file_include, int command);
@@ -194,6 +196,7 @@ static struct option long_options[] = {
     {"include-list-glob", 1, NULL, 34},
     {"exclude-list-glob", 1, NULL, 35},
     {"verbose"          , 1, NULL, 36},
+    {"ignore-zeros"     , 1, NULL, 37},
     {NULL, 0, NULL, 0}
 };
 
@@ -370,6 +373,7 @@ main(
     argument.include_list_glob = NULL;
     argument.exclude_list_glob = NULL;
     argument.verbose = 0;
+    argument.ignore_zeros = 1;
     init_dle(&argument.dle);
     argument.dle.record = 0;
 
@@ -501,6 +505,9 @@ main(
        case 36: if (optarg  && strcasecmp(optarg, "YES") == 0)
                     argument.verbose = 1;
                 break;
+       case 37: if (strcasecmp(optarg, "YES") != 0)
+                    argument.ignore_zeros = 0;
+                break;
        case ':':
        case '?':
                break;
@@ -1118,7 +1125,13 @@ amgtar_restore(
     if (gnutar_xattrs)
        g_ptr_array_add(argv_ptr, stralloc("--xattrs"));
     /* ignore trailing zero blocks on input (this was the default until tar-1.21) */
-    g_ptr_array_add(argv_ptr, stralloc("--ignore-zeros"));
+    if (argument->ignore_zeros) {
+       g_ptr_array_add(argv_ptr, stralloc("--ignore-zeros"));
+    }
+    if (argument->tar_blocksize) {
+       g_ptr_array_add(argv_ptr, stralloc("--blocking-factor"));
+       g_ptr_array_add(argv_ptr, stralloc(argument->tar_blocksize));
+    }
     g_ptr_array_add(argv_ptr, stralloc("-xpGvf"));
     g_ptr_array_add(argv_ptr, stralloc("-"));
     if (gnutar_directory) {
@@ -1451,6 +1464,41 @@ amgtar_get_incrname(
     return incrname;
 }
 
+static void
+check_no_check_device(void)
+{
+    if (gnutar_checkdevice == 0) {
+       GPtrArray *argv_ptr = g_ptr_array_new();
+       int dumpin;
+       int dataf;
+       int outf;
+       int size;
+       char buf[32768];
+
+       g_ptr_array_add(argv_ptr, gnutar_path);
+       g_ptr_array_add(argv_ptr, "-x");
+       g_ptr_array_add(argv_ptr, "--no-check-device");
+       g_ptr_array_add(argv_ptr, "-f");
+       g_ptr_array_add(argv_ptr, "-");
+       g_ptr_array_add(argv_ptr, NULL);
+
+       pipespawnv(gnutar_path, STDIN_PIPE|STDOUT_PIPE|STDERR_PIPE, 0,
+                            &dumpin, &dataf, &outf, (char **)argv_ptr->pdata);
+       aclose(dumpin);
+       aclose(dataf);
+       size = read(outf, buf, 32767);
+       if (size > 0) {
+           buf[size] = '\0';
+           if (strstr(buf, "--no-check-device")) {
+               g_debug("disabling --no-check-device since '%s' doesn't support it", gnutar_path);
+               gnutar_checkdevice = 1;
+           }
+       }
+       aclose(outf);
+       g_ptr_array_free(argv_ptr, TRUE);
+    }
+}
+
 GPtrArray *amgtar_build_argv(
     application_argument_t *argument,
     char  *incrname,
@@ -1465,6 +1513,7 @@ GPtrArray *amgtar_build_argv(
     GPtrArray *argv_ptr = g_ptr_array_new();
     GSList    *copt;
 
+    check_no_check_device();
     amgtar_build_exinclude(&argument->dle, 1,
                           &nb_exclude, file_exclude,
                           &nb_include, file_include);
index 284e68f99aa7abd7e8383ddd709c7244a015656a..eaf2a6d20b5fb4b73b85132f9b95f03a6af871df 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 0150af1bd18331e82b4043ad2ddee9b4f6082623..652345f08202e0c3b546a96d9f0beeb7efe906c7 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -273,6 +273,9 @@ sub _run_psql_command {
        chomp $line;
        debug("psql stderr: $line");
        if ($line =~ /NOTICE: pg_stop_backup complete, all required WAL segments have been archived/) {
+       } elsif ($line =~ /could not connect to server/) {
+           $self->print_to_server("psql stderr: $line",
+                                  $Amanda::Script_App::ERROR);
        } else {
            $self->print_to_server("psql stderr: $line",
                                   $Amanda::Script_App::GOOD);
@@ -425,19 +428,6 @@ sub command_selfcheck {
                _check("Connecting to database server", "succeeded", "failed",
                   \&_run_psql_command, $self, '');
        }
-        
-       if ($try_connect) {
-           my $label = "$self->{'label-prefix'}-selfcheck-" . time();
-           if (_check("Call pg_start_backup", "succeeded",
-                      "failed (is another backup running?)",
-                      \&_run_psql_command, $self, "SELECT pg_start_backup('$label')")
-               and _check("Call pg_stop_backup", "succeeded", "failed",
-                          \&_run_psql_command, $self, "SELECT pg_stop_backup()")) {
-
-               _check("Get info from .backup file", "succeeded", "failed",
-                      sub {my ($start, $end) = _get_backup_info($self, $label); $start and $end});
-           }
-       }
 
        {
            my @gv = `$self->{'args'}->{'gnutar-path'} --version`;
@@ -479,9 +469,11 @@ sub _write_state_file {
 
 sub _get_prev_state {
     my $self = shift @_;
+    my $initial_level = shift;
+    $initial_level = $self->{'args'}->{'level'} - 1 if !defined $initial_level;
 
     my $end_wal;
-    for (my $level = $self->{'args'}->{'level'} - 1; $level >= 0; $level--) {
+    for (my $level = $initial_level; $level >= 0; $level--) {
         my $fn = _state_filename($self, $level);
         debug("reading state file: $fn");
         my $h = new IO::File($fn, "r");
@@ -708,7 +700,10 @@ sub _wait_for_wal {
     my $count = 0; # try at least 4 cycles
     my $stoptime = time() + $maxwait;
     while ($maxwait == 0 || time < $stoptime || $count++ < 4) {
-       return if -f "$archive_dir/$wal";
+       if (-f "$archive_dir/$wal") {
+           sleep(1);
+           return;
+       }
 
        # for versions 8.0 or 8.1, the only way to "force" a WAL archive is to write
        # garbage to the database.
@@ -732,8 +727,10 @@ sub _base_backup {
    -d $self->{'props'}->{'pg-archivedir'} or
        die("WAL file archive directory does not exist (or is not a directory)");
 
-   _run_psql_command($self, "SELECT pg_start_backup('$label')") or
-       $self->{'die_cb'}->("Failed to call pg_start_backup");
+   if ($self->{'action'} eq 'backup') {
+       _run_psql_command($self, "SELECT pg_start_backup('$label')") or
+           $self->{'die_cb'}->("Failed to call pg_start_backup");
+   }
 
    # tar data dir, using symlink to prefix
    # XXX: tablespaces and their symlinks?
@@ -741,8 +738,10 @@ sub _base_backup {
    my $old_die_cb = $self->{'die_cb'};
    $self->{'die_cb'} = sub {
        my $msg = shift @_;
-       unless(_run_psql_command($self, "SELECT pg_stop_backup()")) {
-           $msg .= " and failed to call pg_stop_backup";
+       if ($self->{'action'} eq 'backup') {
+           unless(_run_psql_command($self, "SELECT pg_stop_backup()")) {
+               $msg .= " and failed to call pg_stop_backup";
+          }
        }
        $old_die_cb->($msg);
    };
@@ -754,28 +753,39 @@ sub _base_backup {
        ".");
    $self->{'die_cb'} = $old_die_cb;
 
-   unless (_run_psql_command($self, "SELECT pg_stop_backup()")) {
-       $self->{'die_cb'}->("Failed to call pg_stop_backup");
+   if ($self->{'action'} eq 'backup') {
+       unless (_run_psql_command($self, "SELECT pg_stop_backup()")) {
+           $self->{'die_cb'}->("Failed to call pg_stop_backup");
+       }
    }
 
    # determine WAL files and append and create their tar file
-   my ($start_wal, $end_wal) = _get_backup_info($self, $label);
+   my $start_wal;
+   my $end_wal;
 
-   ($start_wal and $end_wal)
-       or $self->{'die_cb'}->("A .backup file was never found in the archive "
-                           . "dir $self->{'props'}->{'pg-archivedir'}");
-
-   $self->_wait_for_wal($end_wal);
+   if ($self->{'action'} eq 'backup') {
+       ($start_wal, $end_wal)  = _get_backup_info($self, $label);
+       ($start_wal and $end_wal)
+               or $self->{'die_cb'}->("A .backup file was never found in the archive "
+                                   . "dir $self->{'props'}->{'pg-archivedir'}");
+       $self->_wait_for_wal($end_wal);
+   } else {
+       $start_wal = undef;
+       $end_wal = _get_prev_state($self, 0);
+   }
 
    # now grab all of the WAL files, *inclusive* of $start_wal
    my @wal_files;
    my $adir = new IO::Dir($self->{'props'}->{'pg-archivedir'});
    while (defined(my $fname = $adir->read())) {
        if ($fname =~ /^$_WAL_FILE_PAT$/) {
-           if (($fname ge $start_wal) and ($fname le $end_wal)) {
+           if (!defined $end_wal ||
+              (!defined $start_wal and ($fname le $end_wal)) ||
+              (defined $start_wal and ($fname ge $start_wal) and
+               ($fname le $end_wal))) {
                push @wal_files, $fname;
                debug("will store: $fname");
-           } elsif ($fname lt $start_wal) {
+           } elsif (defined $start_wal and $fname lt $start_wal) {
                $self->{'unlink_cb'}->("$self->{'props'}->{'pg-archivedir'}/$fname");
            }
        }
index 5502657dc5325f19f525a0853c9d2f87c9158dda..198758646a0029995f118ee7c1cc002231e14b4e 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@ 
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index d1f0bda72689c6c2e33da142ea208d0dc8e9ca1d..7a6ffd8bdb7554f1866e47eafd331ac8266e3cab 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@ 
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -36,6 +36,7 @@ use Amanda::Config qw( :init :getconf  config_dir_relative );
 use Amanda::Debug qw( :logging );
 use Amanda::Paths;
 use Amanda::Util qw( :constants :quoting);
+use Amanda::MainLoop qw( :GIOCondition );
 
 sub new {
     my $class = shift;
@@ -70,11 +71,6 @@ sub new {
     } else {
        $self->{device}       = $disk;
     }
-    if ($self->{disk} =~ /^\\\\/) {
-       $self->{unc}          = 1;
-    } else {
-       $self->{unc}          = 0;
-    }
     $self->{level}            = [ @{$level} ];
     $self->{index}            = $index;
     $self->{message}          = $message;
@@ -146,6 +142,9 @@ sub validate_inexclude {
                next;
            }
            while (<FF>) {
+               if (defined $self->{'subdir'}) {
+                   $_ =~ s/^\./$self->{'subdir'}/;
+               }
                print INC_FILE;
            }
            close(FF);
@@ -155,7 +154,11 @@ sub validate_inexclude {
        for(my $i=1;defined $ARGV[$i]; $i++) {
            my $param = $ARGV[$i];
            $param =~ /^(.*)$/;
-           print INC_FILE "$1\n";
+           $_ = $1;
+           if (defined $self->{'subdir'}) {
+               $_ =~ s/^\./$self->{'subdir'}/;
+           }
+           print INC_FILE "$_\n";
        }
 
        close INC_FILE;
@@ -176,6 +179,10 @@ sub validate_inexclude {
            }
            while (<FF>) {
                chomp;
+               if ($self->{action} eq "restore" and
+                   defined $self->{'subdir'}) {
+                   $_ =~ s/^\./$self->{'subdir'}/;
+               }
                push @{$self->{include}}, $_;
            }
            close(FF);
@@ -186,6 +193,10 @@ sub validate_inexclude {
                for(my $i=1;defined $ARGV[$i]; $i++) {
                my $param = $ARGV[$i];
                $param =~ /^(.*)$/;
+               $_ = $1;
+               if (defined $self->{'subdir'}) {
+                   $_ =~ s/^\./$self->{'subdir'}/;
+               }
                push @{$self->{include}}, $1;
            }
        }
@@ -207,6 +218,11 @@ sub parsesharename {
     $to_parse = $self->{device} if !defined $to_parse;;
 
     return if !defined $to_parse;
+    if ($to_parse =~ /^\\\\/) {
+       $self->{unc}          = 1;
+    } else {
+       $self->{unc}          = 0;
+    }
 
     if ($self->{unc}) {
        if ($to_parse =~ m,^(\\\\[^\\]+\\[^\\]+)\\(.*)$,) {
@@ -375,13 +391,13 @@ sub command_selfcheck {
     print "OK " . $self->{device} . "\n";
     print "OK " . $self->{directory} . "\n" if defined $self->{directory};
 
-    my ($child_rdr, $parent_wtr);
+    my ($password_rdr, $password_wtr);
     if (defined $self->{password}) {
        # Don't set close-on-exec
         $^F=10;
-        pipe($child_rdr, $parent_wtr);
+        pipe($password_rdr, $password_wtr);
         $^F=2;
-        $parent_wtr->autoflush(1);
+        $password_wtr->autoflush(1);
     }
     my($wtr, $rdr, $err);
     $err = Symbol::gensym;
@@ -389,10 +405,10 @@ sub command_selfcheck {
     if ($pid == 0) {
        #child
         if (defined $self->{password}) {
-           my $ff = $child_rdr->fileno;
-           debug("child_rdr $ff");
-           $parent_wtr->close();
-           $ENV{PASSWD_FD} = $child_rdr->fileno;
+           my $ff = $password_rdr->fileno;
+           debug("password_rdr $ff");
+           $password_wtr->close();
+           $ENV{PASSWD_FD} = $password_rdr->fileno;
        }
        close(1);
        close(2);
@@ -414,11 +430,11 @@ sub command_selfcheck {
     }
     #parent
     if (defined $self->{password}) {
-        my $ff = $parent_wtr->fileno;
-        debug("parent_wtr $ff");
-        $parent_wtr->print($self->{password});
-        $parent_wtr->close();
-        $child_rdr->close();
+        my $ff = $password_wtr->fileno;
+        debug("password_wtr $ff");
+        $password_wtr->print($self->{password});
+        $password_wtr->close();
+        $password_rdr->close();
     } else {
        debug("No password");
     }
@@ -447,13 +463,13 @@ sub command_estimate {
     $self->validate_inexclude();
 
     my $level = $self->{level}[0];
-    my ($child_rdr, $parent_wtr);
+    my ($password_rdr, $password_wtr);
     if (defined $self->{password}) {
        # Don't set close-on-exec
         $^F=10;
-        pipe($child_rdr,  $parent_wtr);
+        pipe($password_rdr,  $password_wtr);
         $^F=2;
-        $parent_wtr->autoflush(1);
+        $password_wtr->autoflush(1);
     }
     my($wtr, $rdr, $err);
     $err = Symbol::gensym;
@@ -461,10 +477,10 @@ sub command_estimate {
     if ($pid == 0) {
        #child
         if (defined $self->{password}) {
-           my $ff = $child_rdr->fileno;
-           debug("child_rdr $ff");
-           $parent_wtr->close();
-           $ENV{PASSWD_FD} = $child_rdr->fileno;
+           my $ff = $password_rdr->fileno;
+           debug("password_rdr $ff");
+           $password_wtr->close();
+           $ENV{PASSWD_FD} = $password_rdr->fileno;
        }
        close(0);
        close(1);
@@ -491,12 +507,12 @@ sub command_estimate {
     }
     #parent
     if (defined $self->{password}) {
-        my $ff = $parent_wtr->fileno;
-        debug("parent_wtr $ff");
+        my $ff = $password_wtr->fileno;
+        debug("password_wtr $ff");
         debug("password $self->{password}");
-        $parent_wtr->print($self->{password});
-        $parent_wtr->close();
-        $child_rdr->close();
+        $password_wtr->print($self->{password});
+        $password_wtr->close();
+        $password_rdr->close();
     }
     close($wtr);
     close($rdr);
@@ -546,6 +562,22 @@ sub output_size {
    }
 }
 
+sub send_empty_tar_file {
+    my $self = shift;
+    my ($out1, $out2) = @_;
+    my $out;
+    my $buf;
+    my $size;
+
+    Amanda::Debug::debug("Create empty archive with: tar --create --file=- --files-from=/dev/null");
+    open2($out, undef, "tar", "--create", "--file=-", "--files-from=/dev/null");
+
+    while(($size = sysread($out, $buf, 32768))) {
+       syswrite($out1, $buf, $size);
+       syswrite($out2, $buf, $size);
+    }
+}
+
 sub command_backup {
     my $self = shift;
 
@@ -555,38 +587,25 @@ sub command_backup {
     $self->findpass();
     $self->validate_inexclude();
 
-    my $pid_tee = open3(\*INDEX_IN, '>&STDOUT', \*INDEX_TEE, "-");
-    if ($pid_tee == 0) {
-       close(INDEX_IN);
-       close(INDEX_TEE);
-       my $buf;
-       my $size = -1;
-       while (($size = POSIX::read(0, $buf, 32768)) > 0) {
-           POSIX::write(1, $buf, $size);
-           POSIX::write(2, $buf, $size);
-       }
-       exit 0;
-    }
-    my ($child_rdr, $parent_wtr);
+    my ($password_rdr, $password_wtr);
     if (defined $self->{password}) {
        # Don't set close-on-exec
         $^F=10;
-        pipe($child_rdr,  $parent_wtr);
+        pipe($password_rdr,  $password_wtr);
         $^F=2;
-        $parent_wtr->autoflush(1);
+        $password_wtr->autoflush(1);
     }
-    my($wtr, $err);
-    $err = Symbol::gensym;
-    my $pid = open3($wtr, ">&INDEX_IN", $err, "-");
+    my($smbclient_wtr, $smbclient_rdr, $smbclient_err);
+    $smbclient_err = Symbol::gensym;
+    my $pid = open3($smbclient_wtr, $smbclient_rdr, $smbclient_err, "-");
     if ($pid == 0) {
        #child
        if (defined $self->{password}) {
-           my $ff = $child_rdr->fileno;
-           debug("child_rdr $ff");
-           $parent_wtr->close();
-           $ENV{PASSWD_FD} = $child_rdr->fileno;
+           my $ff = $password_rdr->fileno;
+           debug("password_rdr $ff");
+           $password_wtr->close();
+           $ENV{PASSWD_FD} = $password_rdr->fileno;
        }
-       close(0);
        my @ARGV = ();
        push @ARGV, $self->{smbclient}, $self->{share};
        push @ARGV, "" if (!defined($self->{password}));
@@ -627,53 +646,126 @@ sub command_backup {
     }
 
     if (defined $self->{password}) {
-        my $ff = $parent_wtr->fileno;
-        debug("parent_wtr $ff");
-        debug("password $self->{password}");
-        $parent_wtr->print($self->{password});
-        $parent_wtr->close();
-        $child_rdr->close();
+        my $ff = $password_wtr->fileno;
+        debug("password_wtr $ff");
+        $password_wtr->print($self->{password});
+        $password_wtr->close();
+        $password_rdr->close();
     } else {
        debug("No password");
     }
-    close($wtr);
+    close($smbclient_wtr);
 
     #index process 
-    my $index;
+    my $index_rdr;
+    my $index_wtr;
     debug("$self->{gnutar} -tf -");
-    my $pid_index1 = open2($index, '<&INDEX_TEE', $self->{gnutar}, "-tf", "-");
-    close(INDEX_IN);
+    my $pid_index1 = open2($index_rdr, $index_wtr, $self->{gnutar}, "-tf", "-");
     my $size = -1;
-    my $index_fd = $index->fileno;
+    my $index_fd = $index_rdr->fileno;
     debug("index $index_fd");
+    my $indexout_fd;
     if (defined($self->{index})) {
-       my $indexout_fd;
        open($indexout_fd, '>&=4') ||
            $self->print_to_server_and_die("Can't open indexout_fd: $!",
                                           $Amanda::Script_App::ERROR);
-       $self->parse_backup($index, $self->{mesgout}, $indexout_fd);
-       close($indexout_fd);
     }
-    else {
-       $self->parse_backup($index_fd, $self->{mesgout}, undef);
-    }
-    close($index);
 
-    while (<$err>) {
-       chomp;
-       debug("stderr: " . $_);
-       next if /^Domain=/;
-       next if /^tarmode is now /;
-       next if /dumped (\d+) files and directories/;
+    my $file_to_close = 3;
+    my $smbclient_stdout_src = Amanda::MainLoop::fd_source($smbclient_rdr,
+                               $G_IO_IN|$G_IO_HUP|$G_IO_ERR);
+    my $smbclient_stderr_src = Amanda::MainLoop::fd_source($smbclient_err,
+                               $G_IO_IN|$G_IO_HUP|$G_IO_ERR);
+    my $index_tar_stdout_src = Amanda::MainLoop::fd_source($index_rdr,
+                               $G_IO_IN|$G_IO_HUP|$G_IO_ERR);
+
+    my $smbclient_stdout_done = 0;
+    my $smbclient_stderr_done = 0;
+    my $data_size = 0;
+    my $nb_files = 0;
+    $smbclient_stdout_src->set_callback(sub {
+       my $buf;
+       my $blocksize = -1;
+       $blocksize = sysread($smbclient_rdr, $buf, 32768);
+       if (!$blocksize) {
+           $file_to_close--;
+           $smbclient_stdout_src->remove();
+           $smbclient_stdout_done = 1;
+           if ($smbclient_stderr_done) {
+               if ($data_size == 0 and $nb_files == 0 and $size == 0) {
+                   $self->send_empty_tar_file(*STDOUT, $index_wtr);
+               }
+               close($index_wtr);
+               close(STDOUT);
+           }
+           close($smbclient_rdr);
+           Amanda::MainLoop::quit() if $file_to_close == 0;
+           return;
+       }
+       $data_size += $blocksize;
+       syswrite(STDOUT, $buf, $blocksize);
+       syswrite($index_wtr, $buf, $blocksize);
+    });
+
+    $smbclient_stderr_src->set_callback(sub {
+       my $line = <$smbclient_err>;
+       if (!defined $line) {
+           $file_to_close--;
+           $smbclient_stderr_src->remove();
+           $smbclient_stderr_done = 1;
+           if ($smbclient_stdout_done) {
+               if ($data_size == 0 and $nb_files == 0 and $size == 0) {
+                   $self->send_empty_tar_file(*STDOUT, $index_wtr);
+               }
+               close($index_wtr);
+               close(STDOUT);
+           }
+           close ($smbclient_err);
+           Amanda::MainLoop::quit() if $file_to_close == 0;
+           return;
+       }
+       chomp $line;
+       debug("stderr: " . $line);
+       return if $line =~ /^Domain=/;
+       return if $line =~ /^tarmode is now /;
+       if ($line =~ /dumped (\d+) files and directories/) {
+           $nb_files = $1;
+           return;
+       }
        # message if samba server is configured with 'security = share'
-       next if /Server not using user level security and no password supplied./;
-       if (/^Total bytes written: (\d*)/) {
+       return if $line =~$line =~  /Server not using user level security and no password supplied./;
+       if ($line =~ /^Total bytes written: (\d*)/) {
            $size = $1;
+           return;
+       }
+       $self->print_to_server("smbclient: $line", $Amanda::Script_App::ERROR);
+    });
+
+    $index_tar_stdout_src->set_callback(sub {
+       my $line = <$index_rdr>;
+       if (!defined $line) {
+           $file_to_close--;
+           $index_tar_stdout_src->remove();
+           close($index_rdr);
+           close($indexout_fd);
+           Amanda::MainLoop::quit() if $file_to_close == 0;
+           return;
+       }
+       if ($line =~ /^\.\//) {
+           if(defined($indexout_fd)) {
+               if(defined($self->{index})) {
+                   $line =~ s/^\.//;
+                   print $indexout_fd $line;
+               }
+           }
        } else {
-           $self->print_to_server("smbclient: $_",
-                                  $Amanda::Script_App::ERROR);
+           chomp $line;
+           $self->print_to_server($line, $Amanda::Script_App::ERROR);
        }
-    }
+    });
+
+    Amanda::MainLoop::run();
+
     if ($size >= 0) {
        my $ksize = $size / 1024;
        if ($ksize < 32) {
@@ -746,6 +838,7 @@ sub command_restore {
        $self->validate_inexclude();
        $self->findpass();
        push @cmd, $self->{smbclient}, $self->{share};
+       push @cmd, "-D", $self->{'subdir'} if defined $self->{'subdir'};
        push @cmd, "" if (!defined $self->{password});
        push @cmd, "-d", "0",
                   "-U", $self->{username};
index 0959a1619b0ffeca8867ce88b21eee0954416a1f..c351d2c3442799a920f4fb72c84b0983b47f81da 100644 (file)
@@ -758,7 +758,7 @@ amstar_backup(
 
        if (regexec(&regex_dir, line, 3, regmatch, 0) == 0) {
            if (argument->dle.create_index && regmatch[1].rm_so == 2) {
-               line[regmatch[1].rm_eo+1]='\0';
+               line[regmatch[1].rm_eo]='\0';
                fprintf(indexstream, "/%s\n", &line[regmatch[1].rm_so]);
            }
            continue;
index bc2db311a1d74902c416b93780ced36030c97603..96917d1ebed0c7c0cb15115ee38180179b660c41 100755 (executable)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 1bbbb9c97a2621bdb67b32ee230af3fda5da85d4..7e6b4572a0c5b4c7059ff4c7f2106bbc28f27d96 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -102,7 +102,8 @@ sub command_support {
 sub command_selfcheck {
     my $self = shift;
 
-    $self->print_to_server("disk " . quote_string($self->{disk}));
+    $self->print_to_server("disk " . quote_string($self->{disk}),
+                          $Amanda::Script_App::GOOD);
 
     $self->print_to_server("amzfs-sendrecv version " . $Amanda::Constants::VERSION,
                           $Amanda::Script_App::GOOD);
index 676e60e57b4ad9858cb95dad4db7d1f49153aead..9deee6cb92cccabf895693561de52991f46887b2 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 07694ac7b287d8593a05477f2a3896b9a05d3493..14ed1adf9399c653ca17ff9762b18e0f19390c44 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f6e3b92724c35df9a3f91ed465b670f68920e992..226ff6eb02671ec16a4678a265de6ddeee543249 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda tape changer programs.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -40,7 +40,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -334,7 +334,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -875,6 +876,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 9bf098d47ec128b5620c86b2fb74debad22e60ea..aff1a681baf863e0872073e65ba0e375433841be 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda client programs.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -40,7 +40,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -345,7 +345,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -973,6 +974,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 560747c7d82e51f39c83506244cf6d425e323f39..f0fd0bbdd951c4602ff30f1210f6b062e47f6097 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -101,7 +101,7 @@ if ($cmd eq 'list') {
                    debug("send: DISK " . Amanda::Util::quote_string($diskname));
                    print {$amservice_in} "DISK " . Amanda::Util::quote_string($diskname) . "\n";
                    my $a = <$amservice_out>;
-                   print if ($a != /^DISK /)
+                   print if ($a !~ /^DISK /)
                }
            }
        }
index 5c77ef5b3324477530b42ab12e3f882f5812c03d..9b23647e0276cace1e487fbf6ce72461d643f4f6 100644 (file)
@@ -35,7 +35,7 @@
 #include "match.h"
 #include "conffile.h"
 #include "fsusage.h"
-#include "sl.h"
+#include "am_sl.h"
 #include "util.h"
 
 #define ROUND(n,x)     ((x) + (n) - 1 - (((x) + (n) - 1) % (n)))
@@ -108,12 +108,12 @@ void add_file_name_unknown(int, char *);
 void add_file_unknown(int, struct stat *);
 off_t final_size_unknown(int, char *);
 
-sl_t *calc_load_file(char *filename);
+am_sl_t *calc_load_file(char *filename);
 int calc_check_exclude(char *filename);
 
 int use_star_excl = 0;
 int use_gtar_excl = 0;
-sl_t *include_sl=NULL, *exclude_sl=NULL;
+am_sl_t *include_sl=NULL, *exclude_sl=NULL;
 
 int
 main(
@@ -682,13 +682,13 @@ final_size_unknown(
 /*
  * =========================================================================
  */
-sl_t *
+am_sl_t *
 calc_load_file(
     char *     filename)
 {
     char pattern[1025];
 
-    sl_t *sl_list;
+    am_sl_t *sl_list;
 
     FILE *file = fopen(filename, "r");
 
index 513d9ba7402fcd180fd71d30ad5cc31b6906479b..27694a67beae98e9aca4cade56ff27f91dc89a06 100644 (file)
@@ -1166,7 +1166,7 @@ run_client_script(
        levellist_t levellist;
        char number[NUM_STR_SIZE];
        for (levellist=dle->levellist; levellist; levellist=levellist->next) {
-           level_t *alevel = (level_t *)levellist->data;
+           am_level_t *alevel = (am_level_t *)levellist->data;
            g_ptr_array_add(argv_ptr, stralloc("--level"));
            g_snprintf(number, SIZEOF(number), "%d", alevel->level);
            g_ptr_array_add(argv_ptr, stralloc(number));
index a2c74420d8a3aae30896223405ecbf34456fcaa5..b714d8cd4bf35008c6baf7dc68aaeb5cfc93021b 100644 (file)
@@ -34,7 +34,7 @@
 #include "amanda.h"
 #include "conffile.h"
 #include "amfeatures.h"
-#include "sl.h"
+#include "am_sl.h"
 #include "util.h"              /* for bstrncmp() */
 #include "amandad.h"           /* for g_option_t */
 #include "amxml.h"             /* for dle_t      */
index e044a6cd50fbc6febd1aad01a2f253d2bab5ea48..8cd7b539361b8f7d7fe9c004e0694950e8c75133 100644 (file)
@@ -95,7 +95,7 @@ main(
     dle_t *dle;
     int level;
     GSList *errlist;
-    level_t *alevel;
+    am_level_t *alevel;
 
     if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) {
        printf("selfcheck-%s\n", VERSION);
@@ -260,7 +260,7 @@ main(
        if (ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
            goto err;                           /* bad level */
        }
-       alevel = g_new0(level_t, 1);
+       alevel = g_new0(am_level_t, 1);
        alevel->level = level;
        dle->levellist = g_slist_append(dle->levellist, alevel);
        skip_integer(s, ch);
index 036d380197538631a68e8b63b6a8482f5673c621..14fd27e4b4d3e517ed7fab246e1e4e8d76194449 100644 (file)
@@ -143,7 +143,7 @@ start_backup(
     char *encryptopt = skip_argument;
     char *qdisk;
     char *config;
-    level_t *alevel = (level_t *)dle->levellist->data;
+    am_level_t *alevel = (am_level_t *)dle->levellist->data;
     int      level  = alevel->level;
 
     g_snprintf(level_str, SIZEOF(level_str), "%d", level);
index 3b718aebd2251337e9749875654859863a806adf..1aeb399520d00e98333d00e6f3a3a46a138fd644 100644 (file)
@@ -156,7 +156,7 @@ start_backup(
     ssize_t nb;
     char buf[32768];
     char *amandates_file = NULL;
-    level_t *alevel = (level_t *)dle->levellist->data;
+    am_level_t *alevel = (am_level_t *)dle->levellist->data;
     int      level  = alevel->level;
 
     error_pn = stralloc2(get_pname(), "-smbclient");
index 506d45babb9e9456fb89bec87cf96177fecea57e..5b9b7e9fbb0d60de18454774420945f45a6cf8e5 100644 (file)
@@ -39,6 +39,7 @@
 #include "getfsent.h"
 #include "conffile.h"
 #include "amandates.h"
+#include "stream.h"
 
 #define sendbackup_debug(i, ...) do {  \
        if ((i) <= debug_sendbackup) {  \
@@ -124,7 +125,7 @@ main(
     int ch;
     GSList *errlist;
     FILE   *mesgstream;
-    level_t *alevel;
+    am_level_t *alevel;
 
     if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) {
        printf("sendbackup-%s\n", VERSION);
@@ -304,7 +305,7 @@ main(
            goto err;                           /* bad level */
        }
        skip_integer(s, ch);
-       alevel = g_new0(level_t, 1);
+       alevel = g_new0(am_level_t, 1);
        alevel->level = level;
        dle->levellist = g_slist_append(dle->levellist, alevel);
 
@@ -384,7 +385,7 @@ main(
        goto err;
     }
 
-    alevel = (level_t *)dle->levellist->data;
+    alevel = (am_level_t *)dle->levellist->data;
     level = alevel->level;
     dbprintf(_("  Parsed request as: program `%s'\n"), dle->program);
     dbprintf(_("                     disk `%s'\n"), qdisk);
@@ -586,6 +587,49 @@ main(
 
        switch(application_api_pid=fork()) {
        case 0:
+           application_api_info_tapeheader(mesgfd, dle->program, dle);
+
+           /* find directt-tcp address from indirect direct-tcp */
+           if (dle->data_path == DATA_PATH_DIRECTTCP &&
+               bsu->data_path_set & DATA_PATH_DIRECTTCP &&
+               strncmp(dle->directtcp_list->data, "255.255.255.255:", 16) == 0) {
+               char *indirect_tcp;
+               char *str_port;
+               in_port_t port;
+               int fd;
+               char buffer[32770];
+               int size;
+               char *s, *s1;
+
+               indirect_tcp = g_strdup(dle->directtcp_list->data);
+               g_slist_free(dle->directtcp_list);
+               dle->directtcp_list = NULL;
+               str_port = strchr(indirect_tcp, ':');
+               str_port++;
+               port = atoi(str_port);
+               fd = stream_client("localhost", port, 32768, 32768, NULL, 0);
+               if (fd <= 0) {
+                   g_debug("Failed to connect to indirect-direct-tcp port: %s",
+                           strerror(errno));
+                   exit(1);
+               }
+               size = full_read(fd, buffer, 32768);
+               if (size <= 0) {
+                   g_debug("Failed to read from indirect-direct-tcp port: %s",
+                           strerror(errno));
+                   exit(1);
+               }
+               buffer[size++] = ' ';
+               buffer[size] = '\0';
+               s1 = buffer;
+               while ((s = strchr(s1, ' ')) != NULL) {
+                   *s++ = '\0';
+                   dle->directtcp_list = g_slist_append(dle->directtcp_list, g_strdup(s1));
+                   s1 = s;
+               }
+               amfree(indirect_tcp);
+           }
+
            argv_ptr = g_ptr_array_new();
            cmd = vstralloc(APPLICATION_DIR, "/", dle->program, NULL);
            g_ptr_array_add(argv_ptr, stralloc(dle->program));
@@ -655,7 +699,6 @@ main(
                }
                fcntl(indexfd, F_SETFD, 0);
            }
-           application_api_info_tapeheader(mesgfd, dle->program, dle);
            if (indexfd != 0) {
                safe_fd(3, 2);
            } else {
index 083ec65e665850744e800a033a0d7d4b82e854bd..a82637cefa559eaae0563628460977fc78e4aa47 100644 (file)
@@ -135,7 +135,7 @@ main(
     char *qamdevice = NULL;
     dle_t *dle;
     GSList *errlist;
-    level_t *alevel;
+    am_level_t *alevel;
 
     (void)argc;        /* Quiet unused parameter warning */
     (void)argv;        /* Quiet unused parameter warning */
@@ -322,7 +322,7 @@ main(
            goto err;
        }
        skip_integer(s, ch);
-       alevel = g_new0(level_t, 1);
+       alevel = g_new0(am_level_t, 1);
        alevel->level = level;
        dle->levellist = g_slist_append(dle->levellist, alevel);
 
@@ -637,7 +637,7 @@ dle_add_diskest(
 
     levellist = dle->levellist;
     while (levellist != NULL) {
-       level_t *alevel = (level_t *)levellist->data;
+       am_level_t *alevel = (am_level_t *)levellist->data;
        if (alevel->level < 0)
            alevel->level = 0;
        if (alevel->level >= DUMP_LEVELS)
@@ -650,7 +650,7 @@ dle_add_diskest(
            /* already have disk info, just note the level request */
            levellist = dle->levellist;
            while (levellist != NULL) {
-               level_t *alevel = (level_t *)levellist->data;
+               am_level_t *alevel = (am_level_t *)levellist->data;
                int      level  = alevel->level;
                curp->est[level].needestimate = 1;
                curp->est[level].server = alevel->server;
@@ -677,7 +677,7 @@ dle_add_diskest(
     }
     levellist = dle->levellist;
     while (levellist != NULL) {
-       level_t *alevel = (level_t *)levellist->data;
+       am_level_t *alevel = (am_level_t *)levellist->data;
        newp->est[alevel->level].needestimate = 1;
        newp->est[alevel->level].server = alevel->server;
        levellist = g_slist_next(levellist);
index d1686f1f27f9cabf736fb04aad861f8c19d666f4..40e2eb63c288ad2aed4b047a945e4d21270eefa2 100644 (file)
@@ -5,7 +5,7 @@ include $(top_srcdir)/config/automake/scripts.am
 include $(top_srcdir)/config/automake/installperms.am
 include $(top_srcdir)/config/automake/precompile.am
 
-INCLUDES =      -I$(top_srcdir)/gnulib   
+INCLUDES =      -I$(top_srcdir)/gnulib
 
 AM_CFLAGS = $(AMANDA_WARNING_CFLAGS)
 AM_LDFLAGS = $(AMANDA_STATIC_LDFLAGS) $(AS_NEEDED_FLAGS)
@@ -19,6 +19,7 @@ LINTFLAGS=$(AMLINTFLAGS)
 
 libamanda_la_SOURCES =         \
        alloc.c                 \
+       am_sl.c                 \
        amfeatures.c            \
        amflock.c               \
        ipc-binary.c            \
@@ -40,7 +41,6 @@ libamanda_la_SOURCES =                \
        security.c              \
        security-util.c         \
        simpleprng.c            \
-       sl.c                    \
        sockaddr-util.c         \
        stream.c                \
        tapelist.c              \
@@ -123,7 +123,7 @@ noinst_HEADERS =            \
        security.h              \
        security-util.h         \
        simpleprng.h            \
-       sl.h                    \
+       am_sl.h                 \
        sockaddr-util.h         \
        stream.h                \
        tapelist.h              \
index 4b108106f658595fc5e9342ff0ed5009715bcc5a..9d35e45a52b72982c2cce904fe2bd5ab89c95235 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda library.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -40,7 +40,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -358,7 +358,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -391,11 +392,11 @@ am__installdirs = "$(DESTDIR)$(amlibdir)" "$(DESTDIR)$(sbindir)" \
        "$(DESTDIR)$(amlibexecdir)"
 LTLIBRARIES = $(amlib_LTLIBRARIES) $(noinst_LTLIBRARIES)
 libamanda_la_DEPENDENCIES = ../gnulib/libgnu.la
-am__libamanda_la_SOURCES_DIST = alloc.c amfeatures.c amflock.c \
+am__libamanda_la_SOURCES_DIST = alloc.c am_sl.c amfeatures.c amflock.c \
        ipc-binary.c amxml.c clock.c columnar.c conffile.c debug.c \
        dgram.c event.c file.c fileheader.c glib-util.c match.c \
        packet.c pipespawn.c protocol.c amsemaphore.c security.c \
-       security-util.c simpleprng.c sl.c sockaddr-util.c stream.c \
+       security-util.c simpleprng.c sockaddr-util.c stream.c \
        tapelist.c timestamp.c util.c amflock-posix.c amflock-flock.c \
        amflock-lockf.c amflock-lnlock.c rsh-security.c ssh-security.c \
        bsd-security.c bsdtcp-security.c bsdudp-security.c \
@@ -410,16 +411,16 @@ am__libamanda_la_SOURCES_DIST = alloc.c amfeatures.c amflock.c \
 @WANT_BSDTCP_SECURITY_TRUE@am__objects_8 = bsdtcp-security.lo
 @WANT_BSDUDP_SECURITY_TRUE@am__objects_9 = bsdudp-security.lo
 @WANT_KRB5_SECURITY_TRUE@am__objects_10 = krb5-security.lo
-am_libamanda_la_OBJECTS = alloc.lo amfeatures.lo amflock.lo \
+am_libamanda_la_OBJECTS = alloc.lo am_sl.lo amfeatures.lo amflock.lo \
        ipc-binary.lo amxml.lo clock.lo columnar.lo conffile.lo \
        debug.lo dgram.lo event.lo file.lo fileheader.lo glib-util.lo \
        match.lo packet.lo pipespawn.lo protocol.lo amsemaphore.lo \
-       security.lo security-util.lo simpleprng.lo sl.lo \
-       sockaddr-util.lo stream.lo tapelist.lo timestamp.lo util.lo \
-       $(am__objects_1) $(am__objects_2) $(am__objects_3) \
-       $(am__objects_4) $(am__objects_5) $(am__objects_6) \
-       $(am__objects_7) $(am__objects_8) $(am__objects_9) \
-       $(am__objects_10) local-security.lo
+       security.lo security-util.lo simpleprng.lo sockaddr-util.lo \
+       stream.lo tapelist.lo timestamp.lo util.lo $(am__objects_1) \
+       $(am__objects_2) $(am__objects_3) $(am__objects_4) \
+       $(am__objects_5) $(am__objects_6) $(am__objects_7) \
+       $(am__objects_8) $(am__objects_9) $(am__objects_10) \
+       local-security.lo
 nodist_libamanda_la_OBJECTS = version.lo
 libamanda_la_OBJECTS = $(am_libamanda_la_OBJECTS) \
        $(nodist_libamanda_la_OBJECTS)
@@ -1015,6 +1016,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
@@ -1360,18 +1364,18 @@ do_installperms = dest=; chown=; chmod=; \
            esac; \
        done
 
-INCLUDES = -I$(top_srcdir)/gnulib   
+INCLUDES = -I$(top_srcdir)/gnulib
 AM_CFLAGS = $(AMANDA_WARNING_CFLAGS)
 AM_LDFLAGS = $(AMANDA_STATIC_LDFLAGS) $(AS_NEEDED_FLAGS)
 amlib_LTLIBRARIES = libamanda.la
 LINT = $(AMLINT)
 LINTFLAGS = $(AMLINTFLAGS)
-libamanda_la_SOURCES = alloc.c amfeatures.c amflock.c ipc-binary.c \
-       amxml.c clock.c columnar.c conffile.c debug.c dgram.c event.c \
-       file.c fileheader.c glib-util.c match.c packet.c pipespawn.c \
-       protocol.c amsemaphore.c security.c security-util.c \
-       simpleprng.c sl.c sockaddr-util.c stream.c tapelist.c \
-       timestamp.c util.c $(am__append_2) $(am__append_3) \
+libamanda_la_SOURCES = alloc.c am_sl.c amfeatures.c amflock.c \
+       ipc-binary.c amxml.c clock.c columnar.c conffile.c debug.c \
+       dgram.c event.c file.c fileheader.c glib-util.c match.c \
+       packet.c pipespawn.c protocol.c amsemaphore.c security.c \
+       security-util.c simpleprng.c sockaddr-util.c stream.c \
+       tapelist.c timestamp.c util.c $(am__append_2) $(am__append_3) \
        $(am__append_4) $(am__append_5) $(am__append_6) \
        $(am__append_7) $(am__append_8) $(am__append_9) \
        $(am__append_10) $(am__append_11) local-security.c
@@ -1411,7 +1415,7 @@ noinst_HEADERS = \
        security.h              \
        security-util.h         \
        simpleprng.h            \
-       sl.h                    \
+       am_sl.h                 \
        sockaddr-util.h         \
        stream.h                \
        tapelist.h              \
@@ -1760,6 +1764,7 @@ distclean-compile:
        -rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/am_sl.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amfeatures.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amflock-flock.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amflock-lnlock.Plo@am__quote@
@@ -1803,7 +1808,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security-util.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleprng.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sl.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockaddr-util.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh-security.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream.Plo@am__quote@
diff --git a/common-src/am_sl.c b/common-src/am_sl.c
new file mode 100644 (file)
index 0000000..e20c310
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                         Computer Science Department
+ *                         University of Maryland at College Park
+ */
+/*
+ * $Id: sl.c,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
+ *
+ * A doubly linked list of string (char *)
+ */
+
+#include "amanda.h"
+#include "am_sl.h"
+
+
+void init_sl(
+    am_sl_t *sl)
+{
+    sl->first = NULL;
+    sl->last  = NULL;
+    sl->nb_element = 0;
+}
+
+
+am_sl_t *
+new_sl(void)
+{
+    am_sl_t *sl;
+    sl = alloc(SIZEOF(am_sl_t));
+    init_sl(sl);
+    return(sl);
+}
+
+
+am_sl_t *
+insert_sl(
+    am_sl_t *sl,
+    char *name)
+{
+    sle_t *a;
+
+    if(!sl) {
+       sl = new_sl();
+    }
+    a = alloc(SIZEOF(sle_t));
+    a->name = stralloc(name);
+    a->next = sl->first;
+    a->prev = NULL;
+    if(a->next)
+       a->next->prev = a;
+    else
+       sl->last = a;
+    sl->first = a;
+    sl->nb_element++;
+    return(sl);
+}
+
+
+am_sl_t *
+append_sl(
+    am_sl_t *  sl,
+    char *     name)
+{
+    sle_t *a;
+
+    if(!sl) {
+       sl = new_sl();
+    }
+    a = alloc(SIZEOF(sle_t));
+    a->name = stralloc(name);
+    a->prev = sl->last;
+    a->next = NULL;
+    if(a->prev)
+       a->prev->next = a;
+    else
+       sl->first = a;
+    sl->last = a;
+    sl->nb_element++;
+    return(sl);
+}
+
+
+am_sl_t *
+insert_sort_sl(
+    am_sl_t *  sl,
+    char *     name)
+{
+    sle_t *a, *b;
+
+    if(!sl) {
+       sl = new_sl();
+    }
+
+    for(b=sl->first; b != NULL; b=b->next) {
+       int i = strcmp(b->name, name);
+       if(i==0) return(sl); /* already there, no need to insert */
+       if(i>0) break;
+    }
+
+    if(b == sl->first) return insert_sl(sl, name);
+    if(b == NULL)      return append_sl(sl, name);
+
+    a = alloc(SIZEOF(sle_t));
+    a->name = stralloc(name);
+
+    /* insert before b */
+    a->next = b;
+    a->prev = b->prev;
+    b->prev->next = a;
+    b->prev = a;
+    sl->nb_element++;
+    return(sl);
+}
+
+
+void
+free_sl(
+    am_sl_t *  sl)
+{
+    sle_t *a, *b;
+
+    if(!sl) return;
+
+    a = sl->first;
+    while(a != NULL) {
+       b = a;
+       a = a->next;
+       amfree(b->name);
+       amfree(b);
+    }
+    amfree(sl);
+}
+
+
+void
+remove_sl(
+    am_sl_t *  sl,
+    sle_t *    elem)
+{
+    if(elem->prev)
+       elem->prev->next = elem->next;
+    else
+       sl->first = elem->next;
+
+    if(elem->next)
+       elem->next->prev = elem->prev;
+    else
+       sl->last = elem->prev;
+
+    sl->nb_element--;
+
+    amfree(elem->name);
+    amfree(elem);
+}
+
+
+am_sl_t *
+duplicate_sl(
+    am_sl_t *  sl)
+{
+    am_sl_t *new_sl = NULL;
+    sle_t *a;
+
+    if(!sl) return new_sl;
+
+    for(a = sl->first; a != NULL; a = a->next) {
+       new_sl = append_sl(new_sl, a->name);
+    }
+
+    return new_sl;
+}
+
+/*
+ * Return "true" iff sl is empty (i.e. contains no elements).
+ */
+int
+is_empty_sl(
+    am_sl_t *  sl)
+{
+    if (sl == NULL)
+       return 1;
+
+    return (sl->nb_element == 0);
+}
diff --git a/common-src/am_sl.h b/common-src/am_sl.h
new file mode 100644 (file)
index 0000000..ecdd5e6
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                         Computer Science Department
+ *                         University of Maryland at College Park
+ */
+/*
+ * $Id: sl.h,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
+ *
+ * A doubly linked list of string (char *)
+ */
+
+/*
+ * To scan over all element of the list
+ *
+ *    for(sle=sl->first; sle != NULL; sle = sle->next) {
+ *    }
+ */
+#ifndef STRINGLIST_H
+#define STRINGLIST_H
+
+#include "amanda.h"
+
+typedef struct sle_s {
+    struct sle_s *next, *prev;
+    char *name;
+} sle_t;
+
+typedef struct sl_s {
+    struct sle_s *first, *last;
+    int nb_element;
+} am_sl_t;
+
+void init_sl(am_sl_t *sl);
+am_sl_t *new_sl(void);
+am_sl_t *insert_sl(am_sl_t *sl, char *name);
+am_sl_t *append_sl(am_sl_t *sl, char *name);
+am_sl_t *insert_sort_sl(am_sl_t *sl, char *name);
+void free_sl(am_sl_t *sl);
+void remove_sl(am_sl_t *sl,sle_t *elem);
+am_sl_t *duplicate_sl(am_sl_t *sl);
+int  is_empty_sl(am_sl_t *sl);
+
+#endif
index d9593cd7bd85eaf04adddfc69fe46d9f859006f0..ac14eead0f5463c49c4f0a1590f8c788c4f3dfb3 100755 (executable)
@@ -1,6 +1,6 @@
 #! @SHELL@
 #
-# Copyright (c) 2007, 2008, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda Inc.  All Rights Reserved.
 # 
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index e8d492280dcb037ca5477cc15a237d7661b32575..dd8760f91d0e0461dbce95e305c0224706201f03 100755 (executable)
@@ -1,6 +1,6 @@
 #!@PERL@ -w
 #
-# Copyright (c) 2007,2008 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -62,9 +62,22 @@ sub do_gpg_agent() {
     return ""
 }
 
+sub which_gpg() {
+    my $path=`which gpg2 2>/dev/null`;
+    if (!$path) {
+        $path=`which gpg 2>/dev/null`;
+    }
+    if (!$path) {
+        die("no gpg or gpg2");
+    }
+    chomp $path;
+    return $path;
+}
+
 sub encrypt() {
     my $gpg_agent_cmd = do_gpg_agent();
-    system "$gpg_agent_cmd gpg --batch --no-secmem-warning --disable-mdc --symmetric --cipher-algo AES256 --passphrase-fd 3  3<$AM_PASS";
+    my $gpg = which_gpg();
+    system "$gpg_agent_cmd $gpg --batch --no-secmem-warning --disable-mdc --symmetric --cipher-algo AES256 --passphrase-fd 3  3<$AM_PASS";
     if ($? == -1) {
        print STDERR "failed to execute gpg: $!\n";
        exit (1);
@@ -79,7 +92,8 @@ sub encrypt() {
 
 sub decrypt() {
     my $gpg_agent_cmd = do_gpg_agent();
-    system "$gpg_agent_cmd gpg --batch --quiet --no-mdc-warning --decrypt --passphrase-fd 3  3<$AM_PASS";
+    my $gpg = which_gpg();
+    system "$gpg_agent_cmd $gpg --batch --quiet --no-mdc-warning --decrypt --passphrase-fd 3  3<$AM_PASS";
     if ($? == -1) {
        print STDERR "failed to execute gpg: $!\n";
        exit (1);
index 858c2885594a4403b948669f8c3d0b42df84f552..20fad47868cf605dc9680dae553b3704d4309473 100644 (file)
  * New Implementation
  */
 
-static GStaticMutex lock_lock = G_STATIC_MUTEX_INIT;
+#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31))
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+  static GStaticMutex lock_lock = G_STATIC_MUTEX_INIT;
+# pragma GCC diagnostic pop
+#else
+  static GStaticMutex lock_lock = G_STATIC_MUTEX_INIT;
+#endif
 static GHashTable *locally_locked_files = NULL;
 static int lock_rw_rd(file_lock *lock, short l_type);
 
index 23a9f1e93e484808548ea5f3b25d85346c71083e..b35cf20fcb268ab49635e3d8d937f511e8b75faf 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -25,6 +25,7 @@ use Amanda::Debug qw( :logging );
 use Amanda::Util qw( :constants );
 use Amanda::Paths;
 use Amanda::Constants;
+eval 'use Amanda::Disklist;';  # can fail if compiled for client only
 use Getopt::Long;
 
 # Implementation note: this application is a bit funny, because it does not
@@ -350,6 +351,14 @@ if ($cfgerr_level >= $CFGERR_WARNINGS) {
 
 Amanda::Util::finish_setup($RUNNING_AS_ANY);
 
+if ($execute_where != $CONFIG_INIT_CLIENT) {
+    my $diskfile = Amanda::Config::config_dir_relative(getconf($CNF_DISKFILE));
+    $cfgerr_level = Amanda::Disklist::read_disklist('filename' => $diskfile);
+#    if ($cfgerr_level >= $CFGERR_ERRORS) {
+#      die "Errors processing disklist";
+#    }
+}
+
 conf_param($parameter, $opt_list);
 
 Amanda::Util::finish_application();
index 2a0c2ebf1223f0c4e92999a5f10d0f4916c23635..50db13a22b9d92bfbc59fd27a4fe6c91a3631f50 100755 (executable)
@@ -1,6 +1,6 @@
 #!@PERL@ -w
 #
-# Copyright (c) 2007,2008 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -46,13 +46,37 @@ $ENV{'PATH'} = '/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin:/opt/csw/bin';
 
 $ENV{'GNUPGHOME'} = "$AMANDA_HOME/.gnupg";
 
+sub do_gpg_agent() {
+    my $path=`which gpg-agent 2>/dev/null`;
+    chomp $path;
+    if (-x $path) {
+       return "gpg-agent --daemon --";
+    }
+    return ""
+}
+
+sub which_gpg() {
+    my $path=`which gpg2 2>/dev/null`;
+    if (!$path) {
+       $path=`which gpg 2>/dev/null`;
+    }
+    if (!$path) {
+       die("no gpg or gpg2");
+    }
+    chomp $path;
+    return $path;
+}
+
 sub encrypt() {
-#   system "gpg --armor --encrypt --recipient $AMANDA";
-    system "gpg  --batch --disable-mdc --encrypt --cipher-algo AES256 --recipient $AMANDA";
+    my $gpg_agent_cmd = do_gpg_agent();
+    my $gpg = which_gpg();
+    system "$gpg_agent_cmd $gpg  --batch --disable-mdc --encrypt --cipher-algo AES256 --recipient $AMANDA";
 }
 
 sub decrypt() {
-     system "gpg --batch --quiet --no-mdc-warning --secret-keyring $AM_PRIV --decrypt --passphrase-fd 3  3<$AM_PASS";
+    my $gpg_agent_cmd = do_gpg_agent();
+    my $gpg = which_gpg();
+    system "$gpg_agent_cmd $gpg --batch --quiet --no-mdc-warning --secret-keyring $AM_PRIV --decrypt --passphrase-fd 3  3<$AM_PASS";
 }
 
 sub my_sig_catcher {
index 5ca4a4082ebb0eda280ce4ab3d696e89277c3d39..eb4c915c354695f1d4ccb2bef9925d5eb86a7c27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 554e7585b687eeb6040f969eb899a659028068a2..52cf869c3b07d4f7253e9bb2cecccc5b95cfa4f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index cf0b974ba20ff57848f7730ae5c0084ee2d09cb2..9b7a3ac3de8c6c35c5fcfc71cb4f236af35a10ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 7aab3f6d41f4faae4c3347b1fe958aa5a855e7ac..6f1e7a6369ab73f72cdcad05c7899120f9191928 100644 (file)
@@ -60,7 +60,7 @@ typedef struct amgxml_s {
     property_t *property_data;
     proplist_t  property;
     script_t   *script;
-    level_t    *alevel;
+    am_level_t    *alevel;
     char       *encoding;
     char       *raw;
 } amgxml_t;
@@ -315,7 +315,7 @@ amstart_element(
        if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0)
           data_user->has_optional = 0;
        if (strcmp(element_name, "level") == 0) {
-           data_user->alevel = g_new0(level_t, 1);
+           data_user->alevel = g_new0(am_level_t, 1);
        }
     } else if (strcmp(element_name, "server") == 0) {
        if (strcmp(last_element_name, "level") != 0) {
@@ -555,7 +555,7 @@ amtext(
     }
     last_element_name = last_element->data;
 
-    tt = malloc(text_len + 1);
+    tt = malloc(text_len + 8 + 1);
     strncpy(tt,text,text_len);
     tt[text_len] = '\0';
 
index a8d40456b72c6cf46bf6323c1d85261db283ba61..063fb11d0ec5a8cb2bc9e82b9ea1c75f3c2f441f 100644 (file)
@@ -49,8 +49,8 @@ typedef GSList *scriptlist_t;
 typedef struct level_s {
     int level;
     int server;                        /* if server can do the estimate */
-} level_t;
-typedef GSList *levellist_t;   /* A list where each element is a (level_t *) */
+} am_level_t;
+typedef GSList *levellist_t;   /* A list where each element is a (am_level_t *) */
 
 typedef struct a_dle_s {
     char   *disk;
@@ -73,10 +73,10 @@ typedef struct a_dle_s {
     int     record;
     int     create_index;
     char   *auth;
-    sl_t   *exclude_file;
-    sl_t   *exclude_list;
-    sl_t   *include_file;
-    sl_t   *include_list;
+    am_sl_t   *exclude_file;
+    am_sl_t   *exclude_list;
+    am_sl_t   *include_file;
+    am_sl_t   *include_list;
     int     exclude_optional;
     int     include_optional;
     proplist_t property;
index 7277e481e87dde296c230d611f5bf93edc5cf738..4d48220ae02cbd47b0c6acdc07d259eb5ae33aa8 100644 (file)
@@ -91,7 +91,7 @@ typedef enum {
     CONF_DEVICE,               CONF_ORDER,             CONF_SINGLE_EXECUTION,
     CONF_DATA_PATH,            CONF_AMANDA,            CONF_DIRECTTCP,
     CONF_TAPER_PARALLEL_WRITE, CONF_INTERACTIVITY,     CONF_TAPERSCAN,
-    CONF_MAX_DLE_BY_VOLUME,    CONF_EJECT_VOLUME,
+    CONF_MAX_DLE_BY_VOLUME,    CONF_EJECT_VOLUME,      CONF_TMPDIR,
 
     /* execute on */
     CONF_PRE_AMCHECK,          CONF_POST_AMCHECK,
@@ -128,6 +128,7 @@ typedef enum {
     CONF_CLNTCOMPPROG,         CONF_SRV_ENCRYPT,       CONF_CLNT_ENCRYPT,
     CONF_SRV_DECRYPT_OPT,      CONF_CLNT_DECRYPT_OPT,  CONF_AMANDAD_PATH,
     CONF_CLIENT_USERNAME,      CONF_CLIENT_PORT,       CONF_ALLOW_SPLIT,
+    CONF_MAX_WARNINGS,
 
     /* tape type */
     /*COMMENT,*/               CONF_BLOCKSIZE,
@@ -229,6 +230,7 @@ static FILE *current_file = NULL;
 static char *current_filename = NULL;
 static char *current_line = NULL;
 static char *current_char = NULL;
+static char *current_block = NULL;
 static int current_line_num = 0; /* (technically, managed by the parser) */
 
 /* A static buffer for storing tokens while they are being scanned. */
@@ -357,7 +359,7 @@ struct device_config_s {
 
 struct changer_config_s {
     struct changer_config_s *next;
-    int seen;
+    seen_t seen;
     char *name;
 
     val_t value[CHANGER_CONFIG_CHANGER_CONFIG];
@@ -521,7 +523,6 @@ static void read_str(conf_var_t *, val_t *);
 static void read_ident(conf_var_t *, val_t *);
 static void read_time(conf_var_t *, val_t *);
 static void read_size(conf_var_t *, val_t *);
-static void read_size_byte(conf_var_t *, val_t *);
 static void read_bool(conf_var_t *, val_t *);
 static void read_no_yes_all(conf_var_t *, val_t *);
 static void read_compress(conf_var_t *, val_t *);
@@ -566,11 +567,11 @@ static taperscan_t *read_taperscan(char *name, FILE *from, char *fname,
  * values can be written: integers can have units, boolean values can be
  * specified with a number of names, etc.  They form utility functions
  * for the read_functions, below. */
+static gint64 get_multiplier(gint64 val, confunit_t unit);
 static time_t  get_time(void);
-static int     get_int(void);
-static ssize_t get_size(void);
-static ssize_t get_size_byte(void);
-static gint64  get_int64(void);
+static int     get_int(confunit_t unit);
+static ssize_t get_size(confunit_t unit);
+static gint64  get_int64(confunit_t unit);
 static int     get_bool(void);
 static int     get_no_yes_all(void);
 
@@ -603,6 +604,8 @@ static void validate_reserved_port_range(conf_var_t *, val_t *);
 static void validate_unreserved_port_range(conf_var_t *, val_t *);
 static void validate_program(conf_var_t *, val_t *);
 static void validate_dump_limit(conf_var_t *, val_t *);
+static void validate_tmpdir(conf_var_t *, val_t *);
+
 gint compare_pp_script_order(gconstpointer a, gconstpointer b);
 
 /*
@@ -691,14 +694,14 @@ static cfgerr_level_t apply_config_overrides(config_overrides_t *co,
  * These set the value's type and seen flags, as well as copying
  * the relevant value into the 'v' field.
  */
-static void conf_init_int(val_t *val, int i);
-static void conf_init_int64(val_t *val, gint64 l);
+static void conf_init_int(val_t *val, confunit_t unit, int i);
+static void conf_init_int64(val_t *val, confunit_t unit, gint64 l);
 static void conf_init_real(val_t *val, float r);
 static void conf_init_str(val_t *val, char *s);
 static void conf_init_ident(val_t *val, char *s);
 static void conf_init_identlist(val_t *val, char *s);
 static void conf_init_time(val_t *val, time_t t);
-static void conf_init_size(val_t *val, ssize_t sz);
+static void conf_init_size(val_t *val, confunit_t unit, ssize_t sz);
 static void conf_init_bool(val_t *val, int i);
 static void conf_init_no_yes_all(val_t *val, int i);
 static void conf_init_compress(val_t *val, comp_t i);
@@ -756,7 +759,7 @@ void free_property_t(gpointer p);
 /* Utility functions/structs for val_t_display_strs */
 static char *exinclude_display_str(val_t *val, int file);
 static void proplist_display_str_foreach_fn(gpointer key_p, gpointer value_p, gpointer user_data_p);
-static void val_t_print_token(FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val);
+static void val_t_print_token(gboolean print_default, gboolean print_source, FILE *output, char *prefix, char *format, keytab_t *kt, val_t *val);
 
 /* Given a key name as used in config overwrites, return a pointer to the corresponding
  * conf_var_t in the current parsetable, and the val_t representing that value.  This
@@ -1002,6 +1005,7 @@ keytab_t server_keytab[] = {
     { "MAXDUMPS", CONF_MAXDUMPS },
     { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
     { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
+    { "MAX_WARNINGS", CONF_MAX_WARNINGS },
     { "MEMORY", CONF_MEMORY },
     { "MEDIUM", CONF_MEDIUM },
     { "META_AUTOLABEL", CONF_META_AUTOLABEL },
@@ -1090,6 +1094,7 @@ keytab_t server_keytab[] = {
     { "TAPERFLUSH", CONF_TAPERFLUSH },
     { "TAPETYPE", CONF_TAPETYPE },
     { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
+    { "TMPDIR", CONF_TMPDIR },
     { "TPCHANGER", CONF_TPCHANGER },
     { "UNRESERVED_TCP_PORT", CONF_UNRESERVED_TCP_PORT },
     { "USE", CONF_USE },
@@ -1264,7 +1269,7 @@ conf_var_t server_var [] = {
    { CONF_ETIMEOUT             , CONFTYPE_INT      , read_int         , CNF_ETIMEOUT             , validate_non_zero },
    { CONF_DTIMEOUT             , CONFTYPE_INT      , read_int         , CNF_DTIMEOUT             , validate_positive },
    { CONF_CTIMEOUT             , CONFTYPE_INT      , read_int         , CNF_CTIMEOUT             , validate_positive },
-   { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size_byte   , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive },
+   { CONF_DEVICE_OUTPUT_BUFFER_SIZE, CONFTYPE_SIZE , read_size        , CNF_DEVICE_OUTPUT_BUFFER_SIZE, validate_positive },
    { CONF_COLUMNSPEC           , CONFTYPE_STR      , read_str         , CNF_COLUMNSPEC           , NULL },
    { CONF_TAPERALGO            , CONFTYPE_TAPERALGO, read_taperalgo   , CNF_TAPERALGO            , NULL },
    { CONF_TAPER_PARALLEL_WRITE , CONFTYPE_INT      , read_int         , CNF_TAPER_PARALLEL_WRITE , NULL },
@@ -1282,6 +1287,7 @@ conf_var_t server_var [] = {
    { CONF_AUTOLABEL            , CONFTYPE_AUTOLABEL, read_autolabel   , CNF_AUTOLABEL            , NULL },
    { CONF_META_AUTOLABEL       , CONFTYPE_STR      , read_str         , CNF_META_AUTOLABEL       , NULL },
    { CONF_EJECT_VOLUME         , CONFTYPE_BOOLEAN  , read_bool        , CNF_EJECT_VOLUME         , NULL },
+   { CONF_TMPDIR               , CONFTYPE_STR      , read_str         , CNF_TMPDIR               , validate_tmpdir },
    { CONF_USETIMESTAMPS        , CONFTYPE_BOOLEAN  , read_bool        , CNF_USETIMESTAMPS        , NULL },
    { CONF_AMRECOVER_DO_FSF     , CONFTYPE_BOOLEAN  , read_bool        , CNF_AMRECOVER_DO_FSF     , NULL },
    { CONF_AMRECOVER_CHANGER    , CONFTYPE_STR      , read_str         , CNF_AMRECOVER_CHANGER    , NULL },
@@ -1376,6 +1382,7 @@ conf_var_t dumptype_var [] = {
    { CONF_SCRIPT            , CONFTYPE_STR      , read_dpp_script, DUMPTYPE_SCRIPTLIST       , NULL },
    { CONF_DATA_PATH         , CONFTYPE_DATA_PATH, read_data_path, DUMPTYPE_DATA_PATH         , NULL },
    { CONF_ALLOW_SPLIT       , CONFTYPE_BOOLEAN  , read_bool    , DUMPTYPE_ALLOW_SPLIT        , NULL },
+   { CONF_MAX_WARNINGS      , CONFTYPE_INT      , read_int     , DUMPTYPE_MAX_WARNINGS       , validate_nonnegative },
    { CONF_RECOVERY_LIMIT    , CONFTYPE_HOST_LIMIT, read_host_limit, DUMPTYPE_RECOVERY_LIMIT  , NULL },
    { CONF_DUMP_LIMIT        , CONFTYPE_HOST_LIMIT, read_host_limit, DUMPTYPE_DUMP_LIMIT      , validate_dump_limit },
    { CONF_UNKNOWN           , CONFTYPE_INT      , NULL          , DUMPTYPE_DUMPTYPE          , NULL }
@@ -1903,6 +1910,7 @@ read_confline(
            else if(tok == CONF_INTERACTIVITY) get_interactivity();
            else if(tok == CONF_TAPERSCAN) get_taperscan();
            else conf_parserror(_("DUMPTYPE, INTERFACE, TAPETYPE, HOLDINGDISK, APPLICATION, SCRIPT, DEVICE, CHANGER, INTERACTIVITY or TAPERSCAN expected"));
+           current_block = NULL;
        }
        break;
 
@@ -1912,6 +1920,20 @@ read_confline(
     case CONF_END:     /* end of file */
        return 0;
 
+    /* These should never be at the begining of a line */
+    case CONF_LBRACE:
+    case CONF_RBRACE:
+    case CONF_IDENT:
+    case CONF_INT:
+    case CONF_INT64:
+    case CONF_BOOL:
+    case CONF_REAL:
+    case CONF_STRING:
+    case CONF_TIME:
+    case CONF_SIZE:
+       conf_parserror("error: not a keyword.");
+       break;
+
     /* if it's not a known punctuation mark, then check the parse table and use the
      * read_function we find there. */
     default:
@@ -2175,6 +2197,8 @@ get_holdingdisk(
 
     get_conftoken(CONF_IDENT);
     hdcur.name = stralloc(tokenval.v.s);
+    current_block = g_strconcat("holdingdisk ", hdcur.name, NULL);
+    hdcur.seen.block = current_block;
     hdcur.seen.filename = current_filename;
     hdcur.seen.linenum = current_line_num;
 
@@ -2239,9 +2263,9 @@ init_holdingdisk_defaults(
 {
     conf_init_str(&hdcur.value[HOLDING_COMMENT]  , "");
     conf_init_str(&hdcur.value[HOLDING_DISKDIR]  , "");
-    conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , (gint64)0);
+    conf_init_int64(&hdcur.value[HOLDING_DISKSIZE] , CONF_UNIT_K, (gint64)0);
                     /* 1 Gb = 1M counted in 1Kb blocks */
-    conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], (gint64)1024*1024);
+    conf_init_int64(&hdcur.value[HOLDING_CHUNKSIZE], CONF_UNIT_K, (gint64)1024*1024);
 }
 
 static void
@@ -2315,6 +2339,8 @@ read_dumptype(
        get_conftoken(CONF_IDENT);
        dpcur.name = stralloc(tokenval.v.s);
     }
+    current_block = g_strconcat("dumptype ", dpcur.name, NULL);
+    dpcur.seen.block = current_block;
     dpcur.seen.filename = current_filename;
     dpcur.seen.linenum = current_line_num;
 
@@ -2369,12 +2395,12 @@ init_dumptype_defaults(void)
     conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]);
     conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]);
     conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY]          , 1);
-    conf_init_int      (&dpcur.value[DUMPTYPE_DUMPCYCLE]         , conf_data[CNF_DUMPCYCLE].v.i);
-    conf_init_int      (&dpcur.value[DUMPTYPE_MAXDUMPS]          , conf_data[CNF_MAXDUMPS].v.i);
-    conf_init_int      (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY]     , 10000);
-    conf_init_int      (&dpcur.value[DUMPTYPE_BUMPPERCENT]       , conf_data[CNF_BUMPPERCENT].v.i);
-    conf_init_int64    (&dpcur.value[DUMPTYPE_BUMPSIZE]          , conf_data[CNF_BUMPSIZE].v.int64);
-    conf_init_int      (&dpcur.value[DUMPTYPE_BUMPDAYS]          , conf_data[CNF_BUMPDAYS].v.i);
+    conf_init_int      (&dpcur.value[DUMPTYPE_DUMPCYCLE]         , CONF_UNIT_NONE, conf_data[CNF_DUMPCYCLE].v.i);
+    conf_init_int      (&dpcur.value[DUMPTYPE_MAXDUMPS]          , CONF_UNIT_NONE, conf_data[CNF_MAXDUMPS].v.i);
+    conf_init_int      (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY]     , CONF_UNIT_NONE, 10000);
+    conf_init_int      (&dpcur.value[DUMPTYPE_BUMPPERCENT]       , CONF_UNIT_NONE, conf_data[CNF_BUMPPERCENT].v.i);
+    conf_init_int64    (&dpcur.value[DUMPTYPE_BUMPSIZE]          , CONF_UNIT_K   , conf_data[CNF_BUMPSIZE].v.int64);
+    conf_init_int      (&dpcur.value[DUMPTYPE_BUMPDAYS]          , CONF_UNIT_NONE, conf_data[CNF_BUMPDAYS].v.i);
     conf_init_real     (&dpcur.value[DUMPTYPE_BUMPMULT]          , conf_data[CNF_BUMPMULT].v.r);
     conf_init_time     (&dpcur.value[DUMPTYPE_STARTTIME]         , (time_t)0);
     conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY]          , DS_STANDARD);
@@ -2385,8 +2411,8 @@ init_dumptype_defaults(void)
     conf_init_str   (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT]   , "-d");
     conf_init_str   (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT]  , "-d");
     conf_init_rate     (&dpcur.value[DUMPTYPE_COMPRATE]          , 0.50, 0.50);
-    conf_init_int64    (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE]    , (gint64)0);
-    conf_init_int64    (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (gint64)10 * 1024);
+    conf_init_int64    (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE]    , CONF_UNIT_K, (gint64)0);
+    conf_init_int64    (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], CONF_UNIT_K, (gint64)10 * 1024);
     conf_init_str   (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER]  , NULL);
     conf_init_bool     (&dpcur.value[DUMPTYPE_RECORD]            , 1);
     conf_init_bool     (&dpcur.value[DUMPTYPE_SKIP_INCR]         , 0);
@@ -2399,6 +2425,7 @@ init_dumptype_defaults(void)
     conf_init_identlist(&dpcur.value[DUMPTYPE_SCRIPTLIST], NULL);
     conf_init_proplist(&dpcur.value[DUMPTYPE_PROPERTY]);
     conf_init_bool     (&dpcur.value[DUMPTYPE_ALLOW_SPLIT]       , 1);
+    conf_init_int      (&dpcur.value[DUMPTYPE_MAX_WARNINGS]      , CONF_UNIT_NONE, 20);
     conf_init_host_limit(&dpcur.value[DUMPTYPE_RECOVERY_LIMIT]);
     conf_init_host_limit_server(&dpcur.value[DUMPTYPE_DUMP_LIMIT]);
 }
@@ -2471,6 +2498,8 @@ get_tapetype(void)
 
     get_conftoken(CONF_IDENT);
     tpcur.name = stralloc(tokenval.v.s);
+    current_block = g_strconcat("tapetype ", tpcur.name, NULL);
+    tpcur.seen.block = current_block;
     tpcur.seen.filename = current_filename;
     tpcur.seen.linenum = current_line_num;
 
@@ -2481,7 +2510,7 @@ get_tapetype(void)
 
     if (tapetype_get_readblocksize(&tpcur) <
        tapetype_get_blocksize(&tpcur)) {
-       conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE],
+       conf_init_size(&tpcur.value[TAPETYPE_READBLOCKSIZE], CONF_UNIT_K,
                       tapetype_get_blocksize(&tpcur));
     }
     save_tapetype();
@@ -2494,15 +2523,15 @@ init_tapetype_defaults(void)
 {
     conf_init_str(&tpcur.value[TAPETYPE_COMMENT]      , "");
     conf_init_str(&tpcur.value[TAPETYPE_LBL_TEMPL]    , "");
-    conf_init_size  (&tpcur.value[TAPETYPE_BLOCKSIZE]    , DISK_BLOCK_KB);
-    conf_init_size  (&tpcur.value[TAPETYPE_READBLOCKSIZE], DISK_BLOCK_KB);
-    conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH]       , ((gint64)2000));
-    conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK]     , (gint64)1);
-    conf_init_int   (&tpcur.value[TAPETYPE_SPEED]        , 200);
-    conf_init_int64(&tpcur.value[TAPETYPE_PART_SIZE], 0);
+    conf_init_size  (&tpcur.value[TAPETYPE_BLOCKSIZE]    , CONF_UNIT_K, DISK_BLOCK_KB);
+    conf_init_size  (&tpcur.value[TAPETYPE_READBLOCKSIZE], CONF_UNIT_K, DISK_BLOCK_KB);
+    conf_init_int64 (&tpcur.value[TAPETYPE_LENGTH]       , CONF_UNIT_K, ((gint64)2000));
+    conf_init_int64 (&tpcur.value[TAPETYPE_FILEMARK]     , CONF_UNIT_K, (gint64)1);
+    conf_init_int   (&tpcur.value[TAPETYPE_SPEED]        , CONF_UNIT_NONE, 200);
+    conf_init_int64(&tpcur.value[TAPETYPE_PART_SIZE], CONF_UNIT_K, 0);
     conf_init_part_cache_type(&tpcur.value[TAPETYPE_PART_CACHE_TYPE], PART_CACHE_TYPE_NONE);
     conf_init_str(&tpcur.value[TAPETYPE_PART_CACHE_DIR], "");
-    conf_init_int64(&tpcur.value[TAPETYPE_PART_CACHE_MAX_SIZE], 0);
+    conf_init_int64(&tpcur.value[TAPETYPE_PART_CACHE_MAX_SIZE], CONF_UNIT_K, 0);
 }
 
 static void
@@ -2566,6 +2595,8 @@ get_interface(void)
 
     get_conftoken(CONF_IDENT);
     ifcur.name = stralloc(tokenval.v.s);
+    current_block = g_strconcat("interface ", ifcur.name, NULL);
+    ifcur.seen.block = current_block;
     ifcur.seen.filename = current_filename;
     ifcur.seen.linenum = current_line_num;
 
@@ -2585,7 +2616,7 @@ static void
 init_interface_defaults(void)
 {
     conf_init_str(&ifcur.value[INTER_COMMENT] , "");
-    conf_init_int   (&ifcur.value[INTER_MAXUSAGE], 80000);
+    conf_init_int   (&ifcur.value[INTER_MAXUSAGE], CONF_UNIT_K, 80000);
 }
 
 static void
@@ -2670,6 +2701,8 @@ read_application(
        get_conftoken(CONF_IDENT);
        apcur.name = stralloc(tokenval.v.s);
     }
+    current_block = g_strconcat("application ", apcur.name, NULL);
+    apcur.seen.block = current_block;
     apcur.seen.filename = current_filename;
     apcur.seen.linenum = current_line_num;
 
@@ -2797,6 +2830,8 @@ read_interactivity(
        get_conftoken(CONF_IDENT);
        ivcur.name = stralloc(tokenval.v.s);
     }
+    current_block = g_strconcat("interactivity ", ivcur.name, NULL);
+    ivcur.seen.block = current_block;
     ivcur.seen.filename = current_filename;
     ivcur.seen.linenum = current_line_num;
 
@@ -2923,6 +2958,8 @@ read_taperscan(
        get_conftoken(CONF_IDENT);
        tscur.name = stralloc(tokenval.v.s);
     }
+    current_block = g_strconcat("taperscan ", tscur.name, NULL);
+    tscur.seen.block = current_block;
     tscur.seen.filename = current_filename;
     tscur.seen.linenum = current_line_num;
 
@@ -3049,6 +3086,8 @@ read_pp_script(
        get_conftoken(CONF_IDENT);
        pscur.name = stralloc(tokenval.v.s);
     }
+    current_block = g_strconcat("script ", pscur.name, NULL);
+    pscur.seen.block = current_block;
     pscur.seen.filename = current_filename;
     pscur.seen.linenum = current_line_num;
 
@@ -3092,7 +3131,7 @@ init_pp_script_defaults(
     conf_init_proplist(&pscur.value[PP_SCRIPT_PROPERTY]);
     conf_init_execute_on(&pscur.value[PP_SCRIPT_EXECUTE_ON], 0);
     conf_init_execute_where(&pscur.value[PP_SCRIPT_EXECUTE_WHERE], ES_CLIENT);
-    conf_init_int(&pscur.value[PP_SCRIPT_ORDER], 5000);
+    conf_init_int(&pscur.value[PP_SCRIPT_ORDER], CONF_UNIT_NONE, 5000);
     conf_init_bool(&pscur.value[PP_SCRIPT_SINGLE_EXECUTION], 0);
     conf_init_str(&pscur.value[PP_SCRIPT_CLIENT_NAME], "");
 }
@@ -3180,6 +3219,8 @@ read_device_config(
        get_conftoken(CONF_IDENT);
        dccur.name = stralloc(tokenval.v.s);
     }
+    current_block = g_strconcat("device ", dccur.name, NULL);
+    dccur.seen.block = current_block;
     dccur.seen.filename = current_filename;
     dccur.seen.linenum = current_line_num;
 
@@ -3306,7 +3347,10 @@ read_changer_config(
        get_conftoken(CONF_IDENT);
        cccur.name = stralloc(tokenval.v.s);
     }
-    cccur.seen = current_line_num;
+    current_block = g_strconcat("changer ", cccur.name, NULL);
+    cccur.seen.block = current_block;
+    cccur.seen.filename = current_filename;
+    cccur.seen.linenum = current_line_num;
 
     read_block(changer_config_var, cccur.value,
               _("changer parameter expected"),
@@ -3361,8 +3405,8 @@ save_changer_config(
     dc = lookup_changer_config(cccur.name);
 
     if(dc != (changer_config_t *)0) {
-       conf_parserror(_("changer %s already defined on line %d"),
-                      dc->name, dc->seen);
+       conf_parserror(_("changer %s already defined at %s:%d"),
+                      dc->name, dc->seen.filename, dc->seen.linenum);
        return;
     }
 
@@ -3409,7 +3453,7 @@ read_int(
     val_t *val)
 {
     ckseen(&val->seen);
-    val_t__int(val) = get_int();
+    val_t__int(val) = get_int(val->unit);
 }
 
 static void
@@ -3418,7 +3462,7 @@ read_int64(
     val_t *val)
 {
     ckseen(&val->seen);
-    val_t__int64(val) = get_int64();
+    val_t__int64(val) = get_int64(val->unit);
 }
 
 static void
@@ -3466,16 +3510,7 @@ read_size(
     val_t *val)
 {
     ckseen(&val->seen);
-    val_t__size(val) = get_size();
-}
-
-static void
-read_size_byte(
-    conf_var_t *np G_GNUC_UNUSED,
-    val_t *val)
-{
-    ckseen(&val->seen);
-    val_t__size(val) = get_size_byte();
+    val_t__size(val) = get_size(val->unit);
 }
 
 static void
@@ -3808,7 +3843,7 @@ read_exinclude(
     val_t *val)
 {
     int file, got_one = 0;
-    sl_t *exclude;
+    am_sl_t *exclude;
     int optional = 0;
 
     get_conftoken(CONF_ANY);
@@ -3888,6 +3923,7 @@ read_property(
     val_t      *val)
 {
     char *key;
+    gboolean set_seen = TRUE;
     property_t *property = malloc(sizeof(property_t));
     property_t *old_property;
     property->append = 0; 
@@ -3921,8 +3957,7 @@ read_property(
     }
 
     if(val->seen.linenum == 0) {
-       val->seen.filename = current_filename;
-       val->seen.linenum = current_line_num;
+       ckseen(&val->seen); // first property
     }
 
     old_property = g_hash_table_lookup(val->v.proplist, key);
@@ -3934,6 +3969,7 @@ read_property(
                property->priority = 1;
            property->values = old_property->values;
            old_property->values = NULL;
+           set_seen = FALSE;
        }
     }
     while(tok == CONF_STRING) {
@@ -3943,6 +3979,12 @@ read_property(
     }
     unget_conftoken();
     g_hash_table_insert(val->v.proplist, key, property);
+    if (set_seen) {
+       property->seen.linenum = 0;
+       property->seen.filename = NULL;
+       property->seen.block = NULL;
+       ckseen(&property->seen);
+    }
 }
 
 
@@ -4324,7 +4366,8 @@ get_time(void)
 }
 
 static int
-get_int(void)
+get_int(
+    confunit_t unit)
 {
     int val;
     keytab_t *save_kt;
@@ -4369,153 +4412,15 @@ get_int(void)
     }
 
     /* get multiplier, if any */
-    get_conftoken(CONF_ANY);
-    switch(tok) {
-    case CONF_NL:                      /* multiply by one */
-    case CONF_END:
-    case CONF_MULT1:
-    case CONF_MULT1K:
-       break;
-
-    case CONF_MULT7:
-       if (val > (INT_MAX / 7))
-           conf_parserror(_("value too large"));
-       if (val < (INT_MIN / 7))
-           conf_parserror(_("value too small"));
-       val *= 7;
-       break;
-
-    case CONF_MULT1M:
-       if (val > (INT_MAX / 1024))
-           conf_parserror(_("value too large"));
-       if (val < (INT_MIN / 1024))
-           conf_parserror(_("value too small"));
-       val *= 1024;
-       break;
-
-    case CONF_MULT1G:
-       if (val > (INT_MAX / (1024 * 1024)))
-           conf_parserror(_("value too large"));
-       if (val < (INT_MIN / (1024 * 1024)))
-           conf_parserror(_("value too small"));
-       val *= 1024 * 1024;
-       break;
-
-    case CONF_MULT1T:
-       if (val > (INT_MAX / (1024 * 1024 * 1024)))
-           conf_parserror(_("value too large"));
-       if (val < (INT_MIN / (1024 * 1024 * 1024)))
-           conf_parserror(_("value too small"));
-       val *= 1024 * 1024 * 1024;
-       break;
-
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-       break;
-    }
-
-    keytable = save_kt;
-    return val;
-}
-
-static ssize_t
-get_size(void)
-{
-    ssize_t val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = numb_keytable;
-
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_SIZE:
-       val = tokenval.v.size;
-       break;
-
-    case CONF_INT:
-#if SIZEOF_SIZE_T < SIZEOF_INT
-       if ((gint64)tokenval.v.i > (gint64)SSIZE_MAX)
-           conf_parserror(_("value too large"));
-       if ((gint64)tokenval.v.i < (gint64)SSIZE_MIN)
-           conf_parserror(_("value too small"));
-#endif
-       val = (ssize_t)tokenval.v.i;
-       break;
-
-    case CONF_INT64:
-#if SIZEOF_SIZE_T < SIZEOF_GINT64
-       if (tokenval.v.int64 > (gint64)SSIZE_MAX)
-           conf_parserror(_("value too large"));
-       if (tokenval.v.int64 < (gint64)SSIZE_MIN)
-           conf_parserror(_("value too small"));
-#endif
-       val = (ssize_t)tokenval.v.int64;
-       break;
-
-    case CONF_AMINFINITY:
-       val = (ssize_t)SSIZE_MAX;
-       break;
-
-    default:
-       conf_parserror(_("an integer is expected"));
-       val = 0;
-       break;
-    }
-
-    /* get multiplier, if any */
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_NL:                      /* multiply by one */
-    case CONF_MULT1:
-    case CONF_MULT1K:
-       break;
-
-    case CONF_MULT7:
-       if (val > (ssize_t)(SSIZE_MAX / 7))
-           conf_parserror(_("value too large"));
-       if (val < (ssize_t)(SSIZE_MIN / 7))
-           conf_parserror(_("value too small"));
-       val *= (ssize_t)7;
-       break;
-
-    case CONF_MULT1M:
-       if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
-           conf_parserror(_("value too large"));
-       if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
-           conf_parserror(_("value too small"));
-       val *= (ssize_t)1024;
-       break;
-
-    case CONF_MULT1G:
-       if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024)))
-           conf_parserror(_("value too large"));
-       if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024)))
-           conf_parserror(_("value too small"));
-       val *= (ssize_t)(1024 * 1024);
-       break;
-
-    case CONF_MULT1T:
-       if (val > (INT_MAX / (1024 * 1024 * 1024)))
-           conf_parserror(_("value too large"));
-       if (val < (INT_MIN / (1024 * 1024 * 1024)))
-           conf_parserror(_("value too small"));
-       val *= 1024 * 1024 * 1024;
-       break;
-
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-       break;
-    }
+    val = get_multiplier(val, unit);
 
     keytable = save_kt;
     return val;
 }
 
 static ssize_t
-get_size_byte(void)
+get_size(
+    confunit_t unit)
 {
     ssize_t val;
     keytab_t *save_kt;
@@ -4561,58 +4466,15 @@ get_size_byte(void)
     }
 
     /* get multiplier, if any */
-    get_conftoken(CONF_ANY);
-
-    switch(tok) {
-    case CONF_NL:                      /* multiply by one */
-    case CONF_MULT1:
-       break;
-    case CONF_MULT1K:
-       if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
-           conf_parserror(_("value too large"));
-       if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
-           conf_parserror(_("value too small"));
-       val *= (ssize_t)1024;
-
-    case CONF_MULT7:
-       if (val > (ssize_t)(SSIZE_MAX / 7))
-           conf_parserror(_("value too large"));
-       if (val < (ssize_t)(SSIZE_MIN / 7))
-           conf_parserror(_("value too small"));
-       val *= (ssize_t)7;
-       break;
-
-    case CONF_MULT1M:
-       if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024 * 1024))
-           conf_parserror(_("value too large"));
-       if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024 * 1024))
-           conf_parserror(_("value too small"));
-       val *= (ssize_t)(1024 * 1024);
-       break;
-
-    case CONF_MULT1G:
-       if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024 * 1024)))
-           conf_parserror(_("value too large"));
-       if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024 * 1024)))
-           conf_parserror(_("value too small"));
-       val *= (ssize_t)(1024 * 1024 * 1024);
-       break;
-
-    case CONF_MULT1T:
-       conf_parserror(_("value too large"));
-       break;
-
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-       break;
-    }
+    val = get_multiplier(val, unit);
 
     keytable = save_kt;
     return val;
 }
 
 static gint64
-get_int64(void)
+get_int64(
+    confunit_t unit)
 {
     gint64 val;
     keytab_t *save_kt;
@@ -4646,45 +4508,54 @@ get_int64(void)
     }
 
     /* get multiplier, if any */
-    get_conftoken(CONF_ANY);
+    val = get_multiplier(val, unit);
 
-    switch(tok) {
-    case CONF_NL:                      /* multiply by one */
-    case CONF_MULT1:
-    case CONF_MULT1K:
-       break;
+    keytable = save_kt;
+
+    return val;
+}
 
-    case CONF_MULT7:
+gint64
+get_multiplier(
+    gint64 val,
+    confunit_t unit)
+{
+    /* get multiplier, if any */
+    get_conftoken(CONF_ANY);
+
+    if (tok == CONF_MULT1 && unit == CONF_UNIT_K) {
+       val /= 1024;
+    } else if (tok == CONF_NL || tok == CONF_MULT1 ||
+       (tok == CONF_MULT1K && unit == CONF_UNIT_K)) {
+       val *= 1;       /* multiply by one */
+    } else if (tok == CONF_MULT7) {
        if (val > G_MAXINT64/7 || val < ((gint64)G_MININT64)/7)
            conf_parserror(_("value too large"));
        val *= 7;
-       break;
-
-    case CONF_MULT1M:
+    } else if (tok == CONF_MULT1K ||
+              (tok == CONF_MULT1M && unit == CONF_UNIT_K)) {
        if (val > G_MAXINT64/1024 || val < ((gint64)G_MININT64)/1024)
            conf_parserror(_("value too large"));
        val *= 1024;
-       break;
-
-    case CONF_MULT1G:
+    } else if (tok == CONF_MULT1M ||
+              (tok == CONF_MULT1G && unit == CONF_UNIT_K)) {
        if (val > G_MAXINT64/(1024*1024) || val < ((gint64)G_MININT64)/(1024*1024))
            conf_parserror(_("value too large"));
        val *= 1024*1024;
-       break;
-
-    case CONF_MULT1T:
+    } else if (tok == CONF_MULT1G ||
+              (tok == CONF_MULT1T && unit == CONF_UNIT_K)) {
        if (val > G_MAXINT64/(1024*1024*1024) || val < ((gint64)G_MININT64)/(1024*1024*1024))
            conf_parserror(_("value too large"));
        val *= 1024*1024*1024;
-       break;
-
-    default:   /* it was not a multiplier */
+    } else if (tok == CONF_MULT1T) {
+       if (val > G_MAXINT64/(1024*1024*1024*1024LL) || val < ((gint64)G_MININT64)/(1024*1024*1024*1024LL))
+           conf_parserror(_("value too large"));
+       val *= 1024*1024*1024*1024LL;
+    } else {
+       val *= 1;
        unget_conftoken();
-       break;
     }
 
-    keytable = save_kt;
-
     return val;
 }
 
@@ -4805,6 +4676,7 @@ ckseen(
        conf_parserror(_("duplicate parameter; previous definition %s:%d"),
                seen->filename, seen->linenum);
     }
+    seen->block = current_block;
     seen->filename = current_filename;
     seen->linenum = current_line_num;
 }
@@ -5047,6 +4919,31 @@ validate_unreserved_port_range(
     validate_port_range(val, IPPORT_RESERVED, 65535);
 }
 
+/*
+ * Validate tmpdir, the directory must exist and be writable by the user.
+ */
+
+static void validate_tmpdir(conf_var_t *var G_GNUC_UNUSED, val_t *value)
+{
+    struct stat stat_buf;
+    gchar *tmpdir = val_t_to_str(value);
+
+    if (stat(tmpdir, &stat_buf)) {
+       conf_parserror(_("invalid TMPDIR: directory '%s': %s."),
+                     tmpdir, strerror(errno));
+    } else if (!S_ISDIR(stat_buf.st_mode)) {
+       conf_parserror(_("invalid TMPDIR: '%s' is not a directory."),
+                     tmpdir);
+    } else {
+       gchar *dir = g_strconcat(tmpdir, "/.", NULL);
+       if (access(dir, R_OK|W_OK) == -1) {
+           conf_parserror(_("invalid TMPDIR: '%s': can not read/write: %s."),
+                          tmpdir, strerror(errno));
+       }
+       g_free(dir);
+    }
+}
+
 /*
  * Initialization Implementation
  */
@@ -5335,65 +5232,66 @@ init_defaults(
     conf_init_str   (&conf_data[CNF_INDEXDIR]             , "/usr/adm/amanda/index");
     conf_init_ident    (&conf_data[CNF_TAPETYPE]             , "DEFAULT_TAPE");
     conf_init_identlist(&conf_data[CNF_HOLDINGDISK]          , NULL);
-    conf_init_int      (&conf_data[CNF_DUMPCYCLE]            , 10);
-    conf_init_int      (&conf_data[CNF_RUNSPERCYCLE]         , 0);
-    conf_init_int      (&conf_data[CNF_TAPECYCLE]            , 15);
-    conf_init_int      (&conf_data[CNF_NETUSAGE]             , 80000);
-    conf_init_int      (&conf_data[CNF_INPARALLEL]           , 10);
+    conf_init_int      (&conf_data[CNF_DUMPCYCLE]            , CONF_UNIT_NONE, 10);
+    conf_init_int      (&conf_data[CNF_RUNSPERCYCLE]         , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_TAPECYCLE]            , CONF_UNIT_NONE, 15);
+    conf_init_int      (&conf_data[CNF_NETUSAGE]             , CONF_UNIT_K   , 80000);
+    conf_init_int      (&conf_data[CNF_INPARALLEL]           , CONF_UNIT_NONE, 10);
     conf_init_str   (&conf_data[CNF_DUMPORDER]            , "ttt");
-    conf_init_int      (&conf_data[CNF_BUMPPERCENT]          , 0);
-    conf_init_int64    (&conf_data[CNF_BUMPSIZE]             , (gint64)10*1024);
+    conf_init_int      (&conf_data[CNF_BUMPPERCENT]          , CONF_UNIT_NONE, 0);
+    conf_init_int64    (&conf_data[CNF_BUMPSIZE]             , CONF_UNIT_K   , (gint64)10*1024);
     conf_init_real     (&conf_data[CNF_BUMPMULT]             , 1.5);
-    conf_init_int      (&conf_data[CNF_BUMPDAYS]             , 2);
+    conf_init_int      (&conf_data[CNF_BUMPDAYS]             , CONF_UNIT_NONE, 2);
     conf_init_str   (&conf_data[CNF_TPCHANGER]            , "");
-    conf_init_int      (&conf_data[CNF_RUNTAPES]             , 1);
-    conf_init_int      (&conf_data[CNF_MAXDUMPS]             , 1);
-    conf_init_int      (&conf_data[CNF_MAX_DLE_BY_VOLUME]    , 1000000000);
-    conf_init_int      (&conf_data[CNF_ETIMEOUT]             , 300);
-    conf_init_int      (&conf_data[CNF_DTIMEOUT]             , 1800);
-    conf_init_int      (&conf_data[CNF_CTIMEOUT]             , 30);
-    conf_init_size     (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], 40*32768);
+    conf_init_int      (&conf_data[CNF_RUNTAPES]             , CONF_UNIT_NONE, 1);
+    conf_init_int      (&conf_data[CNF_MAXDUMPS]             , CONF_UNIT_NONE, 1);
+    conf_init_int      (&conf_data[CNF_MAX_DLE_BY_VOLUME]    , CONF_UNIT_NONE, 1000000000);
+    conf_init_int      (&conf_data[CNF_ETIMEOUT]             , CONF_UNIT_NONE, 300);
+    conf_init_int      (&conf_data[CNF_DTIMEOUT]             , CONF_UNIT_NONE, 1800);
+    conf_init_int      (&conf_data[CNF_CTIMEOUT]             , CONF_UNIT_NONE, 30);
+    conf_init_size     (&conf_data[CNF_DEVICE_OUTPUT_BUFFER_SIZE], CONF_UNIT_NONE, 40*32768);
     conf_init_str   (&conf_data[CNF_PRINTER]              , "");
     conf_init_str   (&conf_data[CNF_MAILER]               , DEFAULT_MAILER);
     conf_init_no_yes_all(&conf_data[CNF_AUTOFLUSH]            , 0);
-    conf_init_int      (&conf_data[CNF_RESERVE]              , 100);
-    conf_init_int64    (&conf_data[CNF_MAXDUMPSIZE]          , (gint64)-1);
+    conf_init_int      (&conf_data[CNF_RESERVE]              , CONF_UNIT_NONE, 100);
+    conf_init_int64    (&conf_data[CNF_MAXDUMPSIZE]          , CONF_UNIT_K   , (gint64)-1);
     conf_init_str   (&conf_data[CNF_COLUMNSPEC]           , "");
     conf_init_bool     (&conf_data[CNF_AMRECOVER_DO_FSF]     , 1);
     conf_init_str   (&conf_data[CNF_AMRECOVER_CHANGER]    , "");
     conf_init_bool     (&conf_data[CNF_AMRECOVER_CHECK_LABEL], 1);
     conf_init_taperalgo(&conf_data[CNF_TAPERALGO]            , 0);
-    conf_init_int      (&conf_data[CNF_TAPER_PARALLEL_WRITE]     , 1);
-    conf_init_int      (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED]   , 0);
-    conf_init_int      (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], 0);
-    conf_init_int      (&conf_data[CNF_TAPERFLUSH]               , 0);
+    conf_init_int      (&conf_data[CNF_TAPER_PARALLEL_WRITE]     , CONF_UNIT_NONE, 1);
+    conf_init_int      (&conf_data[CNF_FLUSH_THRESHOLD_DUMPED]   , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_FLUSH_THRESHOLD_SCHEDULED], CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_TAPERFLUSH]               , CONF_UNIT_NONE, 0);
     conf_init_str   (&conf_data[CNF_DISPLAYUNIT]          , "k");
     conf_init_str   (&conf_data[CNF_KRB5KEYTAB]           , "/.amanda-v5-keytab");
     conf_init_str   (&conf_data[CNF_KRB5PRINCIPAL]        , "service/amanda");
     conf_init_str   (&conf_data[CNF_LABEL_NEW_TAPES]      , "");
     conf_init_bool     (&conf_data[CNF_EJECT_VOLUME]         , 0);
+    conf_init_str      (&conf_data[CNF_TMPDIR]               , "");
     conf_init_bool     (&conf_data[CNF_USETIMESTAMPS]        , 1);
-    conf_init_int      (&conf_data[CNF_CONNECT_TRIES]        , 3);
-    conf_init_int      (&conf_data[CNF_REP_TRIES]            , 5);
-    conf_init_int      (&conf_data[CNF_REQ_TRIES]            , 3);
-    conf_init_int      (&conf_data[CNF_DEBUG_DAYS]           , AMANDA_DEBUG_DAYS);
-    conf_init_int      (&conf_data[CNF_DEBUG_AMANDAD]        , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_RECOVERY]       , 1);
-    conf_init_int      (&conf_data[CNF_DEBUG_AMIDXTAPED]     , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_AMINDEXD]       , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_AMRECOVER]      , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_AUTH]           , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_EVENT]          , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_HOLDING]        , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_PROTOCOL]       , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_PLANNER]        , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_DRIVER]         , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_DUMPER]         , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_CHUNKER]        , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_TAPER]          , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_SELFCHECK]      , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_SENDSIZE]       , 0);
-    conf_init_int      (&conf_data[CNF_DEBUG_SENDBACKUP]     , 0);
+    conf_init_int      (&conf_data[CNF_CONNECT_TRIES]        , CONF_UNIT_NONE, 3);
+    conf_init_int      (&conf_data[CNF_REP_TRIES]            , CONF_UNIT_NONE, 5);
+    conf_init_int      (&conf_data[CNF_REQ_TRIES]            , CONF_UNIT_NONE, 3);
+    conf_init_int      (&conf_data[CNF_DEBUG_DAYS]           , CONF_UNIT_NONE, AMANDA_DEBUG_DAYS);
+    conf_init_int      (&conf_data[CNF_DEBUG_AMANDAD]        , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_RECOVERY]       , CONF_UNIT_NONE, 1);
+    conf_init_int      (&conf_data[CNF_DEBUG_AMIDXTAPED]     , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_AMINDEXD]       , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_AMRECOVER]      , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_AUTH]           , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_EVENT]          , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_HOLDING]        , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_PROTOCOL]       , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_PLANNER]        , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_DRIVER]         , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_DUMPER]         , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_CHUNKER]        , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_TAPER]          , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_SELFCHECK]      , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_SENDSIZE]       , CONF_UNIT_NONE, 0);
+    conf_init_int      (&conf_data[CNF_DEBUG_SENDBACKUP]     , CONF_UNIT_NONE, 0);
 #ifdef UDPPORTRANGE
     conf_init_intrange (&conf_data[CNF_RESERVED_UDP_PORT]    , UDPPORTRANGE);
 #else
@@ -5666,22 +5564,28 @@ update_derived_values(
 static void
 conf_init_int(
     val_t *val,
+    confunit_t unit,
     int    i)
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_INT;
+    val->unit = unit;
     val_t__int(val) = i;
 }
 
 static void
 conf_init_int64(
     val_t *val,
+    confunit_t unit,
     gint64   l)
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_INT64;
+    val->unit = unit;
     val_t__int64(val) = l;
 }
 
@@ -5692,7 +5596,9 @@ conf_init_real(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_REAL;
+    val->unit = CONF_UNIT_NONE;
     val_t__real(val) = r;
 }
 
@@ -5703,7 +5609,9 @@ conf_init_str(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_STR;
+    val->unit = CONF_UNIT_NONE;
     if(s)
        val->v.s = stralloc(s);
     else
@@ -5717,7 +5625,9 @@ conf_init_ident(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_IDENT;
+    val->unit = CONF_UNIT_NONE;
     if(s)
        val->v.s = stralloc(s);
     else
@@ -5731,7 +5641,9 @@ conf_init_identlist(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_IDENTLIST;
+    val->unit = CONF_UNIT_NONE;
     val->v.identlist = NULL;
     if (s)
        val->v.identlist = g_slist_append(val->v.identlist, stralloc(s));
@@ -5744,18 +5656,23 @@ conf_init_time(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_TIME;
+    val->unit = CONF_UNIT_NONE;
     val_t__time(val) = t;
 }
 
 static void
 conf_init_size(
     val_t *val,
+    confunit_t unit,
     ssize_t   sz)
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_SIZE;
+    val->unit = unit;
     val_t__size(val) = sz;
 }
 
@@ -5766,7 +5683,9 @@ conf_init_bool(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_BOOLEAN;
+    val->unit = CONF_UNIT_NONE;
     val_t__boolean(val) = i;
 }
 
@@ -5777,7 +5696,9 @@ conf_init_no_yes_all(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_NO_YES_ALL;
+    val->unit = CONF_UNIT_NONE;
     val_t__int(val) = i;
 }
 
@@ -5788,7 +5709,9 @@ conf_init_compress(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_COMPRESS;
+    val->unit = CONF_UNIT_NONE;
     val_t__compress(val) = (int)i;
 }
 
@@ -5799,7 +5722,9 @@ conf_init_encrypt(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_ENCRYPT;
+    val->unit = CONF_UNIT_NONE;
     val_t__encrypt(val) = (int)i;
 }
 
@@ -5810,7 +5735,9 @@ conf_init_part_cache_type(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_PART_CACHE_TYPE;
+    val->unit = CONF_UNIT_NONE;
     val_t__part_cache_type(val) = (int)i;
 }
 
@@ -5820,7 +5747,9 @@ conf_init_host_limit(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_HOST_LIMIT;
+    val->unit = CONF_UNIT_NONE;
     val_t__host_limit(val).match_pats = NULL;
     val_t__host_limit(val).same_host  = FALSE;
     val_t__host_limit(val).server     = FALSE;
@@ -5841,7 +5770,9 @@ conf_init_data_path(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_DATA_PATH;
+    val->unit = CONF_UNIT_NONE;
     val_t__data_path(val) = (int)i;
 }
 
@@ -5852,7 +5783,9 @@ conf_init_holding(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_HOLDING;
+    val->unit = CONF_UNIT_NONE;
     val_t__holding(val) = (int)i;
 }
 
@@ -5864,7 +5797,9 @@ conf_init_estimatelist(
     GSList *estimates = NULL;
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_ESTIMATELIST;
+    val->unit = CONF_UNIT_NONE;
     estimates = g_slist_append(estimates, GINT_TO_POINTER(i));
     val_t__estimatelist(val) = estimates;
 }
@@ -5876,6 +5811,8 @@ conf_init_strategy(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
+    val->unit = CONF_UNIT_NONE;
     val->type = CONFTYPE_STRATEGY;
     val_t__strategy(val) = i;
 }
@@ -5887,7 +5824,9 @@ conf_init_taperalgo(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_TAPERALGO;
+    val->unit = CONF_UNIT_NONE;
     val_t__taperalgo(val) = i;
 }
 
@@ -5898,7 +5837,9 @@ conf_init_priority(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_PRIORITY;
+    val->unit = CONF_UNIT_NONE;
     val_t__priority(val) = i;
 }
 
@@ -5910,7 +5851,9 @@ conf_init_rate(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_RATE;
+    val->unit = CONF_UNIT_NONE;
     val_t__rate(val)[0] = r1;
     val_t__rate(val)[1] = r2;
 }
@@ -5921,7 +5864,9 @@ conf_init_exinclude(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_EXINCLUDE;
+    val->unit = CONF_UNIT_NONE;
     val_t__exinclude(val).optional = 0;
     val_t__exinclude(val).sl_list = NULL;
     val_t__exinclude(val).sl_file = NULL;
@@ -5935,7 +5880,9 @@ conf_init_intrange(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_INTRANGE;
+    val->unit = CONF_UNIT_NONE;
     val_t__intrange(val)[0] = i1;
     val_t__intrange(val)[1] = i2;
 }
@@ -5945,7 +5892,9 @@ conf_init_autolabel(
     val_t *val) {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_AUTOLABEL;
+    val->unit = CONF_UNIT_NONE;
     val->v.autolabel.template = NULL;
     val->v.autolabel.autolabel = 0;
 }
@@ -5965,7 +5914,9 @@ conf_init_proplist(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_PROPLIST;
+    val->unit = CONF_UNIT_NONE;
     val_t__proplist(val) =
         g_hash_table_new_full(g_str_amanda_hash, g_str_amanda_equal,
                              &g_free, &free_property_t);
@@ -5978,7 +5929,9 @@ conf_init_execute_on(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_EXECUTE_ON;
+    val->unit = CONF_UNIT_NONE;
     val->v.i = i;
 }
 
@@ -5989,7 +5942,9 @@ conf_init_execute_where(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_EXECUTE_WHERE;
+    val->unit = CONF_UNIT_NONE;
     val->v.i = i;
 }
 
@@ -6000,14 +5955,18 @@ conf_init_send_amreport(
 {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_SEND_AMREPORT_ON;
+    val->unit = CONF_UNIT_NONE;
     val->v.i = i;
 }
 
 static void conf_init_application(val_t *val) {
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
     val->type = CONFTYPE_APPLICATION;
+    val->unit = CONF_UNIT_NONE;
     val->v.s = NULL;
 }
 
@@ -6939,6 +6898,12 @@ merge_val_t(
 {
     if (valsrc->type == CONFTYPE_PROPLIST) {
        if (valsrc->v.proplist) {
+           if (valdst->v.proplist == NULL ||
+               g_hash_table_size(valdst->v.proplist) == 0) {
+               valdst->seen.block = current_block;
+               valdst->seen.filename = current_filename;
+               valdst->seen.linenum = current_line_num;
+           }
            if (valdst->v.proplist == NULL) {
                valdst->v.proplist = g_hash_table_new_full(g_str_amanda_hash,
                                                           g_str_amanda_equal,
@@ -7105,6 +7070,7 @@ merge_proplist_foreach_fn(
     }
     if (!new_property) {
         new_property = malloc(sizeof(property_t));
+       new_property->seen = property->seen;
        new_property->append = property->append;
        new_property->priority = property->priority;
        new_property->values = NULL;
@@ -7132,6 +7098,7 @@ copy_proplist_foreach_fn(
     property_t *new_property = malloc(sizeof(property_t));
     new_property->append = property->append;
     new_property->priority = property->priority;
+    new_property->seen = property->seen;
     new_property->values = NULL;
 
     for(elem = property->values;elem != NULL; elem=elem->next) {
@@ -7203,6 +7170,7 @@ free_val_t(
     }
     val->seen.linenum = 0;
     val->seen.filename = NULL;
+    val->seen.block = NULL;
 }
 
 /*
@@ -7269,7 +7237,9 @@ generic_client_get_security_conf(
 }
 
 void
-dump_configuration(void)
+dump_configuration(
+    gboolean print_default,
+    gboolean print_source)
 {
     tapetype_t *tp;
     dumptype_t *dp;
@@ -7301,7 +7271,7 @@ dump_configuration(void)
        if(kt->token == CONF_UNKNOWN)
            error(_("server bad token"));
 
-        val_t_print_token(stdout, NULL, "%-21s ", kt, &conf_data[np->parm]);
+        val_t_print_token(print_default, print_source, stdout, NULL, "%-21s ", kt, &conf_data[np->parm]);
     }
 
     for(hp = holdinglist; hp != NULL; hp = hp->next) {
@@ -7322,7 +7292,7 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("holding bad token"));
 
-            val_t_print_token(stdout, NULL, "      %-9s ", kt, &hd->value[i]);
+            val_t_print_token(print_default, print_source, stdout, NULL, "      %-9s ", kt, &hd->value[i]);
        }
        g_printf("}\n");
     }
@@ -7344,7 +7314,7 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("tapetype bad token"));
 
-            val_t_print_token(stdout, prefix, "      %-9s ", kt, &tp->value[i]);
+            val_t_print_token(print_default, print_source, stdout, prefix, "      %-9s ", kt, &tp->value[i]);
        }
        g_printf("%s}\n", prefix);
     }
@@ -7367,7 +7337,7 @@ dump_configuration(void)
                if(kt->token == CONF_UNKNOWN)
                    error(_("dumptype bad token"));
 
-               val_t_print_token(stdout, prefix, "      %-19s ", kt, &dp->value[i]);
+               val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &dp->value[i]);
            }
            g_printf("%s}\n", prefix);
        }
@@ -7393,7 +7363,7 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("interface bad token"));
 
-           val_t_print_token(stdout, prefix, "      %-19s ", kt, &ip->value[i]);
+           val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &ip->value[i]);
        }
        g_printf("%s}\n",prefix);
     }
@@ -7415,7 +7385,7 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("application bad token"));
 
-           val_t_print_token(stdout, prefix, "      %-19s ", kt, &ap->value[i]);
+           val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &ap->value[i]);
        }
        g_printf("%s}\n",prefix);
     }
@@ -7437,7 +7407,7 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("script bad token"));
 
-           val_t_print_token(stdout, prefix, "      %-19s ", kt, &ps->value[i]);
+           val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &ps->value[i]);
        }
        g_printf("%s}\n",prefix);
     }
@@ -7456,7 +7426,7 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("device bad token"));
 
-           val_t_print_token(stdout, prefix, "      %-19s ", kt, &dc->value[i]);
+           val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &dc->value[i]);
        }
        g_printf("%s}\n",prefix);
     }
@@ -7475,7 +7445,7 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("changer bad token"));
 
-           val_t_print_token(stdout, prefix, "      %-19s ", kt, &cc->value[i]);
+           val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &cc->value[i]);
        }
        g_printf("%s}\n",prefix);
     }
@@ -7494,7 +7464,7 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("interactivity bad token"));
 
-           val_t_print_token(stdout, prefix, "      %-19s ", kt, &iv->value[i]);
+           val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &iv->value[i]);
        }
        g_printf("%s}\n",prefix);
     }
@@ -7513,14 +7483,41 @@ dump_configuration(void)
            if(kt->token == CONF_UNKNOWN)
                error(_("taperscan bad token"));
 
-           val_t_print_token(stdout, prefix, "      %-19s ", kt, &ts->value[i]);
+           val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &ts->value[i]);
        }
        g_printf("%s}\n",prefix);
     }
 }
 
+void dump_dumptype(
+    dumptype_t *dp,
+    char       *prefix,
+    gboolean    print_default,
+    gboolean    print_source)
+{
+    int i;
+    conf_var_t *np;
+    keytab_t *kt;
+
+    for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
+       for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
+           if(np->parm == i) break;
+       if(np->token == CONF_UNKNOWN)
+           error(_("dumptype bad value"));
+
+       for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+           if(kt->token == np->token) break;
+       if(kt->token == CONF_UNKNOWN)
+           error(_("dumptype bad token"));
+
+       val_t_print_token(print_default, print_source, stdout, prefix, "      %-19s ", kt, &dp->value[i]);
+    }
+}
+
 static void
 val_t_print_token(
+    gboolean  print_default,
+    gboolean  print_source,
     FILE     *output,
     char     *prefix,
     char     *format,
@@ -7528,7 +7525,12 @@ val_t_print_token(
     val_t    *val)
 {
     char       **dispstrs, **dispstr;
-    dispstrs = val_t_display_strs(val, 1);
+
+    if (print_default == 0 && !val_t_seen(val)) {
+       return;
+    }
+
+    dispstrs = val_t_display_strs(val, 1, print_source, TRUE);
 
     /* For most configuration types, this outputs
      *   PREFIX KEYWORD DISPSTR
@@ -7555,11 +7557,40 @@ val_t_print_token(
     g_strfreev(dispstrs);
 }
 
+typedef struct proplist_display_str_foreach_user_data {
+    char     **msg;
+    gboolean   print_source;
+} proplist_display_str_foreach_user_data;
+
+char *source_string(seen_t *seen);
+char *source_string(
+    seen_t *seen)
+{
+    char *buf;
+
+    if (seen->linenum) {
+       if (seen->block) {
+           buf = g_strdup_printf("     (%s file %s line %d)",
+                       seen->block, seen->filename, seen->linenum);
+       } else {
+           buf = g_strdup_printf("     (file %s line %d)",
+                       seen->filename, seen->linenum);
+       }
+    } else {
+       buf = g_strdup("     (default)");
+    }
+    return buf;
+}
+
 char **
 val_t_display_strs(
     val_t *val,
-    int    str_need_quote)
+    int    str_need_quote,
+    gboolean print_source,
+    gboolean print_unit)
 {
+    gboolean add_source = TRUE;
+    int    i;
     char **buf;
     buf = malloc(3*SIZEOF(char *));
     buf[0] = NULL;
@@ -7568,15 +7599,33 @@ val_t_display_strs(
 
     switch(val->type) {
     case CONFTYPE_INT:
-       buf[0] = vstrallocf("%d", val_t__int(val));
+       buf[0] = vstrallocf("%d ", val_t__int(val));
+       i = strlen(buf[0]) - 1;
+       if (print_unit && val->unit == CONF_UNIT_K) {
+           buf[0][i] = 'K';
+       } else {
+           buf[0][i] = '\0';
+       }
        break;
 
     case CONFTYPE_SIZE:
-       buf[0] = vstrallocf("%zd", (ssize_t)val_t__size(val));
+       buf[0] = vstrallocf("%zd ", (ssize_t)val_t__size(val));
+       i = strlen(buf[0]) - 1;
+       if (print_unit && val->unit == CONF_UNIT_K) {
+           buf[0][i] = 'K';
+       } else {
+           buf[0][i] = '\0';
+       }
        break;
 
     case CONFTYPE_INT64:
-       buf[0] = vstrallocf("%lld", (long long)val_t__int64(val));
+       buf[0] = vstrallocf("%lld ", (long long)val_t__int64(val));
+       i = strlen(buf[0]) - 1;
+       if (print_unit && val->unit == CONF_UNIT_K) {
+           buf[0][i] = 'K';
+       } else {
+           buf[0][i] = '\0';
+       }
        break;
 
     case CONFTYPE_REAL:
@@ -7892,16 +7941,18 @@ val_t_display_strs(
 
     case CONFTYPE_PROPLIST: {
        int    nb_property;
-       char **mybuf;
+       proplist_display_str_foreach_user_data user_data;
 
        nb_property = g_hash_table_size(val_t__proplist(val));
-       amfree(buf);
+       g_free(buf);
        buf = malloc((nb_property+1)*SIZEOF(char*));
        buf[nb_property] = NULL;
-       mybuf = buf;
+       user_data.msg = buf;
+       user_data.print_source = print_source;
        g_hash_table_foreach(val_t__proplist(val),
                             proplist_display_str_foreach_fn,
-                            &mybuf);
+                            &user_data);
+       add_source = FALSE;
         break;
     }
 
@@ -8014,6 +8065,16 @@ val_t_display_strs(
         break;
 
     }
+
+    /* add source */
+    if (print_source && add_source) {
+       char **buf1;
+       for (buf1 = buf; *buf1 != NULL; buf1++) {
+           char *buf2 = g_strjoin("", *buf1, source_string(&val->seen), NULL);
+           g_free(*buf1);
+           *buf1 = buf2;
+       }
+    }
     return buf;
 }
 
@@ -8060,7 +8121,8 @@ proplist_display_str_foreach_fn(
     char         *property_s = quote_string_always(key_p);
     property_t   *property   = value_p;
     GSList       *value;
-    char       ***msg        = (char ***)user_data_p;
+    proplist_display_str_foreach_user_data *user_data = user_data_p;
+    char       ***msg        = (char ***)&user_data->msg;
 
     /* What to do with property->append? it should be printed only on client */
     if (property->priority) {
@@ -8075,6 +8137,9 @@ proplist_display_str_foreach_fn(
        **msg = vstrextend(*msg, " ", qstr, NULL);
        amfree(qstr);
     }
+    if (user_data->print_source) {
+       **msg = vstrextend(*msg, source_string(&property->seen));
+    }
     (*msg)++;
 }
 
@@ -8083,7 +8148,7 @@ exinclude_display_str(
     val_t *val,
     int    file)
 {
-    sl_t  *sl;
+    am_sl_t  *sl;
     sle_t *excl;
     char *rval;
 
@@ -8163,6 +8228,8 @@ parm_key_info(
     pp_script_t   *pp;
     device_config_t   *dc;
     changer_config_t   *cc;
+    taperscan_t        *ts;
+    interactivity_t    *iv;
     int success = FALSE;
 
     /* WARNING: assumes globals keytable and parsetable are set correctly. */
@@ -8190,7 +8257,7 @@ parm_key_info(
            if (*s == '-') *s = '_';
        }
 
-       subsec_key = strchr(subsec_name,':');
+       subsec_key = strrchr(subsec_name,':');
        if(!subsec_key) goto out; /* failure */
 
        *subsec_key = '\0';
@@ -8311,6 +8378,30 @@ parm_key_info(
            if (val) *val = &cc->value[np->parm];
            if (parm) *parm = np;
            success = TRUE;
+       } else if (g_str_equal(subsec_type, "INTERACTIVITY")) {
+           iv = lookup_interactivity(subsec_name);
+           if (!iv) goto out;
+           for(np = interactivity_var; np->token != CONF_UNKNOWN; np++) {
+               if(np->token == kt->token)
+                  break;
+           }
+           if (np->token == CONF_UNKNOWN) goto out;
+
+           if (val) *val = &iv->value[np->parm];
+           if (parm) *parm = np;
+           success = TRUE;
+       } else if (g_str_equal(subsec_type, "TAPERSCAN")) {
+           ts = lookup_taperscan(subsec_name);
+           if (!ts) goto out;
+           for(np = taperscan_var; np->token != CONF_UNKNOWN; np++) {
+               if(np->token == kt->token)
+                  break;
+           }
+           if (np->token == CONF_UNKNOWN) goto out;
+
+           if (val) *val = &ts->value[np->parm];
+           if (parm) *parm = np;
+           success = TRUE;
        }
 
     /* No delimiters -- we're referencing a global config parameter */
index 2c867cc3325bbd7667dca11914b76ae5adfaf73d..a9a65046cae7aa988d3b6efc2f2dabe049b786ef 100644 (file)
  * this works and it's here.
  */
 
+/* A "seen" struct.  Rather than allocate strings all over the place, this
+ * string is in the "parsed_filenames" GSList and will be freed when that
+ * GSList is freed.  This struct should be opaque to other modules. */
+typedef struct seen_s {
+    char *block;
+    char *filename;
+    int linenum;
+} seen_t;
+
 /* holdingdisk types */
 typedef enum {
     HOLD_NEVER,                 /* Always direct to tape  */
@@ -195,8 +204,8 @@ typedef enum {
 } data_path_t;
 
 typedef struct exinclude_s {
-    sl_t *sl_list;
-    sl_t *sl_file;
+    am_sl_t *sl_list;
+    am_sl_t *sl_file;
     int  optional;
 } exinclude_t;
 
@@ -204,6 +213,7 @@ typedef struct {
     int append;
     int priority;
     GSList* values;
+    seen_t seen;
 } property_t;
 
 typedef GHashTable* proplist_t;
@@ -258,13 +268,10 @@ typedef enum {
     CONFTYPE_NO_YES_ALL,
 } conftype_t;
 
-/* A "seen" struct.  Rather than allocate strings all over the place, this
- * string is in the "parsed_filenames" GSList and will be freed when that
- * GSList is freed.  This struct should be opaque to other modules. */
-typedef struct seen_s {
-    char *filename;
-    int linenum;
-} seen_t;
+typedef enum {
+    CONF_UNIT_NONE,
+    CONF_UNIT_K,
+} confunit_t;
 
 /* This should be considered an opaque type for any other modules.  The complete
  * struct is included here to allow quick access via macros. Access it *only* through
@@ -288,6 +295,7 @@ typedef struct val_s {
     } v;
     seen_t seen;
     conftype_t type;
+    confunit_t unit;
 } val_t;
 
 /* Functions to typecheck and extract a particular type of
@@ -488,6 +496,7 @@ typedef enum {
     CNF_TAPERSCAN,
     CNF_MAX_DLE_BY_VOLUME,
     CNF_EJECT_VOLUME,
+    CNF_TMPDIR,
     CNF_CNF /* sentinel */
 } confparm_key;
 
@@ -715,6 +724,7 @@ typedef enum {
     DUMPTYPE_ALLOW_SPLIT,
     DUMPTYPE_RECOVERY_LIMIT,
     DUMPTYPE_DUMP_LIMIT,
+    DUMPTYPE_MAX_WARNINGS,
     DUMPTYPE_DUMPTYPE /* sentinel */
 } dumptype_key;
 
@@ -806,6 +816,7 @@ char *dumptype_name(dumptype_t *dtyp);
 #define dumptype_get_allow_split(dtyp)         (val_t_to_boolean(dumptype_getconf((dtyp), DUMPTYPE_ALLOW_SPLIT)))
 #define dumptype_get_recovery_limit(dtyp)      (val_t_to_host_limit(dumptype_getconf((dtyp), DUMPTYPE_RECOVERY_LIMIT)))
 #define dumptype_get_dump_limit(dtyp)          (val_t_to_host_limit(dumptype_getconf((dtyp), DUMPTYPE_DUMP_LIMIT)))
+#define dumptype_get_max_warnings(dtyp)        (val_t_to_int(dumptype_getconf((dtyp), DUMPTYPE_MAX_WARNINGS)))
 
 /*
  * Interface parameter access
@@ -1481,7 +1492,10 @@ char *generic_get_security_conf(char *, void *);
  * This function only dumps the server configuration, and will fail on
  * clients.
  */
-void dump_configuration(void);
+void dump_configuration(gboolean print_default, gboolean print_source);
+
+void dump_dumptype(dumptype_t *dp, char *prefix, gboolean print_default,
+                  gboolean print_source);
 
 /* Return a sequence of strings giving the printable representation
  * of the given val_t.  If str_needs_quotes is true and each string is
@@ -1500,7 +1514,8 @@ void dump_configuration(void);
  * @param str_needs_quotes: add quotes to CONFTYPE_STR values?
  * @returns: NULL-terminated string vector
  */
-char **val_t_display_strs(val_t *val, int str_needs_quotes);
+char **val_t_display_strs(val_t *val, int str_needs_quotes, gboolean  print_source,
+                         gboolean print_unit);
 
 /* Read a dumptype; this is used by this module as well as by diskfile.c to
  * read the disklist.  The two are carefully balanced in their parsing process.
index 9fa8f2cd04049ecb3e8ffcf84e87d99d3b005bd4..33c45771def7d825a355f3e497beecede3a74415 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index e4c67c5629d983b845585a0f01b409b84708269d..832147e449b2b9d7a9d0c658f05b47d4e6e49ccf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 97e7c29552c7e0c7a27bf15aee958020d82b0638..218d63872fbd0386d9fdf23e65af9f35aa40a3bc 100644 (file)
@@ -311,6 +311,7 @@ any_mainloop_events(void)
 
     for (iter = all_events; iter != NULL; iter = g_slist_next(iter)) {
        event_handle_t *hdl = (event_handle_t *)iter->data;
+       event_debug(2, _("list %p: %s/%jd\n"), hdl, event_type2str((hdl)->type), (hdl)->data);
        if (hdl->type != EV_WAIT)
            return TRUE;
     }
index ec8057d7043ba6b99f2c310f62ce5d604f03e1c1..589f5caa1490b6d16534ec12b552df72645895b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+ * Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License version 2.1 as
index 5193837fe55626cc2472fc829381394fa88871d6..381c40d4a74bb6ded14a49b34e665817f193d028 100644 (file)
@@ -139,7 +139,7 @@ parse_file_header(
 
     if (strcmp(tok, "NETDUMP:") != 0 && strcmp(tok, "AMANDA:") != 0) {
        amfree(buf);
-       file->type = F_UNKNOWN;
+       file->type = F_WEIRD;
        amfree(line1);
        return;
     }
index 91985e500f4efa670c7ee69116af001ae4761a65..9fd8ced967bae8b91086e4c752a751523834c371 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
 
 #ifdef HAVE_LIBCURL
 #include <curl/curl.h>
-#endif
+
+#ifdef LIBCURL_USE_OPENSSL
+#include <openssl/crypto.h>
+static GMutex **openssl_mutex_array;
+static void openssl_lock_callback(int mode, int type, const char *file, int line)
+{
+    (void)file;
+    (void)line;
+    if (mode & CRYPTO_LOCK) {
+       g_mutex_lock(openssl_mutex_array[type]);
+    }
+    else {
+       g_mutex_unlock(openssl_mutex_array[type]);
+    }
+}
+
+static void
+init_ssl(void)
+{
+    int i;
+
+    openssl_mutex_array = g_new0(GMutex *, CRYPTO_num_locks());
+
+    for (i=0; i<CRYPTO_num_locks(); i++) {
+       openssl_mutex_array[i] = g_mutex_new();
+    }
+    CRYPTO_set_locking_callback(openssl_lock_callback);
+
+}
+
+#else /* LIBCURL_USE_OPENSSL */
+#if defined LIBCURL_USE_GNUTLS
+
+#include <gcrypt.h>
+#include <errno.h>
+
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+static void
+init_ssl(void)
+{
+  gcry_control(GCRYCTL_SET_THREAD_CBS);
+}
+
+#else  /* LIBCURL_USE_GNUTLS  */
+
+static void
+init_ssl(void)
+{
+}
+#endif /* LIBCURL_USE_GNUTLS  */
+#endif  /* LIBCURL_USE_OPENSSL */
+
+#else  /* HAVE_LIBCURL */
+static void
+init_ssl(void)
+{
+}
+#endif /* HAVE_LIBCURL */
 
 void
 glib_init(void) {
@@ -42,7 +99,9 @@ glib_init(void) {
      * is initialized) */
 #ifdef HAVE_LIBCURL
 # ifdef G_THREADS_ENABLED
+#  if (GLIB_MAJOR_VERSION < 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 31))
     g_assert(!g_thread_supported()); /* assert threads aren't initialized yet */
+#  endif
 # endif
     g_assert(curl_global_init(CURL_GLOBAL_ALL) == 0);
 #endif
@@ -70,6 +129,10 @@ glib_init(void) {
     if (!g_thread_supported())
        g_thread_init(NULL);
 #endif
+
+    /* initialize ssl */
+    init_ssl();
+
 }
 
 typedef enum {
@@ -120,15 +183,6 @@ void slist_free_full(GSList * list, GDestroyNotify free_fn) {
 }
 #endif
 
-void g_queue_free_full(GQueue * queue) {
-    while (!g_queue_is_empty(queue)) {
-        gpointer data;
-        data = g_queue_pop_head(queue);
-        amfree(data);
-    }
-    g_queue_free(queue);
-}
-
 void g_ptr_array_free_full(GPtrArray * array) {
     size_t i;
 
index f687fcd0529f5c08afadfd5f81bbe6b9713c6c54..a9b24ee8548ce8afe1206498c8828facce93f129 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -72,7 +72,6 @@ void slist_free_full(GSList * list, GDestroyNotify free_fn);
 
 /* These functions all take a GLib container, and call free() on all the
  * pointers in the container before free()ing the container itself. */
-void g_queue_free_full(GQueue * queue);
 void g_ptr_array_free_full(GPtrArray * array);
 
 /* g_value_compare() does what you expect. It returns TRUE if and
index 4d2363a0adf25273a9b586c5f1d301f3521144d7..99251645c3fb0609824cfc512ade6bd8cd780e93 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index e36efb7c3db6f92d2d81251012a59077a45b1841..3d8b54bf0917fabac9b2decce7b14a28e43006af 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 9be05efbe45674cb9a0bacdf8139f8407c2b26a6..30f21b2623b2e539f7d0d6d9ddac5a34adef526a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 0981a43f74484a3e7c7a8e1357a80f26a8452454..cd363e45877ca5e399040ad7d7744284de8fa7cb 100644 (file)
@@ -153,7 +153,14 @@ static struct mword_regexes mword_slash_regexes = {
  * be called from within threads, so play it safe.
  */
 
-static GStaticMutex re_cache_mutex = G_STATIC_MUTEX_INIT;
+#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31))
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+  static GStaticMutex re_cache_mutex = G_STATIC_MUTEX_INIT;
+# pragma GCC diagnostic pop
+#else
+  static GStaticMutex re_cache_mutex = G_STATIC_MUTEX_INIT;
+#endif
 static GHashTable *regex_cache = NULL, *regex_cache_newline = NULL;
 
 /*
index 967c852b854c880738bd8df54aeba104fb681bae..97adac0188740a748d7ca756743bbe6b6d611a69 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index b2df6acff293cfd511909789102cd21e5b2c2c7b..9edac6c453e705a25ae721b7b8ff8ffab42b30c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 2e0c0d03fe78c7cf46215886e6f0c79c40b9df40..e3942e649f433492d843d9c4a1115bfb57ad2715 100644 (file)
@@ -2672,7 +2672,7 @@ sec_get_authenticated_peer_name_gethostname(
        return server_hostname;
     }
     amfree(server_hostname);
-    return "localhost";
+    return strdup("localhost");
 }
 
 char *
@@ -2682,5 +2682,5 @@ sec_get_authenticated_peer_name_hostname(
     char *hostname = ((struct sec_handle *)hdl)->hostname;
     if (!hostname)
        hostname = "";
-    return hostname;
+    return strdup(hostname);
 }
index 46c636084fd80f530a47d5171f54b61c3bf6c3dc..c988a6d3014f1360e6c4cff8c3ea2f374afd0c7f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 961412475f08deeb100fe493daca8e8c369be436..e6e5950fd9006513863064b6d086606935ab6635 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
diff --git a/common-src/sl.c b/common-src/sl.c
deleted file mode 100644 (file)
index f84ebb3..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1991-1998 University of Maryland at College Park
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of U.M. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  U.M. makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
- *
- * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: James da Silva, Systems Design and Analysis Group
- *                         Computer Science Department
- *                         University of Maryland at College Park
- */
-/*
- * $Id: sl.c,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
- *
- * A doubly linked list of string (char *)
- */
-
-#include "amanda.h"
-#include "sl.h"
-
-
-void init_sl(
-    sl_t *sl)
-{
-    sl->first = NULL;
-    sl->last  = NULL;
-    sl->nb_element = 0;
-}
-
-
-sl_t *
-new_sl(void)
-{
-    sl_t *sl;
-    sl = alloc(SIZEOF(sl_t));
-    init_sl(sl);
-    return(sl);
-}
-
-
-sl_t *
-insert_sl(
-    sl_t *sl,
-    char *name)
-{
-    sle_t *a;
-
-    if(!sl) {
-       sl = new_sl();
-    }
-    a = alloc(SIZEOF(sle_t));
-    a->name = stralloc(name);
-    a->next = sl->first;
-    a->prev = NULL;
-    if(a->next)
-       a->next->prev = a;
-    else
-       sl->last = a;
-    sl->first = a;
-    sl->nb_element++;
-    return(sl);
-}
-
-
-sl_t *
-append_sl(
-    sl_t *     sl,
-    char *     name)
-{
-    sle_t *a;
-
-    if(!sl) {
-       sl = new_sl();
-    }
-    a = alloc(SIZEOF(sle_t));
-    a->name = stralloc(name);
-    a->prev = sl->last;
-    a->next = NULL;
-    if(a->prev)
-       a->prev->next = a;
-    else
-       sl->first = a;
-    sl->last = a;
-    sl->nb_element++;
-    return(sl);
-}
-
-
-sl_t *
-insert_sort_sl(
-    sl_t *     sl,
-    char *     name)
-{
-    sle_t *a, *b;
-
-    if(!sl) {
-       sl = new_sl();
-    }
-
-    for(b=sl->first; b != NULL; b=b->next) {
-       int i = strcmp(b->name, name);
-       if(i==0) return(sl); /* already there, no need to insert */
-       if(i>0) break;
-    }
-
-    if(b == sl->first) return insert_sl(sl, name);
-    if(b == NULL)      return append_sl(sl, name);
-
-    a = alloc(SIZEOF(sle_t));
-    a->name = stralloc(name);
-
-    /* insert before b */
-    a->next = b;
-    a->prev = b->prev;
-    b->prev->next = a;
-    b->prev = a;
-    sl->nb_element++;
-    return(sl);
-}
-
-
-void
-free_sl(
-    sl_t *     sl)
-{
-    sle_t *a, *b;
-
-    if(!sl) return;
-
-    a = sl->first;
-    while(a != NULL) {
-       b = a;
-       a = a->next;
-       amfree(b->name);
-       amfree(b);
-    }
-    amfree(sl);
-}
-
-
-void
-remove_sl(
-    sl_t *     sl,
-    sle_t *    elem)
-{
-    if(elem->prev)
-       elem->prev->next = elem->next;
-    else
-       sl->first = elem->next;
-
-    if(elem->next)
-       elem->next->prev = elem->prev;
-    else
-       sl->last = elem->prev;
-
-    sl->nb_element--;
-
-    amfree(elem->name);
-    amfree(elem);
-}
-
-
-sl_t *
-duplicate_sl(
-    sl_t *     sl)
-{
-    sl_t *new_sl = NULL;
-    sle_t *a;
-
-    if(!sl) return new_sl;
-
-    for(a = sl->first; a != NULL; a = a->next) {
-       new_sl = append_sl(new_sl, a->name);
-    }
-
-    return new_sl;
-}
-
-/*
- * Return "true" iff sl is empty (i.e. contains no elements).
- */
-int
-is_empty_sl(
-    sl_t *     sl)
-{
-    if (sl == NULL)
-       return 1;
-
-    return (sl->nb_element == 0);
-}
diff --git a/common-src/sl.h b/common-src/sl.h
deleted file mode 100644 (file)
index 7671d79..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1991-1998 University of Maryland at College Park
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of U.M. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  U.M. makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
- *
- * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: James da Silva, Systems Design and Analysis Group
- *                         Computer Science Department
- *                         University of Maryland at College Park
- */
-/*
- * $Id: sl.h,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
- *
- * A doubly linked list of string (char *)
- */
-
-/*
- * To scan over all element of the list
- *
- *    for(sle=sl->first; sle != NULL; sle = sle->next) {
- *    }
- */
-#ifndef STRINGLIST_H
-#define STRINGLIST_H
-
-#include "amanda.h"
-
-typedef struct sle_s {
-    struct sle_s *next, *prev;
-    char *name;
-} sle_t;
-
-typedef struct sl_s {
-    struct sle_s *first, *last;
-    int nb_element;
-} sl_t;
-
-void init_sl(sl_t *sl);
-sl_t *new_sl(void);
-sl_t *insert_sl(sl_t *sl, char *name);
-sl_t *append_sl(sl_t *sl, char *name);
-sl_t *insert_sort_sl(sl_t *sl, char *name);
-void free_sl(sl_t *sl);
-void remove_sl(sl_t *sl,sle_t *elem);
-sl_t *duplicate_sl(sl_t *sl);
-int  is_empty_sl(sl_t *sl);
-
-#endif
index 041757575de264f3e394d975773d7b088f5be286..1cf79dad41732aed2d135ad4369bd4e31753ca03 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 2b162018d025081bc663e2bb8327399d7d427f50..5277742c8b913580de99c258e24ab47269f0e5c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 1d84ab6fd7a74ad1c954acbb57cac87bc438fccb..bcd1d98658a16be53147268630342881ac5facd2 100644 (file)
@@ -114,7 +114,7 @@ ssh_connect(
     int result;
     struct sec_handle *rh;
     char *amandad_path=NULL, *client_username=NULL, *ssh_keys=NULL;
-    char *client_port = "22";
+    char *client_port = NULL;
 
     assert(fn != NULL);
     assert(hostname != NULL);
@@ -304,6 +304,10 @@ runssh(
     char *xclient_username = (char *)client_username;
     char *xssh_keys = (char *)ssh_keys;
     char *xclient_port = (char *)client_port;
+    GPtrArray *myargs;
+    gchar *ssh_options[100] = {SSH_OPTIONS, NULL};
+    gchar **ssh_option;
+    gchar *cmd;
 
     memset(rpipe, -1, SIZEOF(rpipe));
     memset(wpipe, -1, SIZEOF(wpipe));
@@ -317,18 +321,31 @@ runssh(
     if(!xclient_username || strlen(xclient_username) <= 1)
        xclient_username = CLIENT_LOGIN;
     if(!xclient_port || strlen(xclient_port) <= 1)
-       xclient_port = "22";
+       xclient_port = NULL;
 
-    if(!ssh_keys || strlen(ssh_keys) <= 1) {
-       g_debug("exec: %s %s %s %s %s %s %s %s %s",
-               SSH, "SSH_OPTIONS", "-l", xclient_username, "-p", client_port,
-               rc->hostname, xamandad_path, "-auth=ssh");
+    myargs = g_ptr_array_sized_new(20);
+    g_ptr_array_add(myargs, SSH);
+    for (ssh_option = ssh_options; *ssh_option != NULL; ssh_option++) {
+       g_ptr_array_add(myargs, *ssh_option);
     }
-    else {
-       g_debug("exec: %s %s %s %s %s %s %s %s %s %s %s",
-               SSH, "SSH_OPTIONS", "-l", xclient_username, "-p", client_port,
-               "-i", xssh_keys, rc->hostname, xamandad_path, "-auth=ssh");
+    g_ptr_array_add(myargs, "-l");
+    g_ptr_array_add(myargs, xclient_username);
+    if (xclient_port) {
+       g_ptr_array_add(myargs, "-p");
+       g_ptr_array_add(myargs, xclient_port);
     }
+    if (ssh_keys && strlen(ssh_keys) > 1) {
+       g_ptr_array_add(myargs, "-i");
+       g_ptr_array_add(myargs, xssh_keys);
+    }
+    g_ptr_array_add(myargs, rc->hostname);
+    g_ptr_array_add(myargs, xamandad_path);
+    g_ptr_array_add(myargs, "-auth=ssh");
+    g_ptr_array_add(myargs, NULL);
+
+    cmd = g_strjoinv(" ", (gchar **)myargs->pdata);
+    g_debug("exec: %s", cmd);
+    g_free(cmd);
 
     switch (rc->pid = fork()) {
     case -1:
@@ -355,15 +372,8 @@ runssh(
 
     safe_fd(-1, 0);
 
-    if(!ssh_keys || strlen(ssh_keys) <= 1) {
-       execlp(SSH, SSH, SSH_OPTIONS, "-l", xclient_username, "-p", client_port,
-              rc->hostname, xamandad_path, "-auth=ssh", (char *)NULL);
-    }
-    else {
-       execlp(SSH, SSH, SSH_OPTIONS, "-l", xclient_username, "-p", client_port,
-              "-i", xssh_keys, rc->hostname, xamandad_path, "-auth=ssh",
-              (char *)NULL);
-    }
+    execvp(SSH, (gchar **)myargs->pdata);
+
     error("error: couldn't exec %s: %s", SSH, strerror(errno));
 
     /* should never go here, shut up compiler warning */
index 1711f251ccaa5e054e4624e4e6bbc6029a680657..da674f6e2deb3b98257d60893d647cbbb735901e 100644 (file)
@@ -1,2 +1,2 @@
-#define BUILT_REV "4553"
-#define BUILT_BRANCH "community_3_3_1"
+#define BUILT_REV "4847"
+#define BUILT_BRANCH "community_3_3_2"
index b957e872a105e61c892145754d3d3466f0289ce1..3d642afe82d18b09fe1f7eabe467c4a739d199bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 256f10432a2c213c70ee7d3d1c7a66a13746dc34..288d34e60c72e0c1ff10dbd6b0cd2af28b7b3f86 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 30963555d25f80171edd43a99c1bd1446737bb76..8589b9a054f604595221edf6e99e6ca9b1639005 100644 (file)
@@ -74,6 +74,12 @@ time_t get_time_from_timestamp(char *timestamp)
     struct tm tm;
     char t[5];
     time_t tt;
+    tm.tm_year = 0;
+    tm.tm_mon = 0;
+    tm.tm_mday = 1;
+    tm.tm_hour = 0;
+    tm.tm_min = 0;
+    tm.tm_sec = 0;
 
     if (strlen(timestamp) >= 4) {
        memcpy(t, timestamp, 4);
index b9172ca41950fa716235833f7e2b0c2853fbd957..eed9d981bca4bc5283453f532e281412de548788 100644 (file)
@@ -960,6 +960,7 @@ expand_braced_alternates(
     char * source)
 {
     GPtrArray *rval = g_ptr_array_new();
+    gpointer *pdata;
 
     g_ptr_array_add(rval, g_strdup(""));
 
@@ -971,6 +972,8 @@ expand_braced_alternates(
        new_components = parse_braced_component(&source);
        if (!new_components) {
            /* parse error */
+           for (i = 0, pdata = rval->pdata; i < rval->len; i++)
+               g_free(*pdata++);
            g_ptr_array_free(rval, TRUE);
            return NULL;
        }
@@ -987,7 +990,11 @@ expand_braced_alternates(
            }
        }
 
+       for (i = 0, pdata = rval->pdata; i < rval->len; i++)
+           g_free(*pdata++);
        g_ptr_array_free(rval, TRUE);
+       for (i = 0, pdata = new_components->pdata; i < new_components->len; i++)
+           g_free(*pdata++);
        g_ptr_array_free(new_components, TRUE);
        rval = new_rval;
     }
@@ -1139,6 +1146,11 @@ add_history(
 # error No readdir() or readdir64() available!
 #endif
 
+#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31))
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
 char * portable_readdir(DIR* handle) {
 
 #ifdef USE_DIRENT64
@@ -1168,6 +1180,9 @@ char * portable_readdir(DIR* handle) {
        sure what to do about that case. */
     return strdup(entry_p->d_name);
 }
+#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31))
+# pragma GCC diagnostic pop
+#endif
 
 int search_directory(DIR * handle, const char * regex,
                      SearchDirectoryFunctor functor, gpointer user_data) {
index 140982f5e45969d582e1f6fcc4f2b96fd40bfa65..fe951b5523556cac992b208a85e3f2ea95266a96 100644 (file)
@@ -30,7 +30,7 @@
 #define        UTIL_H
 
 #include "amanda.h"
-#include "sl.h"
+#include "am_sl.h"
 
 #include <glib.h>
 #include <glib-object.h>
index 9f8e8e6d6207343501da7d97b458fc9470ac069a..de1f943f493c26aa54239cc364d72a0dca2b9d4c 100644 (file)
@@ -189,7 +189,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -705,6 +706,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index b853132c657509f0c382b9774ecba9c593426998..e6acb04cd4b9b0d6409401d2ddd100ebb174279b 100644 (file)
@@ -381,6 +381,41 @@ x=CURLOPT_VERBOSE;
         fi
      fi
 
+      LIBCURL_USE_NSS=no
+      LIBCURL_USE_GNUTLS=no
+      LIBCURL_USE_OPENSSL=yes
+     _libcurl_configures=`$_libcurl_config --configure`
+     for _libcurl_configure in $_libcurl_configures ; do
+       if [[[ $_libcurl_configure = \'--with-nss* ]]]; then
+           LIBCURL_USE_NSS=yes
+       fi
+       if [[[ $_libcurl_configure = \'--without-nss* ]]]; then
+           LIBCURL_USE_NSS=no
+       fi
+       if [[[ $_libcurl_configure = \'--with-gnutls* ]]]; then
+           LIBCURL_USE_GNUTLS=yes
+       fi
+       if [[[ $_libcurl_configure = \'--without-gnutls* ]]]; then
+           LIBCURL_USE_GNUTLS=no
+       fi
+       if [[[ $_libcurl_configure = \'--with-ssl* ]]]; then
+           LIBCURL_USE_OPENSSL=yes
+       fi
+       if [[[ $_libcurl_configure = \'--without-ssl* ]]]; then
+           LIBCURL_USE_OPENSSL=no
+       fi
+     done
+
+     if test "x$LIBCURL_USE_NSS" = "xyes"; then
+       AC_DEFINE(LIBCURL_USE_NSS, 1, [Defined if libcurl use NSS])
+     fi
+     if test "x$LIBCURL_USE_GNUTLS" = "xyes"; then
+       AC_DEFINE(LIBCURL_USE_GNUTLS, , [Defined if libcurl use GnuTLS])
+     fi
+     if test "x$LIBCURL_USE_OPENSSL" = "xyes"; then
+       AC_DEFINE(LIBCURL_USE_OPENSSL, 1, [Defined if libcurl use OpenSSL])
+     fi
+
      unset _libcurl_try_link
      unset _libcurl_version_parse
      unset _libcurl_config
@@ -390,6 +425,8 @@ x=CURLOPT_VERBOSE;
      unset _libcurl_protocols
      unset _libcurl_version
      unset _libcurl_ldflags
+     unset _libcurl_configure
+     unset _libcurl_configures
   fi
 
   if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
index 128b03d1ce6b85aa24c922055be0fa3965eec9eb..31e70075cade57ac081bd20be1f6ddeb4d8fb963 100644 (file)
@@ -395,3 +395,9 @@ AC_DEFUN([AMANDA_PROG_LEX],
     fi
 ])
 
+AC_DEFUN([AMANDA_PROG_NC],
+[
+    AC_PATH_PROG(NC,nc,,$LOCSYSPATH)
+    AC_PATH_PROG(NC6,nc6,,$LOCSYSPATH)
+    AC_PATH_PROG(NETCAT,netcat,,$LOCSYSPATH)
+])
index da26e94eace944adc3506e799f53b13676e55acc..736362ec65740cb2767dbb94246c0eec50b3d31e 100644 (file)
@@ -1,18 +1,35 @@
 # Amanda version handling macros
 
+# SYNOPSIS
+#
+#   AMANDA_INIT_VERSION
+#
+# DESCRIPTION
+#
+#   Create a macro, AMANDA_F_VERSION using only m4 which can expand
+#   legally before AC_INIT.  AC_INIT requires the version to be a
+#   string not a shell variable. Include FULL_VERSION if it exists, otherwise
+#   use VERSION.  -I dirs are searched for FULL_VERSION and VERSION.
+#
+AC_DEFUN([AMANDA_INIT_VERSION],
+[
+    m4_syscmd([test -f FULL_VERSION])
+    m4_if(m4_sysval, [0],
+    [
+        m4_define([AMANDA_F_VERSION], m4_chomp(m4_include([FULL_VERSION])))
+    ],
+    [
+        m4_define([AMANDA_F_VERSION], m4_chomp(m4_include([VERSION])))
+
+    ])
+    VERSION=AMANDA_F_VERSION
+])
+
 AC_DEFUN([AMANDA_VERSION],
 [
     AMANDA_GET_SVN_INFO
     AMANDA_GET_GIT_INFO
 
-    if test -f FULL_VERSION; then
-       VERSION=`cat FULL_VERSION`
-    else if test -f $srcdir/FULL_VERSION; then
-       VERSION=`cat $srcdir/FULL_VERSION`
-    else
-       VERSION=`cat $srcdir/VERSION`
-    fi
-    fi
     AC_MSG_NOTICE("version: $VERSION")
 ])
 
@@ -49,7 +66,7 @@ AC_DEFUN([AMANDA_SNAPSHOT_STAMP],
 # DESCRIPTION
 #
 #   Set the version number of this release of Amanda from the VERSION
-#   string, which is set in AM_INIT_AUTOMAKE.  Sets VERSION_MAJOR,
+#   string, which is set in AC_INIT.  Sets VERSION_MAJOR,
 #   VERSION_MINOR, VERSION_PATCH, and VERSION_COMMENT to the 
 #   corresponding components of VERSION.  These four variables are
 #   also AC_DEFINE'd
index 7d38cf3ea5b5f6eefc73af78e30101ed9bb8edf6..3997189b0fc4771e6cdf227daa8f091b8e5bc139 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index ea75addea50e7562e0bd4d9b66e9dcba4d07ba74..00d24e893f963345216ab90bc66c7e41b93a5b68 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index d91daf7b89444a63c1a8bef493deab6869c72d42..c2557ce0ee36e5f53aeb9bc4aa468090f95df771 100644 (file)
 /* Defined if libcurl supports TFTP */
 #undef LIBCURL_PROTOCOL_TFTP
 
+/* Defined if libcurl use GnuTLS */
+#undef LIBCURL_USE_GNUTLS
+
+/* Defined if libcurl use NSS */
+#undef LIBCURL_USE_NSS
+
+/* Defined if libcurl use OpenSSL */
+#undef LIBCURL_USE_OPENSSL
+
 /* A comma-separated list of two integers, determining the minimum and maximum
    * reserved TCP port numbers sockets should be bound to. (mainly for
    amrecover) */
index b2d269bb47cc94c9fddd73fb1b1311dd8521b0db..db6eae46ebdad122cb1cc3c67b14c2e09cdfd2b4 100644 (file)
@@ -32,7 +32,7 @@
 #
 # COPYRIGHT
 #
-#   Copyright (c) 2007,2008 Zmanda, Inc.  All Rights Reserved.
+#   Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #  
 #   This program is free software; you can redistribute it and/or modify it
 #   under the terms of the GNU General Public License version 2 as published
index 453c79c34e3e2d740cbb54b3fe63e2a22fe88ab1..5ac1b08fa9e5b9fa874221b7aeb56bc79bef67ee 100644 (file)
@@ -27,7 +27,7 @@
 #
 # COPYRIGHT
 #
-#   Copyright (c) 2007,2008 Zmanda, Inc.  All Rights Reserved.
+#   Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #  
 #   This program is free software; you can redistribute it and/or modify it
 #   under the terms of the GNU General Public License version 2 as published
index 36788de8d9f4d3a75eed95647e5dc81b9ca7fc12..4c3f4dff85c1407e5a08706fb38eaf8c1b25bec9 100644 (file)
@@ -32,7 +32,7 @@
 #
 # COPYRIGHT
 #
-#   Copyright (c) 2007,2008 Zmanda, Inc.  All Rights Reserved.
+#   Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #  
 #   This program is free software; you can redistribute it and/or modify it
 #   under the terms of the GNU General Public License version 2 as published
index 12a2bd7928029b8420a7645b987b90a4b5ea3f18..386a34c5de221e7ce578ea7c9efa49b96a74567e 100644 (file)
@@ -27,7 +27,7 @@
 #
 # COPYRIGHT
 #
-#   Copyright (c) 2007,2008 Zmanda, Inc.  All Rights Reserved.
+#   Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #  
 #   This program is free software; you can redistribute it and/or modify it
 #   under the terms of the GNU General Public License version 2 as published
index a8b2b5513c96f50a4933ad314c821e5e8ea2b13d..c0e7761bf1cbc47f661c17e6b25a053d4fb9e2f6 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68.
+# Generated by GNU Autoconf 2.68 for amanda 3.3.2.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -565,12 +565,12 @@ MFLAGS=
 MAKEFLAGS=
 
 # Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-PACKAGE_URL=
+PACKAGE_NAME='amanda'
+PACKAGE_TARNAME='amanda'
+PACKAGE_VERSION='3.3.2'
+PACKAGE_STRING='amanda 3.3.2'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
 
 ac_unique_file="common-src/amanda.h"
 # Factoring default headers for most tests.
@@ -664,6 +664,9 @@ LIBTOOL
 AMANDA_SWIG_PERL_CFLAGS
 GCC_COMPILER_FALSE
 GCC_COMPILER_TRUE
+NETCAT
+NC6
+NC
 RPCGEN
 PS_ARGUMENT_ARGS
 PS_ARGUMENT
@@ -1644,7 +1647,7 @@ sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
 infodir='${datarootdir}/info'
 htmldir='${docdir}'
 dvidir='${docdir}'
@@ -2146,7 +2149,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
+\`configure' configures amanda 3.3.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -2194,7 +2197,7 @@ Fine tuning of the installation directories:
   --infodir=DIR           info documentation [DATAROOTDIR/info]
   --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
   --mandir=DIR            man documentation [DATAROOTDIR/man]
-  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/amanda]
   --htmldir=DIR           html documentation [DOCDIR]
   --dvidir=DIR            dvi documentation [DOCDIR]
   --pdfdir=DIR            pdf documentation [DOCDIR]
@@ -2215,7 +2218,9 @@ _ACEOF
 fi
 
 if test -n "$ac_init_help"; then
-
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of amanda 3.3.2:";;
+   esac
   cat <<\_ACEOF
 
 Optional Features:
@@ -2490,7 +2495,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-configure
+amanda configure 3.3.2
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -3190,7 +3195,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by $as_me, which was
+It was created by amanda $as_me 3.3.2, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3883,14 +3888,6 @@ $as_echo "not available" >&6; }
     rm -f conftemp.git
 
 
-    if test -f FULL_VERSION; then
-       VERSION=`cat FULL_VERSION`
-    else if test -f $srcdir/FULL_VERSION; then
-       VERSION=`cat $srcdir/FULL_VERSION`
-    else
-       VERSION=`cat $srcdir/VERSION`
-    fi
-    fi
     { $as_echo "$as_me:${as_lineno-$LINENO}: \"version: $VERSION\"" >&5
 $as_echo "$as_me: \"version: $VERSION\"" >&6;}
 
@@ -4332,8 +4329,8 @@ fi
 
 
 # Define the identity of the package.
- PACKAGE=amanda
- VERSION=$VERSION
+ PACKAGE='amanda'
+ VERSION='3.3.2'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4367,7 +4364,88 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
 AMTAR=${AMTAR-"${am_missing_run}tar"}
 
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5
+$as_echo_n "checking how to create a ustar tar archive... " >&6; }
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar plaintar pax cpio none'
+_am_tools=${am_cv_prog_tar_ustar-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      { echo "$as_me:$LINENO: $_am_tar --version" >&5
+   ($_am_tar --version) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && break
+    done
+    am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x ustar -w "$$tardir"'
+    am__tar_='pax -L -x ustar -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H ustar -L'
+    am__tar_='find "$tardir" -print | cpio -o -H ustar -L'
+    am__untar='cpio -i -H ustar -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_ustar}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5
+   (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    { echo "$as_me:$LINENO: $am__untar <conftest.tar" >&5
+   ($am__untar <conftest.tar) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+if ${am_cv_prog_tar_ustar+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  am_cv_prog_tar_ustar=$_am_tool
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5
+$as_echo "$am_cv_prog_tar_ustar" >&6; }
 
 
 
 
 
 
+    # Extract the first word of "nc", so it can be a program name with args.
+set dummy nc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_NC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $NC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_NC="$NC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_NC="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+NC=$ac_cv_path_NC
+if test -n "$NC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NC" >&5
+$as_echo "$NC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    # Extract the first word of "nc6", so it can be a program name with args.
+set dummy nc6; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_NC6+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $NC6 in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_NC6="$NC6" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_NC6="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+NC6=$ac_cv_path_NC6
+if test -n "$NC6"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NC6" >&5
+$as_echo "$NC6" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    # Extract the first word of "netcat", so it can be a program name with args.
+set dummy netcat; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_NETCAT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $NETCAT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_NETCAT="$NETCAT" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_NETCAT="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+NETCAT=$ac_cv_path_NETCAT
+if test -n "$NETCAT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NETCAT" >&5
+$as_echo "$NETCAT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
 
 #
 # Compiler / system characteristics
@@ -44270,6 +44470,47 @@ _ACEOF
            unset LIBCURL
            unset LIBCURL_CPPFLAGS
         fi
+     fi
+
+      LIBCURL_USE_NSS=no
+      LIBCURL_USE_GNUTLS=no
+      LIBCURL_USE_OPENSSL=yes
+     _libcurl_configures=`$_libcurl_config --configure`
+     for _libcurl_configure in $_libcurl_configures ; do
+       if [[ $_libcurl_configure = \'--with-nss* ]]; then
+           LIBCURL_USE_NSS=yes
+       fi
+       if [[ $_libcurl_configure = \'--without-nss* ]]; then
+           LIBCURL_USE_NSS=no
+       fi
+       if [[ $_libcurl_configure = \'--with-gnutls* ]]; then
+           LIBCURL_USE_GNUTLS=yes
+       fi
+       if [[ $_libcurl_configure = \'--without-gnutls* ]]; then
+           LIBCURL_USE_GNUTLS=no
+       fi
+       if [[ $_libcurl_configure = \'--with-ssl* ]]; then
+           LIBCURL_USE_OPENSSL=yes
+       fi
+       if [[ $_libcurl_configure = \'--without-ssl* ]]; then
+           LIBCURL_USE_OPENSSL=no
+       fi
+     done
+
+     if test "x$LIBCURL_USE_NSS" = "xyes"; then
+
+$as_echo "#define LIBCURL_USE_NSS 1" >>confdefs.h
+
+     fi
+     if test "x$LIBCURL_USE_GNUTLS" = "xyes"; then
+
+$as_echo "#define LIBCURL_USE_GNUTLS /**/" >>confdefs.h
+
+     fi
+     if test "x$LIBCURL_USE_OPENSSL" = "xyes"; then
+
+$as_echo "#define LIBCURL_USE_OPENSSL 1" >>confdefs.h
+
      fi
 
      unset _libcurl_try_link
@@ -44281,6 +44522,8 @@ _ACEOF
      unset _libcurl_protocols
      unset _libcurl_version
      unset _libcurl_ldflags
+     unset _libcurl_configure
+     unset _libcurl_configures
   fi
 
   if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
@@ -45494,7 +45737,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by $as_me, which was
+This file was extended by amanda $as_me 3.3.2, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -45560,7 +45803,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-config.status
+amanda config.status 3.3.2
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
index 103000945aa4785e89c41edb333c049bbf6a0a3e..72c255df98cadc05cb057b57d6f49185915c1361 100644 (file)
@@ -1,4 +1,5 @@
-AC_INIT
+AMANDA_INIT_VERSION
+AC_INIT([amanda], [AMANDA_F_VERSION])
 AC_CONFIG_SRCDIR([common-src/amanda.h])
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_MACRO_DIR(config)
@@ -8,11 +9,11 @@ PACKAGE=amanda
 AC_SUBST(PACKAGE)
 
 AMANDA_VERSION
-AM_INIT_AUTOMAKE(amanda, $VERSION)
+AM_INIT_AUTOMAKE(tar-ustar 1.10)
 AC_CONFIG_HEADERS([config/config.h])
 
 dnl Minimum Autoconf version required.
-AC_PREREQ(2.59)
+AC_PREREQ(2.64)
 
 #
 # Take care of some early Amanda-specific setup
@@ -145,6 +146,7 @@ AMANDA_PROG_PERL
 AMANDA_PROG_SWIG
 AMANDA_PS_ARGUMENT
 AMANDA_PROG_RPCGEN
+AMANDA_PROG_NC
 
 dnl -------------------------------------------------------------------------
 
index 3900adeeecc658bb8985eab23e390ce040db647e..1e2d68d1adba818dbf056a91f1e5198e7cf71c23 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda tape library.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -40,7 +40,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -300,7 +300,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -893,6 +894,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 78392643d378bc6d555307cd3c2a8b56121ed19f..43cfa98b98354bbefc7000fd0fbf62636bb3a92f 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index ef40d579b551a565430c867d5bc9a88f423fd9a9..8e38957ad5ddfc55afe4720ef1b4fae9cedb8c22 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f0258d5d25b20cba4b4a69aa999312e21016fa82..2413dfc6160e74e4585152522e79ddb4ce0529fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -526,6 +526,7 @@ device_open (char * device_name)
     device = factory(device_name, device_type, device_node);
     g_assert(device != NULL); /* factories must always return a device */
 
+    device->device_mutex = g_mutex_new();
     amfree(device_type);
     amfree(device_node);
 
@@ -1116,6 +1117,46 @@ device_finish (Device * self) {
     return (klass->finish)(self);
 }
 
+guint64
+device_get_bytes_read (Device * self) {
+    DeviceClass *klass;
+    guint64 bytes = 0;
+
+    g_assert(IS_DEVICE (self));
+
+    g_mutex_lock(self->device_mutex);
+    if (self->in_file) {
+       klass = DEVICE_GET_CLASS(self);
+       if (klass->get_bytes_read) {
+           bytes = (klass->get_bytes_read)(self);
+       } else {
+           bytes = self->bytes_read;
+       }
+    }
+    g_mutex_unlock(self->device_mutex);
+    return bytes;
+}
+
+guint64
+device_get_bytes_written (Device * self) {
+    DeviceClass *klass;
+    guint64 bytes = 0;
+
+    g_assert(IS_DEVICE (self));
+
+    g_mutex_lock(self->device_mutex);
+    if (self->in_file) {
+       klass = DEVICE_GET_CLASS(self);
+       if (klass->get_bytes_written) {
+           bytes = (klass->get_bytes_written)(self);
+       } else {
+           bytes = self->bytes_written;
+       }
+    }
+    g_mutex_unlock(self->device_mutex);
+    return bytes;
+}
+
 gboolean
 device_configure (Device * self, gboolean use_global_config)
 {
@@ -1392,6 +1433,26 @@ device_accept(
     }
 }
 
+gboolean
+device_accept_with_cond(
+    Device *self,
+    DirectTCPConnection **conn,
+    GMutex *abort_mutex,
+    GCond *abort_cond)
+{
+    DeviceClass *klass;
+
+    klass = DEVICE_GET_CLASS(self);
+    if(klass->accept_with_cond) {
+       return (klass->accept_with_cond)(self, conn, abort_mutex, abort_cond);
+    } else {
+       device_set_error(self,
+           g_strdup(_("Unimplemented method")),
+           DEVICE_STATUS_DEVICE_ERROR);
+       return FALSE;
+    }
+}
+
 gboolean
 device_connect(
     Device *self,
@@ -1414,6 +1475,28 @@ device_connect(
     }
 }
 
+gboolean
+device_connect_with_cond(
+    Device *self,
+    gboolean for_writing,
+    DirectTCPAddr *addrs,
+    DirectTCPConnection **conn,
+    GMutex *abort_mutex,
+    GCond *abort_cond)
+{
+    DeviceClass *klass;
+
+    klass = DEVICE_GET_CLASS(self);
+    if(klass->connect) {
+       return (klass->connect_with_cond)(self, for_writing, addrs, conn, abort_mutex, abort_cond);
+    } else {
+       device_set_error(self,
+           g_strdup(_("Unimplemented method")),
+           DEVICE_STATUS_DEVICE_ERROR);
+       return FALSE;
+    }
+}
+
 gboolean
 device_write_from_connection(
     Device *self,
index 57f6b37573eeeadf8f7e2e5e529d02b3022267a4..0945b0b1ef930fa12e6610bf0ff092d63bff0939 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -91,6 +91,11 @@ typedef struct Device {
     /* You can peek at the stuff below, but only subclasses should
        change these values.*/
 
+    /* A mutex to protect field accessed from another thread.
+     * Only get_bytes_read and get_bytes_written are allowed from another
+     * Only in_file, bytes_read and bytes_written are protected */
+    GMutex  *device_mutex;
+
     /* What file, block are we at? (and are we in the middle of a file?) */
     int file;
     guint64 block;
@@ -134,6 +139,9 @@ typedef struct Device {
     gsize block_size;
     gsize header_block_size;
 
+    guint64 bytes_read;
+    guint64 bytes_written;
+
     /* surety and source for the block size; if you set block_size directly,
      * set these, too! */
     PropertySurety block_size_surety;
@@ -193,13 +201,20 @@ struct _DeviceClass {
     gboolean (* erase) (Device * self);
     gboolean (* eject) (Device * self);
     gboolean (* finish) (Device * self);
+    guint64  (* get_bytes_read) (Device * self);
+    guint64  (* get_bytes_written) (Device * self);
 
     gboolean (* listen)(Device *self, gboolean for_writing, DirectTCPAddr **addrs);
     gboolean (* accept)(Device *self, DirectTCPConnection **conn,
                        ProlongProc prolong, gpointer prolong_data);
+    int (* accept_with_cond)(Device *self, DirectTCPConnection **conn,
+                                 GMutex *abort_mutex, GCond *abort_cond);
     gboolean (* connect)(Device *self, gboolean for_writing, DirectTCPAddr *addrs,
                        DirectTCPConnection **conn, ProlongProc prolong,
                        gpointer prolong_data);
+    gboolean (* connect_with_cond)(Device *self, gboolean for_writing,
+                       DirectTCPAddr *addrs, DirectTCPConnection **conn,
+                       GMutex *abort_mutex, GCond *abort_cond);
     gboolean (* write_from_connection)(Device *self, guint64 size, guint64 *actual_size);
     gboolean (* read_to_connection)(Device *self, guint64 size, guint64 *actual_size);
     gboolean (* use_connection)(Device *self, DirectTCPConnection *conn);
@@ -294,6 +309,8 @@ gboolean    device_start    (Device * self,
                                  DeviceAccessMode mode, char * label,
                                  char * timestamp);
 gboolean       device_finish   (Device * self);
+guint64        device_get_bytes_read   (Device * self);
+guint64        device_get_bytes_written(Device * self);
 gboolean        device_start_file       (Device * self,
                                          dumpfile_t * jobInfo);
 gboolean       device_write_block      (Device * self,
@@ -331,9 +348,14 @@ gboolean   device_eject    (Device * self);
 gboolean device_listen(Device *self, gboolean for_writing, DirectTCPAddr **addrs);
 gboolean device_accept(Device *self, DirectTCPConnection **conn,
                 ProlongProc prolong, gpointer prolong_data);
+int device_accept_with_cond(Device *self, DirectTCPConnection **conn,
+                                GMutex *abort_mutex, GCond *abort_cond);
 gboolean device_connect(Device *self, gboolean for_writing, DirectTCPAddr *addrs,
                        DirectTCPConnection **conn, ProlongProc prolong,
                        gpointer prolong_data);
+gboolean device_connect_with_cond(Device *self, gboolean for_writing,
+                       DirectTCPAddr *addrs, DirectTCPConnection **conn,
+                       GMutex *abort_mutex, GCond *abort_cond);
 gboolean device_write_from_connection(Device *self, guint64 size, guint64 *actual_size);
 gboolean device_read_to_connection(Device *self, guint64 size, guint64 *actual_size);
 gboolean device_use_connection(Device *self, DirectTCPConnection *conn);
index a7ce07117f0d5d7ec6c2f58be7bd24ec6c6fafeb..442fd8a95db7aeed70a2dda7ca5a85a7ed395e34 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 89c089434605fde311867c110af4cf0313dfdb6e..89616260bdecf5303d577f7cd19013dbd3ceb132 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index f4e39bd29f0f83b9c27e16705557fe9b6c200f52..865f7407b47196eb625c57ad7819fb9c6897c0b1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
 #include "util.h"
 #include "device.h"
 #include "directtcp.h"
+#include "stream.h"
 #include "ndmlib.h"
 #include "ndmpconnobj.h"
+#include "sockaddr-util.h"
 
 /*
  * Type checking and casting macros
@@ -54,6 +56,10 @@ struct NdmpDevice_ {
     DirectTCPAddr *listen_addrs;
     gboolean for_writing;
 
+    /* support for IndirectTCP */
+    int indirecttcp_sock; /* -1 if not in use */
+    int indirect;
+
     /* Current DirectTCPConnectionNDMP */
     struct DirectTCPConnectionNDMP_ *directtcp_conn;
 
@@ -136,9 +142,11 @@ typedef enum {
 static DevicePropertyBase device_property_ndmp_username;
 static DevicePropertyBase device_property_ndmp_password;
 static DevicePropertyBase device_property_ndmp_auth;
+static DevicePropertyBase device_property_indirect;
 #define PROPERTY_NDMP_USERNAME (device_property_ndmp_username.ID)
 #define PROPERTY_NDMP_PASSWORD (device_property_ndmp_password.ID)
 #define PROPERTY_NDMP_AUTH (device_property_ndmp_auth.ID)
+#define PROPERTY_INDIRECT (device_property_indirect.ID)
 
 
 /*
@@ -453,6 +461,8 @@ static void ndmp_device_finalize(GObject * obj_self)
        g_free(self->ndmp_password);
     if (self->ndmp_auth)
        g_free(self->ndmp_auth);
+    if (self->indirecttcp_sock != -1)
+       close(self->indirecttcp_sock);
 }
 
 static DeviceStatusFlags
@@ -580,7 +590,9 @@ ndmp_device_start(
     }
 
     dself->access_mode = mode;
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = FALSE;
+    g_mutex_unlock(dself->device_mutex);
 
     if (!single_ndmp_mtio(self, NDMP9_MTIO_REW)) {
        /* single_ndmp_mtio already set our error message */
@@ -714,6 +726,9 @@ ndmp_device_start_file(
 
     dself->is_eof = FALSE;
     dself->is_eom = FALSE;
+    g_mutex_lock(dself->device_mutex);
+    dself->bytes_written = 0;
+    g_mutex_unlock(dself->device_mutex);
 
     /* set the blocksize in the header properly */
     header->blocksize = dself->block_size;
@@ -751,7 +766,9 @@ ndmp_device_start_file(
     amfree(header_buf);
 
     /* arrange the file numbers correctly */
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = TRUE;
+    g_mutex_unlock(dself->device_mutex);
     if (!ndmp_get_state(self)) {
        /* error already set by ndmp_get_state */
        return FALSE;
@@ -809,6 +826,9 @@ ndmp_device_write_block(
     }
 
     dself->block++;
+    g_mutex_lock(dself->device_mutex);
+    dself->bytes_written += size;
+    g_mutex_unlock(dself->device_mutex);
 
     if (replacement_buffer) g_free(replacement_buffer);
     return TRUE;
@@ -823,7 +843,9 @@ ndmp_device_finish_file(
     if (device_in_error(dself)) return FALSE;
 
     /* we're not in a file anymore */
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = FALSE;
+    g_mutex_unlock(dself->device_mutex);
 
     if (!single_ndmp_mtio(self, NDMP9_MTIO_EOF)) {
        /* error was set by single_ndmp_mtio */
@@ -911,9 +933,14 @@ incomplete_bsf:
     }
 
     /* fix up status */
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = TRUE;
+    g_mutex_unlock(dself->device_mutex);
     dself->file = file;
     dself->block = 0;
+    g_mutex_lock(dself->device_mutex);
+    dself->bytes_read = 0;
+    g_mutex_unlock(dself->device_mutex);
 
     /* now read the header */
     read_block_size = ndmp_device_read_size(self);
@@ -988,10 +1015,37 @@ ndmp_device_read_block (Device * dself, gpointer data, int *size_req) {
     }
 
     *size_req = (int)actual; /* cast is OK - requested size was < INT_MAX too */
+    g_mutex_lock(dself->device_mutex);
+    dself->bytes_read += actual;
+    g_mutex_unlock(dself->device_mutex);
 
     return *size_req;
 }
 
+static gboolean
+indirecttcp_listen(
+    NdmpDevice *self,
+    DirectTCPAddr **addrs)
+{
+    in_port_t port;
+
+    self->indirecttcp_sock = stream_server(AF_INET, &port, 0, STREAM_BUFSIZE, 0);
+    if (self->indirecttcp_sock < 0) {
+       device_set_error(DEVICE(self),
+           g_strdup_printf("Could not bind indirecttcp socket: %s", strerror(errno)),
+           DEVICE_STATUS_DEVICE_ERROR);
+       return FALSE;
+    }
+
+    /* An IndirectTCP address is 255.255.255.255:$port */
+    self->listen_addrs = *addrs = g_new0(DirectTCPAddr, 2);
+    addrs[0]->sin.sin_family = AF_INET;
+    addrs[0]->sin.sin_addr.s_addr = htonl(0xffffffff);
+    SU_SET_PORT(addrs[0], port);
+
+    return TRUE;
+}
+
 static gboolean
 listen_impl(
     Device *dself,
@@ -1010,6 +1064,8 @@ listen_impl(
        return FALSE;
     }
 
+    self->for_writing = for_writing;
+
     /* first, set the window to an empty span so that the mover doesn't start
      * reading or writing data immediately.  NDMJOB tends to reset the record
      * size periodically (in direct contradiction to the spec), so we reset it
@@ -1020,9 +1076,34 @@ listen_impl(
        return FALSE;
     }
 
-    if (!ndmp_connection_mover_set_window(self->ndmp, 0, 0)) {
-       set_error_from_ndmp(self);
-       return FALSE;
+    if (for_writing) {
+       /* if we're forcing indirecttcp, just do it */
+       if (self->indirect) {
+           return indirecttcp_listen(self, addrs);
+       }
+       if (!ndmp_connection_mover_set_window(self->ndmp, 0, 0)) {
+           /* NDMP4_ILLEGAL_ARGS_ERR means the NDMP server doesn't like a zero-byte
+            * mover window, so we'll ignore it */
+           if (ndmp_connection_err_code(self->ndmp) != NDMP4_ILLEGAL_ARGS_ERR) {
+               set_error_from_ndmp(self);
+               return FALSE;
+           }
+
+           g_debug("NDMP Device: cannot set zero-length mover window; "
+                   "falling back to IndirectTCP");
+           /* In this case, we need to set up IndirectTCP */
+           return indirecttcp_listen(self, addrs);
+       }
+    } else {
+       /* For reading, set the window to the second mover record, so that the
+        * mover will pause immediately when it wants to read the first mover
+        * record. */
+       if (!ndmp_connection_mover_set_window(self->ndmp,
+                                             dself->block_size,
+                                             dself->block_size)) {
+           set_error_from_ndmp(self);
+           return FALSE;
+       }
     }
 
     /* then tell it to start listening */
@@ -1034,7 +1115,6 @@ listen_impl(
        return FALSE;
     }
     self->listen_addrs = *addrs;
-    self->for_writing = for_writing;
 
     return TRUE;
 }
@@ -1106,35 +1186,175 @@ accept_impl(
            return FALSE;
        }
 
+       /* now we should expect a notice that the mover has paused */
+    } else {
+       /* when writing, the mover will pause as soon as the first byte comes
+         * in, so there's no need to do anything to trigger the pause.
+         *
+         * Well, sometimes it won't - specifically, when it does not allow a
+         * zero-byte mover window, which means we've set up IndirectTCP.  But in
+         * that case, there's nothing interesting to do here.*/
+    }
+
+    if (self->indirecttcp_sock == -1) {
+       /* NDMJOB sends NDMP9_MOVER_PAUSE_SEEK to indicate that it wants to write
+        * outside the window, while the standard specifies .._EOW, instead.  When
+        * reading to a connection, we get the appropriate .._SEEK.  It's easy
+        * enough to handle both. */
+
+       if (!ndmp_connection_wait_for_notify(self->ndmp,
+               NULL,
+               NULL,
+               &reason, &seek_position)) {
+           set_error_from_ndmp(self);
+           return FALSE;
+       }
+
+       if (reason != NDMP9_MOVER_PAUSE_SEEK && reason != NDMP9_MOVER_PAUSE_EOW) {
+           device_set_error(DEVICE(self),
+               g_strdup_printf("got NOTIFY_MOVER_PAUSED, but not because of EOW or SEEK"),
+               DEVICE_STATUS_DEVICE_ERROR);
+           return FALSE;
+       }
+    }
+
+    /* at this point, if we're doing directtcp, the mover is paused and ready
+     * to go, and the listen addrs are no longer required; if we're doing
+     * indirecttcp, then the other end may not even know of our listen_addrs
+     * yet, so we can't free them.
+     */
+
+    if (self->indirecttcp_sock == -1) {
+       g_free(self->listen_addrs);
+       self->listen_addrs = NULL;
+    }
+
+    if (self->for_writing)
+       mode = NDMP9_MOVER_MODE_READ;
+    else
+       mode = NDMP9_MOVER_MODE_WRITE;
+
+    /* set up the new directtcp connection */
+    if (self->directtcp_conn)
+       g_object_unref(self->directtcp_conn);
+    self->directtcp_conn =
+       directtcp_connection_ndmp_new(self->ndmp, mode);
+    *dtcpconn = DIRECTTCP_CONNECTION(self->directtcp_conn);
+
+    /* reference it for the caller */
+    g_object_ref(*dtcpconn);
+
+    return TRUE;
+}
+
+static int
+accept_with_cond_impl(
+    Device *dself,
+    DirectTCPConnection **dtcpconn,
+    GMutex *abort_mutex,
+    GCond *abort_cond)
+{
+    NdmpDevice *self = NDMP_DEVICE(dself);
+    ndmp9_mover_state state;
+    guint64 bytes_moved;
+    ndmp9_mover_mode mode;
+    ndmp9_mover_pause_reason reason;
+    guint64 seek_position;
+    int result;
+
+    if (device_in_error(self)) return 1;
+
+    g_assert(self->listen_addrs);
+
+    *dtcpconn = NULL;
+
+    if (!self->for_writing) {
+       /* when reading, we don't get any kind of notification that the
+        * connection has been established, but we can't call NDMP_MOVER_READ
+        * until the mover is active.  So we have to poll, waiting for ACTIVE.
+        * This is ugly. */
+       gulong backoff = G_USEC_PER_SEC/20; /* 5 msec */
+       while (1) {
+           if (!ndmp_connection_mover_get_state(self->ndmp,
+                   &state, &bytes_moved, NULL, NULL)) {
+               set_error_from_ndmp(self);
+               return 1;
+           }
+
+           if (state != NDMP9_MOVER_STATE_LISTEN)
+               break;
+
+           /* back off a little bit to give the other side time to breathe,
+            * but not more than one second */
+           g_usleep(backoff);
+           backoff *= 2;
+           if (backoff > G_USEC_PER_SEC)
+               backoff = G_USEC_PER_SEC;
+       }
+
+       /* double-check state */
+       if (state != NDMP9_MOVER_STATE_ACTIVE) {
+           device_set_error(DEVICE(self),
+               g_strdup("mover did not enter the ACTIVE state as expected"),
+               DEVICE_STATUS_DEVICE_ERROR);
+           return 1;
+       }
+
+       /* now, we need to get this into the PAUSED state, since right now we
+        * aren't allowed to perform any tape movement commands.  So we issue a
+        * MOVER_READ request for the whole darn image stream after setting the
+        * usual empty window. Note that this means the whole dump will be read
+        * in one MOVER_READ operation, even if it does not begin at the
+        * beginning of a part. */
+       if (!ndmp_connection_mover_read(self->ndmp, 0, G_MAXUINT64)) {
+           set_error_from_ndmp(self);
+           return 1;
+       }
+
        /* now we should expect a notice that the mover has paused */
     } else {
        /* when writing, the mover will pause as soon as the first byte comes
         * in, so there's no need to do anything to trigger the pause. */
     }
 
+    if (self->indirecttcp_sock == -1) {
+       /* NDMJOB sends NDMP9_MOVER_PAUSE_SEEK to indicate that it wants to
+        * write outside the window, while the standard specifies .._EOW,
+        * instead.  When reading to a connection, we get the appropriate
+        * .._SEEK.  It's easy enough to handle both. */
+       result = ndmp_connection_wait_for_notify_with_cond(self->ndmp,
+                       NULL,
+                       NULL,
+                       &reason, &seek_position,
+                       abort_mutex, abort_cond);
+
+       if (result == 1) {
+           set_error_from_ndmp(self);
+           return 1;
+       } else if (result == 2) {
+           return 2;
+       }
+
+       if (reason != NDMP9_MOVER_PAUSE_SEEK &&
+           reason != NDMP9_MOVER_PAUSE_EOW) {
+           device_set_error(DEVICE(self),
+           g_strdup_printf(
+               "got NOTIFY_MOVER_PAUSED, but not because of EOW or SEEK"),
+               DEVICE_STATUS_DEVICE_ERROR);
+           return FALSE;
+       }
+    }
+
     /* NDMJOB sends NDMP9_MOVER_PAUSE_SEEK to indicate that it wants to write
      * outside the window, while the standard specifies .._EOW, instead.  When
      * reading to a connection, we get the appropriate .._SEEK.  It's easy
      * enough to handle both. */
 
-    if (!ndmp_connection_wait_for_notify(self->ndmp,
-           NULL,
-           NULL,
-           &reason, &seek_position)) {
-       set_error_from_ndmp(self);
-       return FALSE;
-    }
-
-    if (reason != NDMP9_MOVER_PAUSE_SEEK && reason != NDMP9_MOVER_PAUSE_EOW) {
-       device_set_error(DEVICE(self),
-           g_strdup_printf("got NOTIFY_MOVER_PAUSED, but not because of EOW or SEEK"),
-           DEVICE_STATUS_DEVICE_ERROR);
-       return FALSE;
+    if (self->indirecttcp_sock == -1) {
+       g_free(self->listen_addrs);
+       self->listen_addrs = NULL;
     }
 
-    g_free(self->listen_addrs);
-    self->listen_addrs = NULL;
-
     if (self->for_writing)
        mode = NDMP9_MOVER_MODE_READ;
     else
@@ -1150,7 +1370,7 @@ accept_impl(
     /* reference it for the caller */
     g_object_ref(*dtcpconn);
 
-    return TRUE;
+    return 0;
 }
 
 static gboolean
@@ -1260,6 +1480,191 @@ connect_impl(
     return TRUE;
 }
 
+static gboolean
+connect_with_cond_impl(
+    Device *dself,
+    gboolean for_writing,
+    DirectTCPAddr *addrs,
+    DirectTCPConnection **dtcpconn,
+    GMutex *abort_mutex,
+    GCond *abort_cond)
+{
+    NdmpDevice *self = NDMP_DEVICE(dself);
+    ndmp9_mover_mode mode;
+    ndmp9_mover_pause_reason reason;
+    guint64 seek_position;
+    int result;
+
+    g_assert(!self->listen_addrs);
+
+    *dtcpconn = NULL;
+    self->for_writing = for_writing;
+
+    if (!open_tape_agent(self)) {
+       /* error message was set by open_tape_agent */
+       return 1;
+    }
+
+    /* first, set the window to an empty span so that the mover doesn't start
+     * reading or writing data immediately.  NDMJOB tends to reset the record
+     * size periodically (in direct contradiction to the spec), so we reset it
+     * here as well. */
+    if (!ndmp_connection_mover_set_record_size(self->ndmp,
+               DEVICE(self)->block_size)) {
+       set_error_from_ndmp(self);
+       return 1;
+    }
+
+    if (!ndmp_connection_mover_set_window(self->ndmp, 0, 0)) {
+       set_error_from_ndmp(self);
+       return 1;
+    }
+
+    if (self->for_writing)
+       mode = NDMP9_MOVER_MODE_READ;
+    else
+       mode = NDMP9_MOVER_MODE_WRITE;
+
+    if (!ndmp_connection_mover_connect(self->ndmp, mode, addrs)) {
+       set_error_from_ndmp(self);
+       return 1;
+    }
+
+    if (!self->for_writing) {
+       /* The agent is in the ACTIVE state, and will remain so until we tell
+        * it to do something else.  The thing we want to is for it to start
+        * reading data from the tape, which will immediately trigger an EOW or
+        * SEEK pause. */
+       if (!ndmp_connection_mover_read(self->ndmp, 0, G_MAXUINT64)) {
+           set_error_from_ndmp(self);
+           return 1;
+       }
+
+       /* now we should expect a notice that the mover has paused */
+    } else {
+       /* when writing, the mover will pause as soon as the first byte comes
+        * in, so there's no need to do anything to trigger the pause. */
+    }
+
+    /* NDMJOB sends NDMP9_MOVER_PAUSE_SEEK to indicate that it wants to write
+     * outside the window, while the standard specifies .._EOW, instead.  When
+     * reading to a connection, we get the appropriate .._SEEK.  It's easy
+     * enough to handle both. */
+
+    result = ndmp_connection_wait_for_notify_with_cond(self->ndmp,
+           NULL,
+           NULL,
+           &reason, &seek_position,
+           abort_mutex, abort_cond);
+
+    if (result == 1) {
+       set_error_from_ndmp(self);
+       return 1;
+    } else if (result == 2) {
+       return 2;
+    }
+
+    if (reason != NDMP9_MOVER_PAUSE_SEEK && reason != NDMP9_MOVER_PAUSE_EOW) {
+       device_set_error(DEVICE(self),
+           g_strdup_printf("got NOTIFY_MOVER_PAUSED, but not because of EOW or SEEK"),
+           DEVICE_STATUS_DEVICE_ERROR);
+       return 1;
+    }
+
+    if (self->listen_addrs) {
+       g_free(self->listen_addrs);
+       self->listen_addrs = NULL;
+    }
+
+    /* set up the new directtcp connection */
+    if (self->directtcp_conn)
+       g_object_unref(self->directtcp_conn);
+    self->directtcp_conn =
+       directtcp_connection_ndmp_new(self->ndmp, mode);
+    *dtcpconn = DIRECTTCP_CONNECTION(self->directtcp_conn);
+
+    /* reference it for the caller */
+    g_object_ref(*dtcpconn);
+
+    return 0;
+}
+
+static gboolean
+indirecttcp_start_writing(
+       NdmpDevice *self)
+{
+    DirectTCPAddr *real_addrs, *iter;
+    int conn_sock;
+
+    /* The current state is that the other end is trying to connect to
+     * indirecttcp_sock.  The mover remains IDLE, although its window is set
+     * correctly for the part we are about to write. */
+
+    g_debug("indirecttcp_start_writing, ready to accept");
+    conn_sock = accept(self->indirecttcp_sock, NULL, NULL);
+    if (conn_sock < 0) {
+       device_set_error(DEVICE(self),
+           g_strdup_printf("Could not accept indirecttcp socket: %s", strerror(errno)),
+           DEVICE_STATUS_DEVICE_ERROR);
+       return FALSE;
+    }
+    g_debug("indirecttcp_start_writing, accepted");
+
+    close(self->indirecttcp_sock);
+    self->indirecttcp_sock = -1;
+
+    /* tell mover to start listening */
+    g_assert(self->for_writing);
+    if (!ndmp_connection_mover_listen(self->ndmp,
+               NDMP4_MOVER_MODE_READ,
+               NDMP4_ADDR_TCP,
+               &real_addrs)) {
+       set_error_from_ndmp(self);
+       return FALSE;
+    }
+
+    /* format the addresses and send them down the socket */
+    for (iter = real_addrs; iter && SU_GET_FAMILY(iter) != 0; iter++) {
+       char inet[INET_ADDRSTRLEN];
+       const char *addr;
+       char *addrspec;
+
+       addr = inet_ntop(AF_INET, &iter->sin.sin_addr.s_addr, inet, 40);
+
+       addrspec = g_strdup_printf("%s:%d%s", addr, SU_GET_PORT(iter),
+               SU_GET_FAMILY(iter+1) !=0? " ":"");
+    g_debug("indirecttcp_start_writing, send %s", addrspec);
+       if (full_write(conn_sock, addrspec, strlen(addrspec)) < strlen(addrspec)) {
+           device_set_error(DEVICE(self),
+               g_strdup_printf("writing to indirecttcp socket: %s", strerror(errno)),
+               DEVICE_STATUS_DEVICE_ERROR);
+           return FALSE;
+       }
+    }
+
+    /* close the socket for good.  This ensures that the next call to
+     * write_from_connection_impl will not go through the mover setup process.
+     * */
+    if (close(conn_sock) < 0) {
+       device_set_error(DEVICE(self),
+           g_strdup_printf("closing indirecttcp socket: %s", strerror(errno)),
+           DEVICE_STATUS_DEVICE_ERROR);
+       return FALSE;
+    }
+    conn_sock = -1;
+
+    /* and free the listen_addrs, since we didn't free them in accept_impl */
+    if (self->listen_addrs) {
+       g_free(self->listen_addrs);
+       self->listen_addrs = NULL;
+    }
+
+    /* Now it's up to the remote end to connect to the mover and start sending
+     * data.  We won't get any notification when this happens, although we could
+     * in principle poll for such a thing. */
+    return TRUE;
+}
+
 static gboolean
 write_from_connection_impl(
     Device *dself,
@@ -1277,6 +1682,7 @@ write_from_connection_impl(
 
     if (device_in_error(self)) return FALSE;
 
+    g_debug("write_from_connection_impl");
     if (actual_size)
        *actual_size = 0;
 
@@ -1291,9 +1697,20 @@ write_from_connection_impl(
        return FALSE;
     }
 
-    /* the mover had best be PAUSED right now */
-    g_assert(mover_state == NDMP9_MOVER_STATE_PAUSED);
+    if (self->indirecttcp_sock != -1) {
+       /* If we're doing IndirectTCP, then we've deferred the whole
+        * mover_set_window mover_listen process.. until now.
+        * So the mover should be IDLE.
+        */
+       g_assert(mover_state == NDMP9_MOVER_STATE_IDLE);
+    } else {
+       /* the mover had best be PAUSED right now */
+       g_assert(mover_state == NDMP9_MOVER_STATE_PAUSED);
+    }
 
+    /* we want to set the window regardless of whether this is directtcp or
+     * indirecttcp
+     */
     if (!ndmp_connection_mover_set_window(self->ndmp,
                nconn->offset,
                size? size : G_MAXUINT64 - nconn->offset)) {
@@ -1301,9 +1718,16 @@ write_from_connection_impl(
        return FALSE;
     }
 
-    if (!ndmp_connection_mover_continue(self->ndmp)) {
-       set_error_from_ndmp(self);
-       return FALSE;
+    /* for DirectTCP, we just tell the mover to continue; IndirectTCP is more complicated. */
+    if (self->indirecttcp_sock != -1) {
+       if (!indirecttcp_start_writing(self)) {
+           return FALSE;
+       }
+    } else {
+       if (!ndmp_connection_mover_continue(self->ndmp)) {
+           set_error_from_ndmp(self);
+           return FALSE;
+       }
     }
 
     /* now wait for the mover to pause itself again, or halt on EOF or an error */
@@ -1407,6 +1831,9 @@ read_to_connection_impl(
 
     if (device_in_error(self)) return FALSE;
 
+    /* read_to_connection does not support IndirectTCP */
+    g_assert(self->indirecttcp_sock == -1);
+
     /* if this is false, then the caller did not use use_connection correctly */
     g_assert(nconn != NULL);
     g_assert(self->ndmp == nconn->ndmp);
@@ -1642,6 +2069,18 @@ ndmp_device_set_read_block_size_fn(Device *p_self, DevicePropertyBase *base G_GN
                                        val, surety, source);
 }
 
+static gboolean
+ndmp_device_set_indirect_fn(Device *dself,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source)
+{
+    NdmpDevice *self = NDMP_DEVICE(dself);
+
+    self->indirect = g_value_get_boolean(val);
+
+    return device_simple_property_set_fn(dself, base, val, surety, source);
+}
+
 static void
 ndmp_device_class_init(NdmpDeviceClass * c G_GNUC_UNUSED)
 {
@@ -1667,7 +2106,9 @@ ndmp_device_class_init(NdmpDeviceClass * c G_GNUC_UNUSED)
     device_class->directtcp_supported = TRUE;
     device_class->listen = listen_impl;
     device_class->accept = accept_impl;
+    device_class->accept_with_cond = accept_with_cond_impl;
     device_class->connect = connect_impl;
+    device_class->connect_with_cond = connect_with_cond_impl;
     device_class->write_from_connection = write_from_connection_impl;
     device_class->read_to_connection = read_to_connection_impl;
     device_class->use_connection = use_connection_impl;
@@ -1693,6 +2134,12 @@ ndmp_device_class_init(NdmpDeviceClass * c G_GNUC_UNUSED)
            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_MASK,
            device_simple_property_get_fn,
            ndmp_device_set_verbose_fn);
+
+    device_class_register_property(device_class, PROPERTY_INDIRECT,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_MASK,
+           device_simple_property_get_fn,
+           ndmp_device_set_indirect_fn);
+
     device_class_register_property(device_class, PROPERTY_READ_BLOCK_SIZE,
            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
            device_simple_property_get_fn,
@@ -1785,6 +2232,14 @@ ndmp_device_init(NdmpDevice *self)
     g_value_unset(&response);
     self->ndmp_auth = g_strdup("md5");
 
+    g_value_init(&response, G_TYPE_BOOLEAN);
+    g_value_set_boolean(&response, FALSE);
+    device_set_simple_property(dself, PROPERTY_INDIRECT,
+           &response, PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_DEFAULT);
+    g_value_unset(&response);
+    self->indirect = FALSE;
+
+    self->indirecttcp_sock = -1;
 }
 
 static GType
@@ -1844,6 +2299,10 @@ ndmp_device_register(void)
     device_property_fill_and_register(&device_property_ndmp_auth,
                                       G_TYPE_STRING, "ndmp_auth",
        "Authentication method for the NDMP agent - md5 (default), text, none, or void");
+    device_property_fill_and_register(&device_property_indirect,
+                                      G_TYPE_BOOLEAN, "indirect",
+       "Use Indirect TCP mode, even if the NDMP server supports "
+       "window length 0");
 }
 
 /*
index 3f1bf3473e07c30a59772b4da19cc08e9c59100b..d5f7106d7754653ef8d71d649215cebe5f1c72d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -50,7 +50,6 @@ struct _NullDevice {
 typedef struct _NullDeviceClass NullDeviceClass;
 struct _NullDeviceClass {
     DeviceClass __parent__;
-    gboolean in_file;
 };
 
 void null_device_register(void);
@@ -237,7 +236,9 @@ null_device_start (Device * pself, DeviceAccessMode mode,
     if (device_in_error(self)) return FALSE;
 
     pself->access_mode = mode;
+    g_mutex_lock(pself->device_mutex);
     pself->in_file = FALSE;
+    g_mutex_unlock(pself->device_mutex);
 
     if (mode == ACCESS_WRITE) {
         pself->volume_label = newstralloc(pself->volume_label, label);
@@ -266,7 +267,9 @@ static gboolean
 null_device_start_file(Device * d_self,
                    dumpfile_t * jobInfo G_GNUC_UNUSED)
 {
+    g_mutex_lock(d_self->device_mutex);
     d_self->in_file = TRUE;
+    g_mutex_unlock(d_self->device_mutex);
     d_self->is_eom = FALSE;
     d_self->block = 0;
     if (d_self->file <= 0)
@@ -294,6 +297,8 @@ static gboolean
 null_device_finish_file(Device * pself) {
     if (device_in_error(pself)) return FALSE;
 
+    g_mutex_lock(pself->device_mutex);
     pself->in_file = FALSE;
+    g_mutex_unlock(pself->device_mutex);
     return TRUE;
 }
index e438dd57791c40a660df06fdf3d79a4ba8efcc6d..c951724e51d2a2fb3ae8344a4f8b900ec8f81183 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index c2ea8f07a82af20ba2e2190da0ec4cd72f376a32..15b3440c1e8c66e5ffdb79cc70dfbed74015497c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index dda81fb1c9b3d9c12c0f75a1037ddc76ac287afb..fa174580e35c2b5b0834c7c761064c50e50a6e69 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -1222,7 +1222,9 @@ rait_device_start (Device * dself, DeviceAccessMode mode, char * label,
        return FALSE;
 
     dself->access_mode = mode;
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = FALSE;
+    g_mutex_unlock(dself->device_mutex);
     amfree(dself->volume_label);
     amfree(dself->volume_time);
     dumpfile_free(dself->volume_header);
@@ -1404,9 +1406,12 @@ rait_device_start_file (Device * dself, dumpfile_t * info) {
         return FALSE;
     }
 
-    dself->in_file = TRUE;
     g_assert(actual_file >= 1);
     dself->file = actual_file;
+    g_mutex_lock(dself->device_mutex);
+    dself->in_file = TRUE;
+    dself->bytes_written = 0;
+    g_mutex_unlock(dself->device_mutex);
 
     return TRUE;
 }
@@ -1584,6 +1589,9 @@ rait_device_write_block (Device * dself, guint size, gpointer data) {
         return FALSE;
     } else {
         dself->block ++;
+       g_mutex_lock(dself->device_mutex);
+       dself->bytes_written += size;
+       g_mutex_unlock(dself->device_mutex);
 
         return TRUE;
     }
@@ -1626,7 +1634,9 @@ rait_device_finish_file (Device * dself) {
         return FALSE;
     }
 
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = FALSE;
+    g_mutex_unlock(dself->device_mutex);
     return TRUE;
 }
 
@@ -1655,9 +1665,12 @@ rait_device_seek_file (Device * dself, guint file) {
 
     if (rait_device_in_error(self)) return NULL;
 
-    dself->in_file = FALSE;
     dself->is_eof = FALSE;
     dself->block = 0;
+    g_mutex_lock(dself->device_mutex);
+    dself->in_file = FALSE;
+    dself->bytes_read = 0;
+    g_mutex_unlock(dself->device_mutex);
 
     ops = g_ptr_array_sized_new(self->private->children->len);
     for (i = 0; i < self->private->children->len; i ++) {
@@ -1722,7 +1735,9 @@ rait_device_seek_file (Device * dself, guint file) {
     }
 
     /* update our state */
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = in_file;
+    g_mutex_unlock(dself->device_mutex);
     dself->file = actual_file;
 
     return rval;
@@ -1990,7 +2005,9 @@ rait_device_read_block (Device * dself, gpointer buf, int * size) {
                stralloc(_("EOF")),
                DEVICE_STATUS_SUCCESS);
             dself->is_eof = TRUE;
+           g_mutex_lock(dself->device_mutex);
            dself->in_file = FALSE;
+           g_mutex_unlock(dself->device_mutex);
         } else {
            device_set_error(dself,
                stralloc(_("All child devices failed to read, but not all are at eof")),
@@ -2007,6 +2024,9 @@ rait_device_read_block (Device * dself, gpointer buf, int * size) {
     if (success) {
        dself->block++;
        *size = blocksize;
+       g_mutex_lock(dself->device_mutex);
+       dself->bytes_read += blocksize;
+       g_mutex_unlock(dself->device_mutex);
         return blocksize;
     } else {
         return -1;
index 7a987505c4e81ba70d40c8fb4f70d12aa13b97c3..8c545c33f5ddb22d6bf216a1d08008af61a37d08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -65,6 +65,7 @@ static GType  s3_device_get_type      (void);
  * Main object structure
  */
 typedef struct _S3MetadataFile S3MetadataFile;
+typedef struct _S3Device S3Device;
 
 typedef struct _S3_by_thread S3_by_thread;
 struct _S3_by_thread {
@@ -77,9 +78,10 @@ struct _S3_by_thread {
     char volatile * volatile     filename;
     DeviceStatusFlags volatile   errflags;     /* device_status */
     char volatile * volatile     errmsg;       /* device error message */
+    GMutex                     *now_mutex;
+    guint64                     dlnow, ulnow;
 };
 
-typedef struct _S3Device S3Device;
 struct _S3Device {
     Device __parent__;
 
@@ -99,11 +101,17 @@ struct _S3Device {
     char *swift_account_id;
     char *swift_access_key;
 
+    char *username;
+    char *password;
+    char *tenant_id;
+    char *tenant_name;
+
     char *bucket_location;
     char *storage_class;
     char *host;
     char *service_path;
     char *server_side_encryption;
+    char *proxy;
 
     char *ca_info;
 
@@ -118,9 +126,12 @@ struct _S3Device {
     /* Produce verbose output? */
     gboolean verbose;
 
+    /* create the bucket? */
+    gboolean create_bucket;
+
     /* Use SSL? */
     gboolean use_ssl;
-    gboolean openstack_swift_api;
+    S3_api s3_api;
 
     /* Throttling */
     guint64 max_send_speed;
@@ -131,6 +142,7 @@ struct _S3Device {
     guint64 volume_limit;
     gboolean enforce_volume_limit;
     gboolean use_subdomain;
+    gboolean use_s3_multi_delete;
 
     int          nb_threads;
     int          nb_threads_backup;
@@ -142,6 +154,17 @@ struct _S3Device {
     GMutex      *thread_idle_mutex;
     int          next_block_to_read;
     GSList      *keys;
+
+    guint64      dltotal;
+    guint64      ultotal;
+
+    /* google OAUTH2 */
+    char        *client_id;
+    char        *client_secret;
+    char        *refresh_token;
+    char        *project_id;
+
+    gboolean    reuse_connection;
 };
 
 /*
@@ -191,6 +214,16 @@ static DevicePropertyBase device_property_swift_access_key;
 #define PROPERTY_SWIFT_ACCOUNT_ID (device_property_swift_account_id.ID)
 #define PROPERTY_SWIFT_ACCESS_KEY (device_property_swift_access_key.ID)
 
+/* Authentication information for Openstack Swift. Both of these are strings. */
+static DevicePropertyBase device_property_username;
+static DevicePropertyBase device_property_password;
+static DevicePropertyBase device_property_tenant_id;
+static DevicePropertyBase device_property_tenant_name;
+#define PROPERTY_USERNAME (device_property_username.ID)
+#define PROPERTY_PASSWORD (device_property_password.ID)
+#define PROPERTY_TENANT_ID (device_property_tenant_id.ID)
+#define PROPERTY_TENANT_NAME (device_property_tenant_name.ID)
+
 /* Host and path */
 static DevicePropertyBase device_property_s3_host;
 static DevicePropertyBase device_property_s3_service_path;
@@ -209,15 +242,24 @@ static DevicePropertyBase device_property_s3_bucket_location;
 static DevicePropertyBase device_property_s3_storage_class;
 #define PROPERTY_S3_STORAGE_CLASS (device_property_s3_storage_class.ID)
 
-/* Storage class */
+/* Server side encryption */
 static DevicePropertyBase device_property_s3_server_side_encryption;
 #define PROPERTY_S3_SERVER_SIDE_ENCRYPTION (device_property_s3_server_side_encryption.ID)
 
+/* proxy */
+static DevicePropertyBase device_property_proxy;
+#define PROPERTY_PROXY (device_property_proxy.ID)
+
 /* Path to certificate authority certificate */
 static DevicePropertyBase device_property_ssl_ca_info;
 #define PROPERTY_SSL_CA_INFO (device_property_ssl_ca_info.ID)
 
+/* Which strotage api to use. */
+static DevicePropertyBase device_property_storage_api;
+#define PROPERTY_STORAGE_API (device_property_storage_api.ID)
+
 /* Whether to use openstack protocol. */
+/* DEPRECATED */
 static DevicePropertyBase device_property_openstack_swift_api;
 #define PROPERTY_OPENSTACK_SWIFT_API (device_property_openstack_swift_api.ID)
 
@@ -225,6 +267,10 @@ static DevicePropertyBase device_property_openstack_swift_api;
 static DevicePropertyBase device_property_s3_ssl;
 #define PROPERTY_S3_SSL (device_property_s3_ssl.ID)
 
+/* Whether to re-use connection. */
+static DevicePropertyBase device_property_reuse_connection;
+#define PROPERTY_REUSE_CONNECTION (device_property_reuse_connection.ID)
+
 /* Speed limits for sending and receiving */
 static DevicePropertyBase device_property_max_send_speed;
 static DevicePropertyBase device_property_max_recv_speed;
@@ -241,6 +287,30 @@ static DevicePropertyBase device_property_nb_threads_backup;
 static DevicePropertyBase device_property_nb_threads_recovery;
 #define PROPERTY_NB_THREADS_RECOVERY (device_property_nb_threads_recovery.ID)
 
+/* If the s3 server have the multi-delete functionality */
+static DevicePropertyBase device_property_s3_multi_delete;
+#define PROPERTY_S3_MULTI_DELETE (device_property_s3_multi_delete.ID)
+
+/* The client_id for OAUTH2 */
+static DevicePropertyBase device_property_client_id;
+#define PROPERTY_CLIENT_ID (device_property_client_id.ID)
+
+/* The client_secret for OAUTH2 */
+static DevicePropertyBase device_property_client_secret;
+#define PROPERTY_CLIENT_SECRET (device_property_client_secret.ID)
+
+/* The refresh token for OAUTH2 */
+static DevicePropertyBase device_property_refresh_token;
+#define PROPERTY_REFRESH_TOKEN (device_property_refresh_token.ID)
+
+/* The PROJECT ID */
+static DevicePropertyBase device_property_project_id;
+#define PROPERTY_PROJECT_ID (device_property_project_id.ID)
+
+/* The PROJECT ID */
+static DevicePropertyBase device_property_create_bucket;
+#define PROPERTY_CREATE_BUCKET (device_property_create_bucket.ID)
+
 /*
  * prototypes
  */
@@ -365,6 +435,22 @@ static gboolean s3_device_set_swift_access_key_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
 
+static gboolean s3_device_set_username(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
+static gboolean s3_device_set_password(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
+static gboolean s3_device_set_tenant_id(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
+static gboolean s3_device_set_tenant_name(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
 static gboolean s3_device_set_user_token_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
@@ -381,6 +467,10 @@ static gboolean s3_device_set_server_side_encryption_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
 
+static gboolean s3_device_set_proxy_fn(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
 static gboolean s3_device_set_ca_info_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
@@ -389,14 +479,30 @@ static gboolean s3_device_set_verbose_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
 
+static gboolean s3_device_set_create_bucket_fn(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
+static gboolean s3_device_set_storage_api(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
 static gboolean s3_device_set_openstack_swift_api_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
 
+static gboolean s3_device_set_s3_multi_delete_fn(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
 static gboolean s3_device_set_ssl_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
 
+static gboolean s3_device_set_reuse_connection_fn(Device *self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
 static gboolean s3_device_set_max_send_speed_fn(Device *self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
@@ -437,6 +543,22 @@ static gboolean s3_device_set_service_path_fn(Device *p_self,
     DevicePropertyBase *base, GValue *val,
     PropertySurety surety, PropertySource source);
 
+static gboolean s3_device_set_client_id_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
+static gboolean s3_device_set_client_secret_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
+static gboolean s3_device_set_refresh_token_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
+static gboolean s3_device_set_project_id_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source);
+
 static void s3_thread_read_block(gpointer thread_data,
                                 gpointer data);
 static void s3_thread_write_block(gpointer thread_data,
@@ -465,6 +587,12 @@ s3_device_start(Device * self,
 static gboolean
 s3_device_finish(Device * self);
 
+static guint64
+s3_device_get_bytes_read(Device * self);
+
+static guint64
+s3_device_get_bytes_written(Device * self);
+
 static gboolean
 s3_device_start_file(Device * self,
                      dumpfile_t * jobInfo);
@@ -732,19 +860,21 @@ delete_file(S3Device *self,
     guint64 total_size = 0;
     Device *d_self = DEVICE(self);
     char *my_prefix;
+
     if (file == -1) {
        my_prefix = g_strdup_printf("%sf", self->prefix);
     } else {
        my_prefix = g_strdup_printf("%sf%08x-", self->prefix, file);
     }
 
-    result = s3_list_keys(self->s3t[0].s3, self->bucket, my_prefix, NULL, &keys,
-                         &total_size);
+    result = s3_list_keys(self->s3t[0].s3, self->bucket, my_prefix, NULL,
+                         &keys, &total_size);
     if (!result) {
        device_set_error(d_self,
-           vstrallocf(_("While listing S3 keys: %s"), s3_strerror(self->s3t[0].s3)),
-           DEVICE_STATUS_DEVICE_ERROR | DEVICE_STATUS_VOLUME_ERROR);
-        return FALSE;
+               g_strdup_printf(_("While listing S3 keys: %s"),
+                   s3_strerror(self->s3t[0].s3)),
+               DEVICE_STATUS_DEVICE_ERROR | DEVICE_STATUS_VOLUME_ERROR);
+       return FALSE;
     }
 
     g_mutex_lock(self->thread_idle_mutex);
@@ -793,26 +923,70 @@ s3_thread_delete_block(
     S3_by_thread *s3t = (S3_by_thread *)thread_data;
     Device *pself = (Device *)data;
     S3Device *self = S3_DEVICE(pself);
-    gboolean result = 1;
+    int result = 1;
     char *filename;
 
     g_mutex_lock(self->thread_idle_mutex);
     while (result && self->keys) {
-       filename = self->keys->data;
-       self->keys = g_slist_remove(self->keys, self->keys->data);
-       count++;
-       if (count >= 1000) {
-           g_debug("Deleting %s ...", filename);
-           count = 0;
-       }
-       g_mutex_unlock(self->thread_idle_mutex);
-       result = s3_delete(s3t->s3, (const char *)self->bucket, (const char *)filename);
-       if (!result) {
-           s3t->errflags = DEVICE_STATUS_DEVICE_ERROR | DEVICE_STATUS_VOLUME_ERROR;
-           s3t->errmsg = g_strdup_printf(_("While deleting key '%s': %s"),
+       if (self->use_s3_multi_delete) {
+           char **filenames = g_new(char *, 1001);
+           char **f = filenames;
+           int  n = 0;
+           while (self->keys && n<1000) {
+               *f++ = self->keys->data;
+               self->keys = g_slist_remove(self->keys, self->keys->data);
+               n++;
+           }
+           *f++ = NULL;
+           g_mutex_unlock(self->thread_idle_mutex);
+           result = s3_multi_delete(s3t->s3, (const char *)self->bucket,
+                                             (const char **)filenames);
+           if (result != 1) {
+               char **f;
+
+               if (result == 2) {
+                   g_debug("Deleting multiple keys not implemented");
+               } else { /* result == 0 */
+                   g_debug("Deleteing multiple keys failed: %s",
+                           s3_strerror(s3t->s3));
+               }
+
+               self->use_s3_multi_delete = 0;
+               /* re-add all filenames */
+               f = filenames;
+               g_mutex_lock(self->thread_idle_mutex);
+               while(*f) {
+                   self->keys = g_slist_prepend(self->keys, *f++);
+               }
+               g_mutex_unlock(self->thread_idle_mutex);
+               g_free(filenames);
+               result = 1;
+               g_mutex_lock(self->thread_idle_mutex);
+               continue;
+           }
+           f = filenames;
+           while(*f) {
+               g_free(*f++);
+           }
+           g_free(filenames);
+       } else {
+           filename = self->keys->data;
+           self->keys = g_slist_remove(self->keys, self->keys->data);
+           count++;
+           if (count >= 1000) {
+               g_debug("Deleting %s ...", filename);
+               count = 0;
+           }
+           g_mutex_unlock(self->thread_idle_mutex);
+           result = s3_delete(s3t->s3, (const char *)self->bucket,
+                                       (const char *)filename);
+           if (!result) {
+               s3t->errflags = DEVICE_STATUS_DEVICE_ERROR | DEVICE_STATUS_VOLUME_ERROR;
+               s3t->errmsg = g_strdup_printf(_("While deleting key '%s': %s"),
                                          filename, s3_strerror(s3t->s3));
+           }
+           g_free(filename);
        }
-       g_free(filename);
        g_mutex_lock(self->thread_idle_mutex);
     }
     s3t->idle = 1;
@@ -880,6 +1054,18 @@ s3_device_register(void)
     device_property_fill_and_register(&device_property_swift_access_key,
                                       G_TYPE_STRING, "swift_access_key",
        "Access key to authenticate with openstack swift");
+    device_property_fill_and_register(&device_property_username,
+                                      G_TYPE_STRING, "username",
+       "Username to authenticate with");
+    device_property_fill_and_register(&device_property_password,
+                                      G_TYPE_STRING, "password",
+       "password to authenticate with");
+    device_property_fill_and_register(&device_property_tenant_id,
+                                      G_TYPE_STRING, "tenant_id",
+       "tenant_id to authenticate with");
+    device_property_fill_and_register(&device_property_tenant_name,
+                                      G_TYPE_STRING, "tenant_name",
+       "tenant_name to authenticate with");
     device_property_fill_and_register(&device_property_s3_host,
                                       G_TYPE_STRING, "s3_host",
        "hostname:port of the server");
@@ -898,15 +1084,39 @@ s3_device_register(void)
     device_property_fill_and_register(&device_property_s3_server_side_encryption,
                                       G_TYPE_STRING, "s3_server_side_encryption",
        "Serve side encryption as specified by Amazon (AES256)");
+    device_property_fill_and_register(&device_property_proxy,
+                                      G_TYPE_STRING, "proxy",
+       "The proxy");
     device_property_fill_and_register(&device_property_ssl_ca_info,
                                       G_TYPE_STRING, "ssl_ca_info",
        "Path to certificate authority certificate");
+    device_property_fill_and_register(&device_property_storage_api,
+                                      G_TYPE_STRING, "storage_api",
+       "Which cloud API to use.");
     device_property_fill_and_register(&device_property_openstack_swift_api,
-                                      G_TYPE_BOOLEAN, "openstack_swift_api",
+                                      G_TYPE_STRING, "openstack_swift_api",
        "Whether to use openstack protocol");
+    device_property_fill_and_register(&device_property_client_id,
+                                      G_TYPE_STRING, "client_id",
+       "client_id for use with oauth2");
+    device_property_fill_and_register(&device_property_client_secret,
+                                      G_TYPE_STRING, "client_secret",
+       "client_secret for use with oauth2");
+    device_property_fill_and_register(&device_property_refresh_token,
+                                      G_TYPE_STRING, "refresh_token",
+       "refresh_token for use with oauth2");
+    device_property_fill_and_register(&device_property_project_id,
+                                      G_TYPE_STRING, "project_id",
+       "project id for use with google");
     device_property_fill_and_register(&device_property_s3_ssl,
                                       G_TYPE_BOOLEAN, "s3_ssl",
        "Whether to use SSL with Amazon S3");
+    device_property_fill_and_register(&device_property_reuse_connection,
+                                      G_TYPE_BOOLEAN, "reuse_connection",
+       "Whether to reuse connection");
+    device_property_fill_and_register(&device_property_create_bucket,
+                                      G_TYPE_BOOLEAN, "create_bucket",
+       "Whether to create/delete bucket");
     device_property_fill_and_register(&device_property_s3_subdomain,
                                       G_TYPE_BOOLEAN, "s3_subdomain",
        "Whether to use subdomain");
@@ -922,6 +1132,9 @@ s3_device_register(void)
     device_property_fill_and_register(&device_property_nb_threads_recovery,
                                       G_TYPE_UINT64, "nb_threads_recovery",
        "Number of reader thread");
+    device_property_fill_and_register(&device_property_s3_multi_delete,
+                                      G_TYPE_BOOLEAN, "s3_multi_delete",
+       "Whether to use multi-delete");
 
     /* register the device itself */
     register_device(s3_device_factory, device_prefix_list);
@@ -959,6 +1172,7 @@ s3_device_init(S3Device * self)
     Device * dself = DEVICE(self);
     GValue response;
 
+    self->s3_api = S3_API_S3;
     self->volume_bytes = 0;
     self->volume_limit = 0;
     self->leom = TRUE;
@@ -972,6 +1186,7 @@ s3_device_init(S3Device * self)
     self->thread_pool_read = NULL;
     self->thread_idle_cond = NULL;
     self->thread_idle_mutex = NULL;
+    self->use_s3_multi_delete = 1;
 
     /* Register property values
      * Note: Some aren't added until s3_device_open_device()
@@ -1052,6 +1267,8 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED)
     device_class->read_label = s3_device_read_label;
     device_class->start = s3_device_start;
     device_class->finish = s3_device_finish;
+    device_class->get_bytes_read = s3_device_get_bytes_read;
+    device_class->get_bytes_written = s3_device_get_bytes_written;
 
     device_class->start_file = s3_device_start_file;
     device_class->write_block = s3_device_write_block;
@@ -1086,6 +1303,26 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED)
            device_simple_property_get_fn,
            s3_device_set_swift_access_key_fn);
 
+    device_class_register_property(device_class, PROPERTY_USERNAME,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_username);
+
+    device_class_register_property(device_class, PROPERTY_PASSWORD,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_password);
+
+    device_class_register_property(device_class, PROPERTY_TENANT_ID,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_tenant_id);
+
+    device_class_register_property(device_class, PROPERTY_TENANT_NAME,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_tenant_name);
+
     device_class_register_property(device_class, PROPERTY_S3_HOST,
            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
            device_simple_property_get_fn,
@@ -1116,6 +1353,11 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED)
            device_simple_property_get_fn,
            s3_device_set_server_side_encryption_fn);
 
+    device_class_register_property(device_class, PROPERTY_PROXY,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_proxy_fn);
+
     device_class_register_property(device_class, PROPERTY_SSL_CA_INFO,
            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
            device_simple_property_get_fn,
@@ -1126,16 +1368,36 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED)
            device_simple_property_get_fn,
            s3_device_set_verbose_fn);
 
+    device_class_register_property(device_class, PROPERTY_CREATE_BUCKET,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_create_bucket_fn);
+
+    device_class_register_property(device_class, PROPERTY_STORAGE_API,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_storage_api);
+
     device_class_register_property(device_class, PROPERTY_OPENSTACK_SWIFT_API,
            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
            device_simple_property_get_fn,
            s3_device_set_openstack_swift_api_fn);
 
+    device_class_register_property(device_class, PROPERTY_S3_MULTI_DELETE,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_s3_multi_delete_fn);
+
     device_class_register_property(device_class, PROPERTY_S3_SSL,
            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
            device_simple_property_get_fn,
            s3_device_set_ssl_fn);
 
+    device_class_register_property(device_class, PROPERTY_REUSE_CONNECTION,
+           PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+           device_simple_property_get_fn,
+           s3_device_set_reuse_connection_fn);
+
     device_class_register_property(device_class, PROPERTY_MAX_SEND_SPEED,
            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
            device_simple_property_get_fn,
@@ -1179,10 +1441,29 @@ s3_device_class_init(S3DeviceClass * c G_GNUC_UNUSED)
             s3_device_set_enforce_max_volume_usage_fn);
 
     device_class_register_property(device_class, PROPERTY_S3_SUBDOMAIN,
-            (PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_MASK) &
-                (~ PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE),
+            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
             device_simple_property_get_fn,
             s3_device_set_use_subdomain_fn);
+
+    device_class_register_property(device_class, PROPERTY_CLIENT_ID,
+            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+            device_simple_property_get_fn,
+            s3_device_set_client_id_fn);
+
+    device_class_register_property(device_class, PROPERTY_CLIENT_SECRET,
+            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+            device_simple_property_get_fn,
+            s3_device_set_client_secret_fn);
+
+    device_class_register_property(device_class, PROPERTY_REFRESH_TOKEN,
+            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+            device_simple_property_get_fn,
+            s3_device_set_refresh_token_fn);
+
+    device_class_register_property(device_class, PROPERTY_PROJECT_ID,
+            PROPERTY_ACCESS_GET_MASK | PROPERTY_ACCESS_SET_BEFORE_START,
+            device_simple_property_get_fn,
+            s3_device_set_project_id_fn);
 }
 
 static gboolean
@@ -1237,6 +1518,58 @@ s3_device_set_swift_access_key_fn(Device *p_self, DevicePropertyBase *base,
     return device_simple_property_set_fn(p_self, base, val, surety, source);
 }
 
+static gboolean
+s3_device_set_username(Device *p_self, DevicePropertyBase *base,
+    GValue *val, PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    amfree(self->username);
+    self->username = g_value_dup_string(val);
+    device_clear_volume_details(p_self);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
+static gboolean
+s3_device_set_password(Device *p_self, DevicePropertyBase *base,
+    GValue *val, PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    amfree(self->password);
+    self->password = g_value_dup_string(val);
+    device_clear_volume_details(p_self);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
+static gboolean
+s3_device_set_tenant_id(Device *p_self, DevicePropertyBase *base,
+    GValue *val, PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    amfree(self->tenant_id);
+    self->tenant_id = g_value_dup_string(val);
+    device_clear_volume_details(p_self);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
+static gboolean
+s3_device_set_tenant_name(Device *p_self, DevicePropertyBase *base,
+    GValue *val, PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    amfree(self->tenant_name);
+    self->tenant_name = g_value_dup_string(val);
+    device_clear_volume_details(p_self);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
 static gboolean
 s3_device_set_host_fn(Device *p_self,
     DevicePropertyBase *base, GValue *val,
@@ -1340,6 +1673,20 @@ s3_device_set_server_side_encryption_fn(Device *p_self, DevicePropertyBase *base
     return device_simple_property_set_fn(p_self, base, val, surety, source);
 }
 
+static gboolean
+s3_device_set_proxy_fn(Device *p_self, DevicePropertyBase *base,
+    GValue *val, PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+    char *str_val = g_value_dup_string(val);
+
+    amfree(self->proxy);
+    self->proxy = str_val;
+    device_clear_volume_details(p_self);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
 static gboolean
 s3_device_set_ca_info_fn(Device *p_self, DevicePropertyBase *base,
     GValue *val, PropertySurety surety, PropertySource source)
@@ -1373,13 +1720,73 @@ s3_device_set_verbose_fn(Device *p_self, DevicePropertyBase *base,
     return device_simple_property_set_fn(p_self, base, val, surety, source);
 }
 
+static gboolean
+s3_device_set_create_bucket_fn(Device *p_self, DevicePropertyBase *base,
+    GValue *val, PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+    int       thread;
+
+    self->create_bucket = g_value_get_boolean(val);
+    /* Our S3 handle may not yet have been instantiated; if so, it will
+     * get the proper verbose setting when it is created */
+    if (self->s3t) {
+       for (thread = 0; thread < self->nb_threads; thread++) {
+           if (self->s3t[thread].s3)
+               s3_verbose(self->s3t[thread].s3, self->verbose);
+       }
+    }
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
+static gboolean
+s3_device_set_storage_api(Device *p_self, DevicePropertyBase *base,
+    GValue *val, PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    const char *storage_api = g_value_get_string(val);
+    if (g_str_equal(storage_api, "S3")) {
+       self->s3_api = S3_API_S3;
+    } else if (g_str_equal(storage_api, "SWIFT-1.0")) {
+       self->s3_api = S3_API_SWIFT_1;
+    } else if (g_str_equal(storage_api, "SWIFT-2.0")) {
+       self->s3_api = S3_API_SWIFT_2;
+    } else if (g_str_equal(storage_api, "OAUTH2")) {
+       self->s3_api = S3_API_OAUTH2;
+    } else {
+       g_debug("Invalid STORAGE_API, using \"S3\".");
+       self->s3_api = S3_API_S3;
+    }
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
 static gboolean
 s3_device_set_openstack_swift_api_fn(Device *p_self, DevicePropertyBase *base,
     GValue *val, PropertySurety surety, PropertySource source)
 {
+
+    const gboolean openstack_swift_api = g_value_get_boolean(val);
+    if (openstack_swift_api) {
+       GValue storage_api_val;
+       g_value_init(&storage_api_val, G_TYPE_STRING);
+       g_value_set_static_string(&storage_api_val, "SWIFT-1.0");
+       return s3_device_set_storage_api(p_self, base, &storage_api_val,
+                                        surety, source);
+    }
+    return TRUE;
+}
+
+static gboolean
+s3_device_set_s3_multi_delete_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source)
+{
     S3Device *self = S3_DEVICE(p_self);
 
-    self->openstack_swift_api = g_value_get_boolean(val);
+    self->use_s3_multi_delete = g_value_get_boolean(val);
 
     return device_simple_property_set_fn(p_self, base, val, surety, source);
 }
@@ -1411,6 +1818,17 @@ s3_device_set_ssl_fn(Device *p_self, DevicePropertyBase *base,
     return device_simple_property_set_fn(p_self, base, val, surety, source);
 }
 
+static gboolean
+s3_device_set_reuse_connection_fn(Device *p_self, DevicePropertyBase *base,
+    GValue *val, PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    self->reuse_connection = g_value_get_boolean(val);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
 static gboolean
 s3_device_set_max_send_speed_fn(Device *p_self,
     DevicePropertyBase *base, GValue *val,
@@ -1545,6 +1963,59 @@ property_set_leom_fn(Device *p_self,
 
     return device_simple_property_set_fn(p_self, base, val, surety, source);
 }
+
+static gboolean
+s3_device_set_client_id_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    amfree(self->client_id);
+    self->client_id = g_value_dup_string(val);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
+static gboolean
+s3_device_set_client_secret_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    amfree(self->client_secret);
+    self->client_secret = g_value_dup_string(val);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
+static gboolean
+s3_device_set_refresh_token_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    amfree(self->refresh_token);
+    self->refresh_token = g_value_dup_string(val);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
+static gboolean
+s3_device_set_project_id_fn(Device *p_self,
+    DevicePropertyBase *base, GValue *val,
+    PropertySurety surety, PropertySource source)
+{
+    S3Device *self = S3_DEVICE(p_self);
+
+    amfree(self->project_id);
+    self->project_id = g_value_dup_string(val);
+
+    return device_simple_property_set_fn(p_self, base, val, surety, source);
+}
+
 static Device*
 s3_device_factory(char * device_name, char * device_type, char * device_node)
 {
@@ -1596,7 +2067,7 @@ s3_device_open_device(Device *pself, char *device_name,
 
     /* default values */
     self->verbose = FALSE;
-    self->openstack_swift_api = FALSE;
+    self->s3_api = S3_API_S3;
 
     /* use SSL if available */
     self->use_ssl = s3_curl_supports_ssl();
@@ -1606,6 +2077,22 @@ s3_device_open_device(Device *pself, char *device_name,
     device_set_simple_property(pself, device_property_s3_ssl.ID,
        &tmp_value, PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_DEFAULT);
 
+    /* reuse connection */
+    self->reuse_connection = TRUE;
+    bzero(&tmp_value, sizeof(GValue));
+    g_value_init(&tmp_value, G_TYPE_BOOLEAN);
+    g_value_set_boolean(&tmp_value, self->reuse_connection);
+    device_set_simple_property(pself, device_property_reuse_connection.ID,
+       &tmp_value, PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_DEFAULT);
+
+    /* Set default create_bucket */
+    self->create_bucket = TRUE;
+    bzero(&tmp_value, sizeof(GValue));
+    g_value_init(&tmp_value, G_TYPE_BOOLEAN);
+    g_value_set_boolean(&tmp_value, self->create_bucket);
+    device_set_simple_property(pself, device_property_create_bucket.ID,
+       &tmp_value, PROPERTY_SURETY_GOOD, PROPERTY_SOURCE_DEFAULT);
+
     if (parent_class->open_device) {
         parent_class->open_device(pself, device_name, device_type, device_node);
     }
@@ -1640,7 +2127,9 @@ static void s3_device_finalize(GObject * obj_self) {
     }
     if (self->s3t) {
        for (thread = 0; thread < self->nb_threads; thread++) {
+           g_mutex_free(self->s3t[thread].now_mutex);
             if(self->s3t[thread].s3) s3_free(self->s3t[thread].s3);
+           g_free(self->s3t[thread].curl_buffer.buffer);
        }
        g_free(self->s3t);
     }
@@ -1650,12 +2139,17 @@ static void s3_device_finalize(GObject * obj_self) {
     if(self->secret_key) g_free(self->secret_key);
     if(self->swift_account_id) g_free(self->swift_account_id);
     if(self->swift_access_key) g_free(self->swift_access_key);
+    if(self->username) g_free(self->username);
+    if(self->password) g_free(self->password);
+    if(self->tenant_id) g_free(self->tenant_id);
+    if(self->tenant_name) g_free(self->tenant_name);
     if(self->host) g_free(self->host);
     if(self->service_path) g_free(self->service_path);
     if(self->user_token) g_free(self->user_token);
     if(self->bucket_location) g_free(self->bucket_location);
     if(self->storage_class) g_free(self->storage_class);
     if(self->server_side_encryption) g_free(self->server_side_encryption);
+    if(self->proxy) g_free(self->proxy);
     if(self->ca_info) g_free(self->ca_info);
 }
 
@@ -1667,15 +2161,7 @@ static gboolean setup_handle(S3Device * self) {
     CURLcode curl_code;
 
     if (self->s3t == NULL) {
-       self->s3t = g_new(S3_by_thread, self->nb_threads);
-       if (self->s3t == NULL) {
-           device_set_error(d_self,
-               stralloc(_("Can't allocate S3Handle array")),
-               DEVICE_STATUS_DEVICE_ERROR);
-            return FALSE;
-       }
-
-       if (!self->openstack_swift_api) {
+       if (self->s3_api == S3_API_S3) {
            if (self->access_key == NULL || self->access_key[0] == '\0') {
                device_set_error(d_self,
                    g_strdup(_("No Amazon access key specified")),
@@ -1689,7 +2175,7 @@ static gboolean setup_handle(S3Device * self) {
                    DEVICE_STATUS_DEVICE_ERROR);
                return FALSE;
            }
-       } else {
+       } else if (self->s3_api == S3_API_SWIFT_1) {
            if (self->swift_account_id == NULL ||
                self->swift_account_id[0] == '\0') {
                device_set_error(d_self,
@@ -1704,10 +2190,53 @@ static gboolean setup_handle(S3Device * self) {
                    DEVICE_STATUS_DEVICE_ERROR);
                return FALSE;
            }
+       } else if (self->s3_api == S3_API_SWIFT_2) {
+           if (!((self->username && self->password && self->tenant_id) ||
+                 (self->username && self->password && self->tenant_name) ||
+                 (self->access_key && self->secret_key && self->tenant_id) ||
+                 (self->access_key && self->secret_key && self->tenant_name))) {
+               device_set_error(d_self,
+                   g_strdup(_("Missing authorization properties")),
+                   DEVICE_STATUS_DEVICE_ERROR);
+               return FALSE;
+           }
+       } else if (self->s3_api == S3_API_OAUTH2) {
+           if (self->client_id == NULL ||
+               self->client_id[0] == '\0') {
+               device_set_error(d_self,
+                   g_strdup(_("Missing client_id properties")),
+                   DEVICE_STATUS_DEVICE_ERROR);
+               return FALSE;
+           }
+           if (self->client_secret == NULL ||
+               self->client_secret[0] == '\0') {
+               device_set_error(d_self,
+                   g_strdup(_("Missing client_secret properties")),
+                   DEVICE_STATUS_DEVICE_ERROR);
+               return FALSE;
+           }
+           if (self->refresh_token == NULL ||
+               self->refresh_token[0] == '\0') {
+               device_set_error(d_self,
+                   g_strdup(_("Missing refresh_token properties")),
+                   DEVICE_STATUS_DEVICE_ERROR);
+               return FALSE;
+           }
+           if (self->project_id == NULL ||
+               self->project_id[0] == '\0') {
+               device_set_error(d_self,
+                   g_strdup(_("Missing project_id properties")),
+                   DEVICE_STATUS_DEVICE_ERROR);
+               return FALSE;
+           }
        }
 
-       if (!self->use_ssl && self->ca_info) {
-           amfree(self->ca_info);
+       self->s3t = g_new0(S3_by_thread, self->nb_threads);
+       if (self->s3t == NULL) {
+           device_set_error(d_self,
+               g_strdup(_("Can't allocate S3Handle array")),
+               DEVICE_STATUS_DEVICE_ERROR);
+            return FALSE;
        }
 
        self->thread_idle_cond = g_cond_new();
@@ -1722,6 +2251,7 @@ static gboolean setup_handle(S3Device * self) {
            self->s3t[thread].filename = NULL;
            self->s3t[thread].curl_buffer.buffer = NULL;
            self->s3t[thread].curl_buffer.buffer_len = 0;
+           self->s3t[thread].now_mutex = g_mutex_new();
             self->s3t[thread].s3 = s3_open(self->access_key, self->secret_key,
                                           self->swift_account_id,
                                           self->swift_access_key,
@@ -1730,24 +2260,22 @@ static gboolean setup_handle(S3Device * self) {
                                           self->user_token, self->bucket_location,
                                           self->storage_class, self->ca_info,
                                           self->server_side_encryption,
-                                          self->openstack_swift_api);
+                                          self->proxy,
+                                          self->s3_api,
+                                          self->username,
+                                          self->password,
+                                          self->tenant_id,
+                                          self->tenant_name,
+                                          self->client_id,
+                                          self->client_secret,
+                                          self->refresh_token,
+                                          self->reuse_connection);
             if (self->s3t[thread].s3 == NULL) {
                device_set_error(d_self,
                    stralloc(_("Internal error creating S3 handle")),
                    DEVICE_STATUS_DEVICE_ERROR);
                self->nb_threads = thread+1;
                 return FALSE;
-            } else if (self->openstack_swift_api) {
-               s3_error(self->s3t[0].s3, NULL, &response_code,
-                       &s3_error_code, NULL, &curl_code, NULL);
-               if (response_code != 200) {
-                   device_set_error(d_self,
-                       g_strdup_printf(_("Internal error creating S3 handle: %s"),
-                                       s3_strerror(self->s3t[0].s3)),
-                       DEVICE_STATUS_DEVICE_ERROR);
-                   self->nb_threads = thread+1;
-                   return FALSE;
-               }
            }
         }
 
@@ -1759,33 +2287,56 @@ static gboolean setup_handle(S3Device * self) {
                                              self->nb_threads, 0, NULL);
        self->thread_pool_read = g_thread_pool_new(s3_thread_read_block, self,
                                              self->nb_threads, 0, NULL);
-    }
 
-    for (thread = 0; thread < self->nb_threads; thread++) {
-       s3_verbose(self->s3t[thread].s3, self->verbose);
+       for (thread = 0; thread < self->nb_threads; thread++) {
+           s3_verbose(self->s3t[thread].s3, self->verbose);
 
-       if (!s3_use_ssl(self->s3t[thread].s3, self->use_ssl)) {
-           device_set_error(d_self, g_strdup_printf(_(
-                "Error setting S3 SSL/TLS use "
-                "(tried to enable SSL/TLS for S3, but curl doesn't support it?)")),
-               DEVICE_STATUS_DEVICE_ERROR);
-            return FALSE;
-       }
+           if (!s3_use_ssl(self->s3t[thread].s3, self->use_ssl)) {
+               device_set_error(d_self, g_strdup_printf(_(
+                       "Error setting S3 SSL/TLS use "
+                       "(tried to enable SSL/TLS for S3, but curl doesn't support it?)")),
+                       DEVICE_STATUS_DEVICE_ERROR);
+               return FALSE;
+           }
 
-       if (self->max_send_speed &&
-           !s3_set_max_send_speed(self->s3t[thread].s3, self->max_send_speed)) {
-           device_set_error(d_self,
-               g_strdup("Could not set S3 maximum send speed"),
-               DEVICE_STATUS_DEVICE_ERROR);
-            return FALSE;
+           if (self->max_send_speed &&
+               !s3_set_max_send_speed(self->s3t[thread].s3,
+                                      self->max_send_speed)) {
+               device_set_error(d_self,
+                       g_strdup("Could not set S3 maximum send speed"),
+                       DEVICE_STATUS_DEVICE_ERROR);
+               return FALSE;
+           }
+
+           if (self->max_recv_speed &&
+               !s3_set_max_recv_speed(self->s3t[thread].s3,
+                                      self->max_recv_speed)) {
+               device_set_error(d_self,
+                       g_strdup("Could not set S3 maximum recv speed"),
+                       DEVICE_STATUS_DEVICE_ERROR);
+               return FALSE;
+           }
        }
 
-       if (self->max_recv_speed &&
-           !s3_set_max_recv_speed(self->s3t[thread].s3, self->max_recv_speed)) {
-           device_set_error(d_self,
-               g_strdup("Could not set S3 maximum recv speed"),
-               DEVICE_STATUS_DEVICE_ERROR);
-            return FALSE;
+       for (thread = 0; thread < self->nb_threads; thread++) {
+           if (!s3_open2(self->s3t[thread].s3)) {
+               if (self->s3_api == S3_API_SWIFT_1 ||
+                   self->s3_api == S3_API_SWIFT_2) {
+                   s3_error(self->s3t[0].s3, NULL, &response_code,
+                            &s3_error_code, NULL, &curl_code, NULL);
+                   device_set_error(d_self,
+                           g_strdup_printf(_("s3_open2 failed: %s"),
+                                           s3_strerror(self->s3t[0].s3)),
+                           DEVICE_STATUS_DEVICE_ERROR);
+                   self->nb_threads = thread+1;
+                   return FALSE;
+               } else {
+                   device_set_error(d_self,
+                                    g_strdup("s3_open2 failed"),
+                                    DEVICE_STATUS_DEVICE_ERROR);
+                   return FALSE;
+               }
+           }
        }
     }
 
@@ -1801,7 +2352,7 @@ make_bucket(
     s3_error_code_t s3_error_code;
     CURLcode curl_code;
 
-    if (s3_is_bucket_exists(self->s3t[0].s3, self->bucket)) {
+    if (s3_is_bucket_exists(self->s3t[0].s3, self->bucket, self->project_id)) {
        return TRUE;
     }
 
@@ -1817,7 +2368,15 @@ make_bucket(
        return FALSE;
     }
 
-    if (!s3_make_bucket(self->s3t[0].s3, self->bucket)) {
+    if (!self->create_bucket) {
+       device_set_error(pself,
+           g_strdup_printf(_("Can't list bucket: %s"),
+                           s3_strerror(self->s3t[0].s3)),
+               DEVICE_STATUS_DEVICE_ERROR);
+       return FALSE;
+    }
+
+    if (!s3_make_bucket(self->s3t[0].s3, self->bucket, self->project_id)) {
         s3_error(self->s3t[0].s3, NULL, &response_code, &s3_error_code, NULL, NULL, NULL);
 
         /* if it isn't an expected error (bucket already exists),
@@ -1834,6 +2393,23 @@ make_bucket(
     return TRUE;
 }
 
+static int progress_func(
+    void *thread_data,
+    double dltotal G_GNUC_UNUSED,
+    double dlnow,
+    double ultotal G_GNUC_UNUSED,
+    double ulnow)
+{
+    S3_by_thread *s3t = (S3_by_thread *)thread_data;
+
+    g_mutex_lock(s3t->now_mutex);
+    s3t->dlnow = dlnow;
+    s3t->ulnow = ulnow;
+    g_mutex_unlock(s3t->now_mutex);
+
+    return 0;
+}
+
 static DeviceStatusFlags
 s3_device_read_label(Device *pself) {
     S3Device *self = S3_DEVICE(pself);
@@ -1936,7 +2512,9 @@ s3_device_start (Device * pself, DeviceAccessMode mode,
 
     reset_thread(self);
     pself->access_mode = mode;
+    g_mutex_lock(pself->device_mutex);
     pself->in_file = FALSE;
+    g_mutex_unlock(pself->device_mutex);
 
     /* try creating the bucket, in case it doesn't exist */
     if (!make_bucket(pself)) {
@@ -1953,7 +2531,9 @@ s3_device_start (Device * pself, DeviceAccessMode mode,
             break;
 
         case ACCESS_WRITE:
-            delete_all_files(self);
+            if (!delete_all_files(self)) {
+               return FALSE;
+           }
 
             /* write a new amanda header */
             if (!write_amanda_header(self, label, timestamp)) {
@@ -2011,6 +2591,54 @@ s3_device_finish (
 /* functions for writing */
 
 
+static guint64
+s3_device_get_bytes_read(
+    Device * pself)
+{
+    S3Device *self = S3_DEVICE(pself);
+    int       thread;
+    guint64   dltotal;
+
+    g_mutex_unlock(pself->device_mutex);
+    /* Add per thread */
+    g_mutex_lock(self->thread_idle_mutex);
+    dltotal = self->dltotal;
+    for (thread = 0; thread < self->nb_threads_recovery; thread++) {
+       g_mutex_lock(self->s3t[thread].now_mutex);
+       dltotal += self->s3t[thread].dlnow;
+       g_mutex_unlock(self->s3t[thread].now_mutex);
+    }
+    g_mutex_unlock(self->thread_idle_mutex);
+    g_mutex_lock(pself->device_mutex);
+
+    return dltotal;
+}
+
+
+static guint64
+s3_device_get_bytes_written(
+    Device * pself)
+{
+    S3Device *self = S3_DEVICE(pself);
+    int       thread;
+    guint64   ultotal;
+
+    g_mutex_unlock(pself->device_mutex);
+    /* Add per thread */
+    g_mutex_lock(self->thread_idle_mutex);
+    ultotal = self->ultotal;
+    for (thread = 0; thread < self->nb_threads_backup; thread++) {
+       g_mutex_lock(self->s3t[thread].now_mutex);
+       ultotal += self->s3t[thread].ulnow;
+       g_mutex_unlock(self->s3t[thread].now_mutex);
+    }
+    g_mutex_unlock(self->thread_idle_mutex);
+    g_mutex_lock(pself->device_mutex);
+
+    return ultotal;
+}
+
+
 static gboolean
 s3_device_start_file (Device *pself, dumpfile_t *jobInfo) {
     S3Device *self = S3_DEVICE(pself);
@@ -2052,10 +2680,22 @@ s3_device_start_file (Device *pself, dumpfile_t *jobInfo) {
         g_free(amanda_header.buffer);
         return FALSE;
     }
+
+    for (thread = 0; thread < self->nb_threads; thread++)  {
+       self->s3t[thread].idle = 1;
+       self->s3t[thread].ulnow = 0;
+    }
+
     /* set the file and block numbers correctly */
     pself->file = (pself->file > 0)? pself->file+1 : 1;
     pself->block = 0;
+    g_mutex_lock(pself->device_mutex);
     pself->in_file = TRUE;
+    pself->bytes_written = 0;
+    g_mutex_unlock(pself->device_mutex);
+    g_mutex_lock(self->thread_idle_mutex);
+    self->ultotal = 0;
+    g_mutex_unlock(self->thread_idle_mutex);
     /* write it out as a special block (not the 0th) */
     key = special_file_to_key(self, "filestart", pself->file);
     result = s3_upload(self->s3t[0].s3, self->bucket, key, S3_BUFFER_READ_FUNCS,
@@ -2070,9 +2710,6 @@ s3_device_start_file (Device *pself, dumpfile_t *jobInfo) {
     }
 
     self->volume_bytes += header_size;
-    for (thread = 0; thread < self->nb_threads; thread++)  {
-       self->s3t[thread].idle = 1;
-    }
 
     return TRUE;
 }
@@ -2167,7 +2804,8 @@ s3_thread_write_block(
     gboolean result;
 
     result = s3_upload(s3t->s3, self->bucket, (char *)s3t->filename,
-                      S3_BUFFER_READ_FUNCS, (CurlBuffer *)&s3t->curl_buffer, NULL, NULL);
+                      S3_BUFFER_READ_FUNCS, (CurlBuffer *)&s3t->curl_buffer,
+                      progress_func, s3t);
     g_free((void *)s3t->filename);
     s3t->filename = NULL;
     if (!result) {
@@ -2177,7 +2815,10 @@ s3_thread_write_block(
     g_mutex_lock(self->thread_idle_mutex);
     s3t->idle = 1;
     s3t->done = 1;
+    if (result)
+       self->ultotal += s3t->curl_buffer.buffer_len;
     s3t->curl_buffer.buffer_len = s3t->buffer_len;
+    s3t->ulnow = 0;
     g_cond_broadcast(self->thread_idle_cond);
     g_mutex_unlock(self->thread_idle_mutex);
 }
@@ -2209,12 +2850,16 @@ s3_device_finish_file (Device * pself) {
            g_cond_wait(self->thread_idle_cond, self->thread_idle_mutex);
        }
     }
+    self->ultotal = 0;
     g_mutex_unlock(self->thread_idle_mutex);
 
     if (device_in_error(pself)) return FALSE;
 
     /* we're not in a file anymore */
+    g_mutex_lock(pself->device_mutex);
     pself->in_file = FALSE;
+    pself->bytes_written = 0;;
+    g_mutex_unlock(pself->device_mutex);
 
     return TRUE;
 }
@@ -2264,7 +2909,8 @@ s3_device_erase(Device *pself) {
     device_set_error(pself, g_strdup("Unlabeled volume"),
                     DEVICE_STATUS_VOLUME_UNLABELED);
 
-    if (!s3_delete_bucket(self->s3t[0].s3, self->bucket)) {
+    if (self->create_bucket &&
+       !s3_delete_bucket(self->s3t[0].s3, self->bucket)) {
         s3_error(self->s3t[0].s3, NULL, &response_code, &s3_error_code, NULL, NULL, NULL);
 
         /*
@@ -2303,9 +2949,15 @@ s3_device_seek_file(Device *pself, guint file) {
 
     pself->file = file;
     pself->is_eof = FALSE;
-    pself->in_file = FALSE;
     pself->block = 0;
+    g_mutex_lock(pself->device_mutex);
+    pself->in_file = FALSE;
+    pself->bytes_read = 0;
+    g_mutex_unlock(pself->device_mutex);
     self->next_block_to_read = 0;
+    g_mutex_lock(self->thread_idle_mutex);
+    self->dltotal = 0;
+    g_mutex_unlock(self->thread_idle_mutex);
 
     /* read it in */
     key = special_file_to_key(self, "filestart", pself->file);
@@ -2374,11 +3026,14 @@ s3_device_seek_file(Device *pself, guint file) {
             return NULL;
     }
 
-    pself->in_file = TRUE;
     for (thread = 0; thread < self->nb_threads; thread++)  {
        self->s3t[thread].idle = 1;
        self->s3t[thread].eof = FALSE;
+       self->s3t[thread].ulnow = 0;
     }
+    g_mutex_lock(pself->device_mutex);
+    pself->in_file = TRUE;
+    g_mutex_unlock(pself->device_mutex);
     return amanda_header;
 }
 
@@ -2413,6 +3068,8 @@ s3_device_read_block (Device * pself, gpointer data, int *size_req) {
            s3t->done = 0;
            s3t->idle = 0;
            s3t->eof = FALSE;
+           s3t->dlnow = 0;
+           s3t->ulnow = 0;
            s3t->errflags = DEVICE_STATUS_SUCCESS;
            if (self->s3t[thread].curl_buffer.buffer &&
                (int)self->s3t[thread].curl_buffer.buffer_len < *size_req) {
@@ -2448,7 +3105,9 @@ s3_device_read_block (Device * pself, gpointer data, int *size_req) {
                    /* return eof */
                    g_free(key);
                    pself->is_eof = TRUE;
+                   g_mutex_lock(pself->device_mutex);
                    pself->in_file = FALSE;
+                   g_mutex_unlock(pself->device_mutex);
                    device_set_error(pself, stralloc(_("EOF")),
                                     DEVICE_STATUS_SUCCESS);
                    g_mutex_unlock(self->thread_idle_mutex);
@@ -2495,6 +3154,8 @@ s3_device_read_block (Device * pself, gpointer data, int *size_req) {
            s3t->done = 0;
            s3t->idle = 0;
            s3t->eof = FALSE;
+           s3t->dlnow = 0;
+           s3t->ulnow = 0;
            s3t->errflags = DEVICE_STATUS_SUCCESS;
            if (!self->s3t[thread].curl_buffer.buffer) {
                self->s3t[thread].curl_buffer.buffer = g_malloc(*size_req);
@@ -2521,8 +3182,9 @@ s3_thread_read_block(
     S3Device *self = S3_DEVICE(pself);
     gboolean result;
 
-    result = s3_read(s3t->s3, self->bucket, (char *)s3t->filename, s3_buffer_write_func,
-        s3_buffer_reset_func, (CurlBuffer *)&s3t->curl_buffer, NULL, NULL);
+    result = s3_read(s3t->s3, self->bucket, (char *)s3t->filename,
+       S3_BUFFER_WRITE_FUNCS,
+       (CurlBuffer *)&s3t->curl_buffer, progress_func, s3t);
 
     g_mutex_lock(self->thread_idle_mutex);
     if (!result) {
@@ -2543,7 +3205,11 @@ s3_thread_read_block(
            s3t->errmsg = g_strdup_printf(_("While reading data block from S3: %s"),
                                          s3_strerror(s3t->s3));
        }
+    } else {
+       self->dltotal += s3t->curl_buffer.buffer_len;
     }
+    s3t->dlnow = 0;
+    s3t->ulnow = 0;
     s3t->done = 1;
     g_cond_broadcast(self->thread_idle_cond);
     g_mutex_unlock(self->thread_idle_mutex);
@@ -2589,16 +3255,18 @@ reset_thread(
     int thread;
     int nb_done = 0;
 
-    g_mutex_lock(self->thread_idle_mutex);
-    while(nb_done != self->nb_threads) {
-       nb_done = 0;
-       for (thread = 0; thread < self->nb_threads; thread++)  {
-           if (self->s3t[thread].done == 1)
-               nb_done++;
-       }
-       if (nb_done != self->nb_threads) {
-           g_cond_wait(self->thread_idle_cond, self->thread_idle_mutex);
+    if (self->thread_idle_mutex) {
+       g_mutex_lock(self->thread_idle_mutex);
+       while(nb_done != self->nb_threads) {
+           nb_done = 0;
+           for (thread = 0; thread < self->nb_threads; thread++)  {
+               if (self->s3t[thread].done == 1)
+                   nb_done++;
+           }
+           if (nb_done != self->nb_threads) {
+               g_cond_wait(self->thread_idle_cond, self->thread_idle_mutex);
+           }
        }
+       g_mutex_unlock(self->thread_idle_mutex);
     }
-    g_mutex_unlock(self->thread_idle_mutex);
 }
index d1d7f21ab14fa2c9cc5b79da840a832492a9da12..a17a506c286b4abd33e11a679ea25d54bfe92790 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index f9285587a49f07bd5599dc9079ec4c58f0889ff8..5f20b88afd3292a3be615d20c50e851dfe2367ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 1c6129156a74c74c66ff2e625bb761e7f8824882..a3c030b58d52c746d3868b3238754c1466fc28da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -139,15 +139,27 @@ struct S3Handle {
     char *user_token;
     char *swift_account_id;
     char *swift_access_key;
+    char *username;
+    char *password;
+    char *tenant_id;
+    char *tenant_name;
+    char *client_id;
+    char *client_secret;
+    char *refresh_token;
+    char *access_token;
+    time_t expires;
+    gboolean getting_oauth2_access_token;
+    gboolean getting_swift_2_token;
 
     /* attributes for new objects */
     char *bucket_location;
     char *storage_class;
     char *server_side_encryption;
+    char *proxy;
     char *host;
     char *service_path;
     gboolean use_subdomain;
-    gboolean openstack_swift_api;
+    S3_api s3_api;
     char *ca_info;
     char *x_auth_token;
     char *x_storage_url;
@@ -171,6 +183,9 @@ struct S3Handle {
 
     /* offset with s3 */
     time_t time_offset_with_s3;
+    char *content_type;
+
+    gboolean reuse_connection;
 };
 
 typedef struct {
@@ -248,7 +263,8 @@ s3_error_name_from_code(s3_error_code_t s3_error_code);
 typedef enum {
     S3_RESULT_RETRY = -1,
     S3_RESULT_FAIL = 0,
-    S3_RESULT_OK = 1
+    S3_RESULT_OK = 1,
+    S3_RESULT_NOTIMPL = 2
 } s3_result_t;
 
 typedef struct result_handling {
@@ -258,6 +274,11 @@ typedef struct result_handling {
     s3_result_t result;
 } result_handling_t;
 
+/*
+ * get the access token for OAUTH2
+ */
+static gboolean oauth2_get_access_token(S3Handle *hdl);
+
 /* Lookup a result in C{result_handling}.
  *
  * @param result_handling: array of handling specifications
@@ -276,7 +297,8 @@ lookup_result(const result_handling_t *result_handling,
  * Precompiled regular expressions */
 static regex_t etag_regex, error_name_regex, message_regex, subdomain_regex,
     location_con_regex, date_sync_regex, x_auth_token_regex,
-    x_storage_url_regex;
+    x_storage_url_regex, access_token_regex, expires_in_regex,
+    content_type_regex, details_regex, code_regex;
 
 
 /*
@@ -335,7 +357,10 @@ authenticate_request(S3Handle *hdl,
                      const char *bucket,
                      const char *key,
                      const char *subresource,
-                     const char *md5_hash);
+                     const char *md5_hash,
+                     const char *content_type,
+                     const size_t content_length,
+                     const char *project_id);
 
 
 
@@ -401,6 +426,8 @@ perform_request(S3Handle *hdl,
                 const char *key,
                 const char *subresource,
                 const char *query,
+                const char *content_type,
+                const char *project_id,
                 s3_read_func read_func,
                 s3_reset_func read_reset_func,
                 s3_size_func size_func,
@@ -435,6 +462,9 @@ s3_internal_header_func(void *ptr, size_t size, size_t nmemb, void * stream);
 static gboolean
 compile_regexes(void);
 
+static gboolean get_openstack_swift_api_v1_setting(S3Handle *hdl);
+static gboolean get_openstack_swift_api_v2_setting(S3Handle *hdl);
+
 /*
  * Static function implementations
  */
@@ -520,6 +550,130 @@ lookup_result(const result_handling_t *result_handling,
     return result_handling->result;
 }
 
+static time_t
+rfc3339_date(
+    const char *date)
+{
+    gint year, month, day, hour, minute, seconds;
+    const char *atz;
+
+    if (strlen(date) < 19)
+       return 1073741824;
+
+    year = atoi(date);
+    month = atoi(date+5);
+    day = atoi(date+8);
+    hour = atoi(date+11);
+    minute = atoi(date+14);
+    seconds = atoi(date+17);
+    atz = date+19;
+    if (*atz == '.') {   /* skip decimal seconds */
+       atz++;
+       while (*atz >= '0' && *atz <= '9') {
+           atz++;
+       }
+    }
+
+#if GLIB_CHECK_VERSION(2,26,0)
+    if (!glib_check_version(2,26,0)) {
+       GTimeZone *tz;
+       GDateTime *dt;
+       time_t a;
+
+       tz = g_time_zone_new(atz);
+       dt = g_date_time_new(tz, year, month, day, hour, minute, seconds);
+       a = g_date_time_to_unix(dt);
+       g_time_zone_unref(tz);
+       g_date_time_unref(dt);
+       return a;
+    } else
+#endif
+    {
+       struct tm tm;
+       time_t t;
+
+       tm.tm_year = year - 1900;
+       tm.tm_mon = month - 1;
+       tm.tm_mday = day;
+       tm.tm_hour = hour;
+       tm.tm_min = minute;
+       tm.tm_sec = seconds;
+       tm.tm_wday = 0;
+       tm.tm_yday = 0;
+       tm.tm_isdst = -1;
+       t = time(NULL);
+
+       if (*atz == '-' || *atz == '+') {  /* numeric timezone */
+           time_t lt, gt;
+           time_t a;
+           struct tm ltt, gtt;
+           gint Hour = atoi(atz);
+           gint Min  = atoi(atz+4);
+
+           if (Hour < 0)
+               Min = -Min;
+           tm.tm_hour -= Hour;
+           tm.tm_min -= Min;
+           tm.tm_isdst = 0;
+           localtime_r(&t, &ltt);
+           lt = mktime(&ltt);
+           gmtime_r(&t, &gtt);
+           gt = mktime(&gtt);
+           tm.tm_sec += lt - gt;
+           a = mktime(&tm);
+           return a;
+       } else if (*atz == 'Z' && *(atz+1) == '\0') { /* Z timezone */
+           time_t lt, gt;
+           time_t a;
+           struct tm ltt, gtt;
+
+           tm.tm_isdst = 0;
+           localtime_r(&t, &ltt);
+           lt = mktime(&ltt);
+           gmtime_r(&t, &gtt);
+           gt = mktime(&gtt);
+           tm.tm_sec += lt - gt;
+           a = mktime(&tm);
+           return a;
+       } else { /* named timezone */
+           int pid;
+           int fd[2];
+           char buf[101];
+           time_t a;
+           size_t size;
+
+           if (pipe(fd) == -1)
+               return 1073741824;
+           pid = fork();
+           switch (pid) {
+               case -1:
+                   close(fd[0]);
+                   close(fd[1]);
+                   return 1073741824;
+                   break;
+               case 0:
+                   close(fd[0]);
+                   setenv("TZ", atz, 1);
+                   tzset();
+                   a = mktime(&tm);
+                   g_snprintf(buf, 100, "%d", (int)a);
+                   size = write(fd[1], buf, strlen(buf));
+                   close(fd[1]);
+                   exit(0);
+               default:
+                   close(fd[1]);
+                   size = read(fd[0], buf, 100);
+                   close(fd[0]);
+                   buf[size] = '\0';
+                   waitpid(pid, NULL, 0);
+                   break;
+           }
+           return atoi(buf);
+       }
+    }
+}
+
+
 static gboolean
 is_non_empty_string(const char *str)
 {
@@ -537,7 +691,9 @@ build_url(
     GString *url = NULL;
     char *esc_bucket = NULL, *esc_key = NULL;
 
-    if (hdl->openstack_swift_api && hdl->x_storage_url) {
+    if ((hdl->s3_api == S3_API_SWIFT_1 || hdl->s3_api == S3_API_SWIFT_2 ||
+        hdl->s3_api == S3_API_OAUTH2) &&
+        hdl->x_storage_url) {
        url = g_string_new(hdl->x_storage_url);
        g_string_append(url, "/");
     } else {
@@ -600,6 +756,10 @@ build_url(
        curl_free(esc_key);
     }
 
+    if (url->str[strlen(url->str)-1] == '/') {
+       g_string_truncate(url, strlen(url->str)-1);
+    }
+
     /* query string */
     if (subresource || query)
         g_string_append(url, "?");
@@ -624,7 +784,10 @@ authenticate_request(S3Handle *hdl,
                      const char *bucket,
                      const char *key,
                      const char *subresource,
-                     const char *md5_hash)
+                     const char *md5_hash,
+                     const char *content_type,
+                     const size_t content_length,
+                     const char *project_id)
 {
     time_t t;
     struct tm tmp;
@@ -642,7 +805,6 @@ authenticate_request(S3Handle *hdl,
     static const char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
 
-
     /* calculate the date */
     t = time(NULL);
 
@@ -660,7 +822,7 @@ authenticate_request(S3Handle *hdl,
         wkday[tmp.tm_wday], tmp.tm_mday, month[tmp.tm_mon], 1900+tmp.tm_year,
         tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
 
-    if (hdl->openstack_swift_api) {
+    if (hdl->s3_api == S3_API_SWIFT_1) {
        if (!bucket) {
             buf = g_strdup_printf("X-Auth-User: %s", hdl->swift_account_id);
             headers = curl_slist_append(headers, buf);
@@ -673,6 +835,21 @@ authenticate_request(S3Handle *hdl,
             headers = curl_slist_append(headers, buf);
             g_free(buf);
        }
+    } else if (hdl->s3_api == S3_API_SWIFT_2) {
+       if (bucket) {
+            buf = g_strdup_printf("X-Auth-Token: %s", hdl->x_auth_token);
+            headers = curl_slist_append(headers, buf);
+            g_free(buf);
+       }
+       buf = g_strdup_printf("Accept: %s", "application/xml");
+       headers = curl_slist_append(headers, buf);
+       g_free(buf);
+    } else if (hdl->s3_api == S3_API_OAUTH2) {
+       if (bucket) {
+            buf = g_strdup_printf("Authorization: Bearer %s", hdl->access_token);
+            headers = curl_slist_append(headers, buf);
+            g_free(buf);
+       }
     } else {
        /* Build the string to sign, per the S3 spec.
         * See: "Authenticating REST Requests" - API Version 2006-03-01 pg 58
@@ -687,7 +864,9 @@ authenticate_request(S3Handle *hdl,
             g_string_append(auth_string, md5_hash);
        g_string_append(auth_string, "\n");
 
-       /* Content-Type is empty*/
+       if (content_type) {
+           g_string_append(auth_string, content_type);
+       }
        g_string_append(auth_string, "\n");
 
        /* Date */
@@ -797,6 +976,29 @@ authenticate_request(S3Handle *hdl,
         headers = curl_slist_append(headers, buf);
         g_free(buf);
     }
+    if (content_length > 0) {
+        buf = g_strdup_printf("Content-Length: %zu", content_length);
+        headers = curl_slist_append(headers, buf);
+        g_free(buf);
+    }
+
+    if (content_type) {
+        buf = g_strdup_printf("Content-Type: %s", content_type);
+        headers = curl_slist_append(headers, buf);
+        g_free(buf);
+    }
+
+    if (hdl->s3_api == S3_API_OAUTH2) {
+        buf = g_strdup_printf("x-goog-api-version: 2");
+        headers = curl_slist_append(headers, buf);
+        g_free(buf);
+    }
+
+    if (project_id && hdl->s3_api == S3_API_OAUTH2) {
+        buf = g_strdup_printf("x-goog-project-id: %s", project_id);
+        headers = curl_slist_append(headers, buf);
+        g_free(buf);
+    }
 
     buf = g_strdup_printf("Date: %s", date);
     headers = curl_slist_append(headers, buf);
@@ -824,24 +1026,36 @@ struct failure_thunk {
     gboolean in_body;
     gboolean in_code;
     gboolean in_message;
+    gboolean in_details;
+    gboolean in_access;
+    gboolean in_token;
+    gboolean in_serviceCatalog;
+    gboolean in_service;
+    gboolean in_endpoint;
     gint     in_others;
 
     gchar *text;
     gsize text_len;
 
     gchar *message;
+    gchar *details;
     gchar *error_name;
+    gchar *token_id;
+    gchar *service_type;
+    gchar *service_public_url;
+    gint64 expires;
 };
 
 static void
 failure_start_element(GMarkupParseContext *context G_GNUC_UNUSED,
                    const gchar *element_name,
-                   const gchar **attribute_names G_GNUC_UNUSED,
-                   const gchar **attribute_values G_GNUC_UNUSED,
+                   const gchar **attribute_names,
+                   const gchar **attribute_values,
                    gpointer user_data,
                    GError **error G_GNUC_UNUSED)
 {
     struct failure_thunk *thunk = (struct failure_thunk *)user_data;
+    const gchar **att_name, **att_value;
 
     if (g_ascii_strcasecmp(element_name, "title") == 0) {
         thunk->in_title = 1;
@@ -859,6 +1073,60 @@ failure_start_element(GMarkupParseContext *context G_GNUC_UNUSED,
         thunk->in_message = 1;
        thunk->in_others = 0;
         thunk->want_text = 1;
+    } else if (g_ascii_strcasecmp(element_name, "details") == 0) {
+        thunk->in_details = 1;
+       thunk->in_others = 0;
+        thunk->want_text = 1;
+    } else if (g_ascii_strcasecmp(element_name, "access") == 0) {
+        thunk->in_access = 1;
+       thunk->in_others = 0;
+    } else if (g_ascii_strcasecmp(element_name, "token") == 0) {
+        thunk->in_token = 1;
+       thunk->in_others = 0;
+       for (att_name=attribute_names, att_value=attribute_values;
+            *att_name != NULL;
+            att_name++, att_value++) {
+           if (g_str_equal(*att_name, "id")) {
+               thunk->token_id = g_strdup(*att_value);
+           }
+           if (g_str_equal(*att_name, "expires") && strlen(*att_value) >= 19) {
+               thunk->expires = rfc3339_date(*att_value) - 600;
+           }
+       }
+    } else if (g_ascii_strcasecmp(element_name, "serviceCatalog") == 0) {
+        thunk->in_serviceCatalog = 1;
+       thunk->in_others = 0;
+    } else if (g_ascii_strcasecmp(element_name, "service") == 0) {
+        thunk->in_service = 1;
+       thunk->in_others = 0;
+       for (att_name=attribute_names, att_value=attribute_values;
+            *att_name != NULL;
+            att_name++, att_value++) {
+           if (g_str_equal(*att_name, "type")) {
+               thunk->service_type = g_strdup(*att_value);
+           }
+       }
+    } else if (g_ascii_strcasecmp(element_name, "endpoint") == 0) {
+        thunk->in_endpoint = 1;
+       thunk->in_others = 0;
+       if (thunk->service_type &&
+           g_str_equal(thunk->service_type, "object-store")) {
+           for (att_name=attribute_names, att_value=attribute_values;
+                *att_name != NULL;
+                att_name++, att_value++) {
+               if (g_str_equal(*att_name, "publicURL")) {
+                   thunk->service_public_url = g_strdup(*att_value);
+               }
+           }
+       }
+    } else if (g_ascii_strcasecmp(element_name, "error") == 0) {
+       for (att_name=attribute_names, att_value=attribute_values;
+            *att_name != NULL;
+            att_name++, att_value++) {
+           if (g_str_equal(*att_name, "message")) {
+               thunk->message = g_strdup(*att_value);
+           }
+       }
     } else {
        thunk->in_others++;
     }
@@ -896,6 +1164,32 @@ failure_end_element(GMarkupParseContext *context G_GNUC_UNUSED,
        thunk->message = thunk->text;
        thunk->text = NULL;
         thunk->in_message = 0;
+    } else if (g_ascii_strcasecmp(element_name, "details") == 0) {
+       thunk->details = thunk->text;
+       thunk->text = NULL;
+        thunk->in_details = 0;
+    } else if (g_ascii_strcasecmp(element_name, "access") == 0) {
+       thunk->message = thunk->text;
+       thunk->text = NULL;
+        thunk->in_access = 0;
+    } else if (g_ascii_strcasecmp(element_name, "token") == 0) {
+       thunk->message = thunk->text;
+       thunk->text = NULL;
+        thunk->in_token = 0;
+    } else if (g_ascii_strcasecmp(element_name, "serviceCatalog") == 0) {
+       thunk->message = thunk->text;
+       thunk->text = NULL;
+        thunk->in_serviceCatalog = 0;
+    } else if (g_ascii_strcasecmp(element_name, "service") == 0) {
+       thunk->message = thunk->text;
+       thunk->text = NULL;
+       g_free(thunk->service_type);
+       thunk->service_type = NULL;
+        thunk->in_service = 0;
+    } else if (g_ascii_strcasecmp(element_name, "endpoint") == 0) {
+       thunk->message = thunk->text;
+       thunk->text = NULL;
+        thunk->in_endpoint = 0;
     } else {
        thunk->in_others--;
     }
@@ -963,11 +1257,6 @@ interpret_response(S3Handle *hdl,
             ret = FALSE;
         return ret;
     }
-    if (200 <= response_code && response_code < 400) {
-        /* 2xx and 3xx codes won't have a response body we care about */
-        hdl->last_s3_error_code = S3_ERROR_None;
-        return FALSE;
-    }
 
     /* Now look at the body to try to get the actual Amazon error message. */
 
@@ -976,24 +1265,45 @@ interpret_response(S3Handle *hdl,
         hdl->last_message = g_strdup("S3 Error: Unknown (response body too large to parse)");
         return FALSE;
     } else if (!body || body_len == 0) {
-        hdl->last_message = g_strdup("S3 Error: Unknown (empty response body)");
-        return TRUE; /* perhaps a network error; retry the request */
+       if (response_code < 100 || response_code >= 400) {
+           hdl->last_message =
+                       g_strdup("S3 Error: Unknown (empty response body)");
+            return TRUE; /* perhaps a network error; retry the request */
+       } else {
+           /* 2xx and 3xx codes without body are good result */
+           hdl->last_s3_error_code = S3_ERROR_None;
+           return FALSE;
+       }
     }
 
     thunk.in_title = FALSE;
     thunk.in_body = FALSE;
     thunk.in_code = FALSE;
     thunk.in_message = FALSE;
+    thunk.in_details = FALSE;
+    thunk.in_access = FALSE;
+    thunk.in_token = FALSE;
+    thunk.in_serviceCatalog = FALSE;
+    thunk.in_service = FALSE;
+    thunk.in_endpoint = FALSE;
     thunk.in_others = 0;
     thunk.text = NULL;
     thunk.want_text = FALSE;
     thunk.text_len = 0;
     thunk.message = NULL;
+    thunk.details = NULL;
     thunk.error_name = NULL;
+    thunk.token_id = NULL;
+    thunk.service_type = NULL;
+    thunk.service_public_url = NULL;
+    thunk.expires = 0;
+
+    if ((hdl->s3_api == S3_API_SWIFT_1 ||
+         hdl->s3_api == S3_API_SWIFT_2) &&
+       hdl->content_type &&
+       (g_str_equal(hdl->content_type, "text/html") ||
+        g_str_equal(hdl->content_type, "text/plain"))) {
 
-    if (hdl->openstack_swift_api &&
-       !g_strstr_len(body, body_len, "xml version") &&
-       !g_strstr_len(body, body_len, "<html>")) {
        char *body_copy = g_strndup(body, body_len);
        char *b = body_copy;
        char *p = strchr(b, '\n');
@@ -1019,6 +1329,37 @@ interpret_response(S3Handle *hdl,
            b = p;
        }
        goto parsing_done;
+    } else if ((hdl->s3_api == S3_API_SWIFT_1 ||
+               hdl->s3_api == S3_API_SWIFT_2) &&
+              hdl->content_type &&
+              g_str_equal(hdl->content_type, "application/json")) {
+       char *body_copy = g_strndup(body, body_len);
+       char *code = NULL;
+       char *details = NULL;
+       regmatch_t pmatch[2];
+
+       if (!s3_regexec_wrap(&code_regex, body_copy, 2, pmatch, 0)) {
+            code = find_regex_substring(body_copy, pmatch[1]);
+       }
+       if (!s3_regexec_wrap(&details_regex, body_copy, 2, pmatch, 0)) {
+            details = find_regex_substring(body_copy, pmatch[1]);
+       }
+       if (code && details) {
+           hdl->last_message = g_strdup_printf("%s (%s)", details, code);
+       } else if (code) {
+           hdl->last_message = g_strdup_printf("(%s)", code);
+       } else if (details) {
+           hdl->last_message = g_strdup_printf("%s", details);
+       } else {
+           hdl->last_message = NULL;
+       }
+       g_free(code);
+       g_free(details);
+       g_free(body_copy);
+       return FALSE;
+    } else if (!hdl->content_type ||
+              !g_str_equal(hdl->content_type, "application/xml")) {
+       return FALSE;
     }
 
     /* run the parser over it */
@@ -1038,6 +1379,20 @@ interpret_response(S3Handle *hdl,
     g_markup_parse_context_free(ctxt);
     ctxt = NULL;
 
+    if (hdl->s3_api == S3_API_SWIFT_2) {
+       if (!hdl->x_auth_token && thunk.token_id) {
+           hdl->x_auth_token = thunk.token_id;
+           thunk.token_id = NULL;
+       }
+       if (!hdl->x_storage_url && thunk.service_public_url) {
+           hdl->x_storage_url = thunk.service_public_url;
+           thunk.service_public_url = NULL;
+       }
+    }
+
+    if (thunk.expires > 0) {
+       hdl->expires = thunk.expires;
+    }
 parsing_done:
     if (thunk.error_name) {
         hdl->last_s3_error_code = s3_error_code_from_name(thunk.error_name);
@@ -1047,14 +1402,24 @@ parsing_done:
 
     if (thunk.message) {
        g_free(hdl->last_message);
-        hdl->last_message = thunk.message;
-        thunk.message = NULL; /* steal the reference to the string */
+       if (thunk.details) {
+           hdl->last_message = g_strdup_printf("%s: %s", thunk.message,
+                                                         thunk.details);
+           amfree(thunk.message);
+           amfree(thunk.details);
+       } else {
+            hdl->last_message = thunk.message;
+            thunk.message = NULL; /* steal the reference to the string */
+       }
     }
 
 cleanup:
     g_free(thunk.text);
     g_free(thunk.message);
     g_free(thunk.error_name);
+    g_free(thunk.token_id);
+    g_free(thunk.service_public_url);
+    g_free(thunk.service_type);
     return FALSE;
 }
 
@@ -1251,6 +1616,7 @@ curl_debug_message(CURL *curl G_GNUC_UNUSED,
     char *lineprefix;
     char *message;
     char **lines, **line;
+    size_t i;
 
     switch (type) {
     case CURLINFO_TEXT:
@@ -1264,17 +1630,27 @@ curl_debug_message(CURL *curl G_GNUC_UNUSED,
     case CURLINFO_HEADER_OUT:
         lineprefix="Hdr Out: ";
         break;
-/*
+
     case CURLINFO_DATA_IN:
-       if (len > 1000) return 0;
+       if (len > 3000) return 0;
+       for (i=0;i<len;i++) {
+           if (!g_ascii_isprint(s[i])) {
+               return 0;
+           }
+       }
         lineprefix="Data In: ";
         break;
 
     case CURLINFO_DATA_OUT:
-       if (len > 1000) return 0;
+       if (len > 3000) return 0;
+       for (i=0;i<len;i++) {
+           if (!g_ascii_isprint(s[i])) {
+               return 0;
+           }
+       }
         lineprefix="Data Out: ";
         break;
-*/
+
     default:
         /* ignore data in/out -- nobody wants to see that in the
          * debug logs! */
@@ -1287,8 +1663,8 @@ curl_debug_message(CURL *curl G_GNUC_UNUSED,
     g_free(message);
 
     for (line = lines; *line; line++) {
-    if (**line == '\0') continue; /* skip blank lines */
-    g_debug("%s%s", lineprefix, *line);
+       if (**line == '\0') continue; /* skip blank lines */
+       g_debug("%s%s", lineprefix, *line);
     }
     g_strfreev(lines);
 
@@ -1302,6 +1678,8 @@ perform_request(S3Handle *hdl,
                 const char *key,
                 const char *subresource,
                 const char *query,
+                const char *content_type,
+                const char *project_id,
                 s3_read_func read_func,
                 s3_reset_func read_reset_func,
                 s3_size_func size_func,
@@ -1335,6 +1713,22 @@ perform_request(S3Handle *hdl,
 
     g_assert(hdl != NULL && hdl->curl != NULL);
 
+    if (hdl->s3_api == S3_API_OAUTH2 && !hdl->getting_oauth2_access_token &&
+       (!hdl->access_token || hdl->expires < time(NULL))) {
+       result = oauth2_get_access_token(hdl);
+       if (!result) {
+           g_debug("oauth2_get_access_token returned %d", result);
+           return result;
+       }
+    } else if (hdl->s3_api == S3_API_SWIFT_2 && !hdl->getting_swift_2_token &&
+              (!hdl->x_auth_token || hdl->expires < time(NULL))) {
+       result = get_openstack_swift_api_v2_setting(hdl);
+       if (!result) {
+           g_debug("get_openstack_swift_api_v2_setting returned %d", result);
+           return result;
+       }
+    }
+
     s3_reset(hdl);
 
     url = build_url(hdl, bucket, key, subresource, query);
@@ -1395,9 +1789,9 @@ perform_request(S3Handle *hdl,
 
         /* set up the request */
         headers = authenticate_request(hdl, verb, bucket, key, subresource,
-            md5_hash_b64);
+            md5_hash_b64, content_type, request_body_size, project_id);
 
-        if (hdl->use_ssl && hdl->ca_info) {
+        if (hdl->ca_info) {
             if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_CAINFO, hdl->ca_info)))
                 goto curl_error;
         }
@@ -1433,6 +1827,10 @@ perform_request(S3Handle *hdl,
             goto curl_error;
         if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_PROGRESSFUNCTION, progress_func)))
             goto curl_error;
+       if (progress_func) {
+           if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_NOPROGRESS,0)))
+               goto curl_error;
+       }
         if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_PROGRESSDATA, progress_data)))
             goto curl_error;
 
@@ -1444,6 +1842,15 @@ perform_request(S3Handle *hdl,
         if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_INFILESIZE, (long)request_body_size)))
             goto curl_error;
 #endif
+/* CURLOPT_POSTFIELDSIZE_LARGE added in 7.11.1 */
+#if LIBCURL_VERSION_NUM >= 0x070b01
+        if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)request_body_size)))
+            goto curl_error;
+#else
+        if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_POSTFIELDSIZE, (long)request_body_size)))
+            goto curl_error;
+#endif
+
 /* CURLOPT_MAX_{RECV,SEND}_SPEED_LARGE added in 7.15.5 */
 #if LIBCURL_VERSION_NUM >= 0x070f05
        if (s3_curl_throttling_compat()) {
@@ -1470,7 +1877,7 @@ perform_request(S3Handle *hdl,
             goto curl_error;
 
 
-        if (curlopt_upload) {
+        if (curlopt_upload || curlopt_post) {
             if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_READFUNCTION, read_func)))
                 goto curl_error;
             if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_READDATA, read_data)))
@@ -1484,6 +1891,20 @@ perform_request(S3Handle *hdl,
                                               NULL)))
                 goto curl_error;
         }
+       if (hdl->proxy) {
+            if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_PROXY,
+                                              hdl->proxy)))
+                goto curl_error;
+       }
+
+       if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_FRESH_CONNECT,
+               (long)(hdl->reuse_connection? 0 : 1)))) {
+           goto curl_error;
+       }
+       if ((curl_code = curl_easy_setopt(hdl->curl, CURLOPT_FORBID_REUSE,
+               (long)(hdl->reuse_connection? 0 : 1)))) {
+           goto curl_error;
+       }
 
         /* Perform the request */
         curl_code = curl_easy_perform(hdl->curl);
@@ -1494,6 +1915,11 @@ perform_request(S3Handle *hdl,
         should_retry = interpret_response(hdl, curl_code, curl_error_buffer,
             int_writedata.resp_buf.buffer, int_writedata.resp_buf.buffer_pos, int_writedata.etag, md5_hash_hex);
 
+       if (hdl->s3_api == S3_API_OAUTH2 &&
+           hdl->last_response_code == 401 &&
+           hdl->last_s3_error_code == S3_ERROR_AuthenticationRequired) {
+           should_retry = oauth2_get_access_token(hdl);
+       }
         /* and, unless we know we need to retry, see what we're to do now */
         if (!should_retry) {
             result = lookup_result(result_handling, hdl->last_response_code,
@@ -1603,6 +2029,9 @@ s3_internal_header_func(void *ptr, size_t size, size_t nmemb, void * stream)
     if (!s3_regexec_wrap(&x_storage_url_regex, header, 2, pmatch, 0))
        data->hdl->x_storage_url = find_regex_substring(header, pmatch[1]);
 
+    if (!s3_regexec_wrap(&content_type_regex, header, 2, pmatch, 0))
+       data->hdl->content_type = find_regex_substring(header, pmatch[1]);
+
     if (strlen(header) == 0)
        data->headers_done = TRUE;
     if (g_str_equal(final_header, header))
@@ -1646,10 +2075,15 @@ compile_regexes(void)
         {"^ETag:[[:space:]]*\"([^\"]+)\"[[:space:]]*$", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &etag_regex},
         {"^X-Auth-Token:[[:space:]]*([^ ]+)[[:space:]]*$", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &x_auth_token_regex},
         {"^X-Storage-Url:[[:space:]]*([^ ]+)[[:space:]]*$", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &x_storage_url_regex},
+        {"^Content-Type:[[:space:]]*([^ ;]+).*$", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &content_type_regex},
         {"<Message>[[:space:]]*([^<]*)[[:space:]]*</Message>", REG_EXTENDED | REG_ICASE, &message_regex},
         {"^[a-z0-9](-*[a-z0-9]){2,62}$", REG_EXTENDED | REG_NOSUB, &subdomain_regex},
         {"(/>)|(>([^<]*)</LocationConstraint>)", REG_EXTENDED | REG_ICASE, &location_con_regex},
         {"^Date:(.*)\r",REG_EXTENDED | REG_ICASE | REG_NEWLINE, &date_sync_regex},
+        {"\"access_token\" : \"([^\"]*)\",", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &access_token_regex},
+       {"\"expires_in\" : (.*)", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &expires_in_regex},
+        {"\"details\": \"([^\"]*)\",", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &details_regex},
+        {"\"code\": (.*),", REG_EXTENDED | REG_ICASE | REG_NEWLINE, &code_regex},
         {NULL, 0, NULL}
     };
     char regmessage[1024];
@@ -1673,6 +2107,15 @@ compile_regexes(void)
         {"^ETag:\\s*\"([^\"]+)\"\\s*$",
          G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
          &etag_regex},
+        {"^X-Auth-Token:\\s*([^ ]+)\\s*$",
+         G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
+         &x_auth_token_regex},
+        {"^X-Storage-Url:\\s*([^ ]+)\\s*$",
+         G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
+         &x_storage_url_regex},
+        {"^Content-Type:\\s*([^ ]+)\\s*$",
+         G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
+         &content_type_regex},
         {"<Message>\\s*([^<]*)\\s*</Message>",
          G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
          &message_regex},
@@ -1685,6 +2128,18 @@ compile_regexes(void)
         {"^Date:(.*)\\r",
          G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
          &date_sync_regex},
+        {"\"access_token\" : \"([^\"]*)\"",
+         G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
+         &access_token_regex},
+        {"\"expires_n\" : (.*)",
+         G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
+         &expires_in_regex},
+        {"\"details\" : \"([^\"]*)\"",
+        G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
+        &details_regex},
+        {"\"code\" : (.*)",
+        G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
+        &code_regex},
         {NULL, 0, NULL}
   };
   int i;
@@ -1706,6 +2161,10 @@ compile_regexes(void)
  * Public function implementations
  */
 
+#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31))
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
 gboolean s3_init(void)
 {
     static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
@@ -1721,6 +2180,9 @@ gboolean s3_init(void)
     g_static_mutex_unlock(&mutex);
     return ret;
 }
+#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31))
+# pragma GCC diagnostic pop
+#endif
 
 gboolean
 s3_curl_location_compat(void)
@@ -1738,7 +2200,7 @@ s3_bucket_location_compat(const char *bucket)
 }
 
 static gboolean
-get_openstack_swift_api_setting(
+get_openstack_swift_api_v1_setting(
        S3Handle *hdl)
 {
     s3_result_t result = S3_RESULT_FAIL;
@@ -1749,12 +2211,60 @@ get_openstack_swift_api_setting(
        };
 
     s3_verbose(hdl, 1);
-    result = perform_request(hdl, "GET", NULL, NULL, NULL, NULL,
+    result = perform_request(hdl, "GET", NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, result_handling);
 
     return result == S3_RESULT_OK;
+}
 
+static gboolean
+get_openstack_swift_api_v2_setting(
+       S3Handle *hdl)
+{
+    s3_result_t result = S3_RESULT_FAIL;
+    static result_handling_t result_handling[] = {
+       { 200,  0,                    0, S3_RESULT_OK },
+       RESULT_HANDLING_ALWAYS_RETRY,
+       { 0, 0,                       0, /* default: */ S3_RESULT_FAIL  }
+       };
+
+    CurlBuffer buf = {NULL, 0, 0, 0};
+    GString *body = g_string_new("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+    if (hdl->username && hdl->password) {
+       g_string_append_printf(body, "<auth xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://docs.openstack.org/identity/api/v2.0\"");
+    } else {
+       g_string_append_printf(body, "<auth xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.hp.com/identity/api/ext/HP-IDM/v1.0\"");
+    }
+
+    if (hdl->tenant_id) {
+       g_string_append_printf(body, " tenantId=\"%s\"", hdl->tenant_id);
+    }
+    if (hdl->tenant_name) {
+       g_string_append_printf(body, " tenantName=\"%s\"", hdl->tenant_name);
+    }
+    g_string_append(body, ">");
+    if (hdl->username && hdl->password) {
+       g_string_append_printf(body, "<passwordCredentials username=\"%s\" password=\"%s\"/>", hdl->username, hdl->password);
+    } else {
+       g_string_append_printf(body, "<apiAccessKeyCredentials accessKey=\"%s\" secretKey=\"%s\"/>", hdl->access_key, hdl->secret_key);
+    }
+    g_string_append(body, "</auth>");
+
+    buf.buffer = g_string_free(body, FALSE);
+    buf.buffer_len = strlen(buf.buffer);
+    s3_verbose(hdl, 1);
+    hdl->getting_swift_2_token = 1;
+    g_free(hdl->x_storage_url);
+    hdl->x_storage_url = NULL;
+    result = perform_request(hdl, "POST", NULL, NULL, NULL, NULL,
+                            "application/xml", NULL,
+                            S3_BUFFER_READ_FUNCS, &buf,
+                            NULL, NULL, NULL,
+                             NULL, NULL, result_handling);
+    hdl->getting_swift_2_token = 0;
+
+    return result == S3_RESULT_OK;
 }
 
 S3Handle *
@@ -1770,26 +2280,49 @@ s3_open(const char *access_key,
         const char *storage_class,
         const char *ca_info,
         const char *server_side_encryption,
-        const gboolean openstack_swift_api)
+        const char *proxy,
+        const S3_api s3_api,
+        const char *username,
+        const char *password,
+        const char *tenant_id,
+        const char *tenant_name,
+       const char *client_id,
+       const char *client_secret,
+       const char *refresh_token,
+       const gboolean reuse_connection)
 {
     S3Handle *hdl;
 
     hdl = g_new0(S3Handle, 1);
     if (!hdl) goto error;
 
-    hdl->verbose = FALSE;
+    hdl->verbose = TRUE;
     hdl->use_ssl = s3_curl_supports_ssl();
+    hdl->reuse_connection = reuse_connection;
 
-    if (!openstack_swift_api) {
+    if (s3_api == S3_API_S3) {
        g_assert(access_key);
        hdl->access_key = g_strdup(access_key);
        g_assert(secret_key);
        hdl->secret_key = g_strdup(secret_key);
-    } else {
+    } else if (s3_api == S3_API_SWIFT_1) {
        g_assert(swift_account_id);
        hdl->swift_account_id = g_strdup(swift_account_id);
        g_assert(swift_access_key);
        hdl->swift_access_key = g_strdup(swift_access_key);
+    } else if (s3_api == S3_API_SWIFT_2) {
+       g_assert((username && password) || (access_key && secret_key));
+       hdl->username = g_strdup(username);
+       hdl->password = g_strdup(password);
+       hdl->access_key = g_strdup(access_key);
+       hdl->secret_key = g_strdup(secret_key);
+       g_assert(tenant_id || tenant_name);
+       hdl->tenant_id = g_strdup(tenant_id);
+       hdl->tenant_name = g_strdup(tenant_name);
+    } else if (s3_api == S3_API_OAUTH2) {
+       hdl->client_id = g_strdup(client_id);
+       hdl->client_secret = g_strdup(client_secret);
+       hdl->refresh_token = g_strdup(refresh_token);
     }
 
     /* NULL is okay */
@@ -1804,6 +2337,9 @@ s3_open(const char *access_key,
     /* NULL is ok */
     hdl->server_side_encryption = g_strdup(server_side_encryption);
 
+    /* NULL is ok */
+    hdl->proxy = g_strdup(proxy);
+
     /* NULL is okay */
     hdl->ca_info = g_strdup(ca_info);
 
@@ -1813,7 +2349,7 @@ s3_open(const char *access_key,
     hdl->use_subdomain = use_subdomain ||
                         (strcmp(hdl->host, "s3.amazonaws.com") == 0 &&
                          is_non_empty_string(hdl->bucket_location));
-    hdl->openstack_swift_api = openstack_swift_api;
+    hdl->s3_api = s3_api;
     if (service_path) {
        if (strlen(service_path) == 0 ||
            (strlen(service_path) == 1 && service_path[0] == '/')) {
@@ -1836,9 +2372,6 @@ s3_open(const char *access_key,
     hdl->curl = curl_easy_init();
     if (!hdl->curl) goto error;
 
-    if (openstack_swift_api) { /* get the X-Storage-Url and X-Auth-Token */
-       get_openstack_swift_api_setting(hdl);
-    }
     return hdl;
 
 error:
@@ -1846,6 +2379,22 @@ error:
     return NULL;
 }
 
+gboolean
+s3_open2(
+    S3Handle *hdl)
+{
+    gboolean ret = TRUE;
+
+    /* get the X-Storage-Url and X-Auth-Token */
+    if (hdl->s3_api == S3_API_SWIFT_1) {
+       ret = get_openstack_swift_api_v1_setting(hdl);
+    } else if (hdl->s3_api == S3_API_SWIFT_2) {
+       ret = get_openstack_swift_api_v2_setting(hdl);
+    }
+
+    return ret;
+}
+
 void
 s3_free(S3Handle *hdl)
 {
@@ -1856,6 +2405,18 @@ s3_free(S3Handle *hdl)
         g_free(hdl->secret_key);
         g_free(hdl->swift_account_id);
         g_free(hdl->swift_access_key);
+        g_free(hdl->content_type);
+        g_free(hdl->user_token);
+        g_free(hdl->ca_info);
+        g_free(hdl->proxy);
+        g_free(hdl->username);
+        g_free(hdl->password);
+        g_free(hdl->tenant_id);
+        g_free(hdl->tenant_name);
+        g_free(hdl->client_id);
+        g_free(hdl->client_secret);
+        g_free(hdl->refresh_token);
+        g_free(hdl->access_token);
         if (hdl->user_token) g_free(hdl->user_token);
         if (hdl->bucket_location) g_free(hdl->bucket_location);
         if (hdl->storage_class) g_free(hdl->storage_class);
@@ -1889,6 +2450,10 @@ s3_reset(S3Handle *hdl)
             g_free(hdl->last_response_body);
             hdl->last_response_body = NULL;
         }
+        if (hdl->content_type) {
+            g_free(hdl->content_type);
+            hdl->content_type = NULL;
+        }
 
         hdl->last_response_body_size = 0;
     }
@@ -2023,7 +2588,7 @@ s3_upload(S3Handle *hdl,
 
     g_assert(hdl != NULL);
 
-    result = perform_request(hdl, "PUT", bucket, key, NULL, NULL,
+    result = perform_request(hdl, "PUT", bucket, key, NULL, NULL, NULL, NULL,
                  read_func, reset_func, size_func, md5_func, read_data,
                  NULL, NULL, NULL, progress_func, progress_data,
                  result_handling);
@@ -2180,21 +2745,24 @@ list_fetch(S3Handle *hdl,
                have_prev_part = TRUE;
             esc_value = curl_escape(pos_parts[i][1], 0);
            keyword = pos_parts[i][0];
-           if (hdl->openstack_swift_api && strcmp(keyword, "max-keys") == 0) {
+           if ((hdl->s3_api == S3_API_SWIFT_1 ||
+                hdl->s3_api == S3_API_SWIFT_2) &&
+               strcmp(keyword, "max-keys") == 0) {
                keyword = "limit";
            }
             g_string_append_printf(query, "%s=%s", keyword, esc_value);
             curl_free(esc_value);
        }
     }
-    if (hdl->openstack_swift_api) {
+    if (hdl->s3_api == S3_API_SWIFT_1 || hdl->s3_api == S3_API_SWIFT_2) {
        if (have_prev_part)
            g_string_append(query, "&");
        g_string_append(query, "format=xml");
     }
 
     /* and perform the request on that URI */
-    result = perform_request(hdl, "GET", bucket, NULL, NULL, query->str,
+    result = perform_request(hdl, "GET", bucket, NULL, NULL, query->str, NULL,
+                            NULL,
                              NULL, NULL, NULL, NULL, NULL,
                              S3_BUFFER_WRITE_FUNCS, buf, NULL, NULL,
                              result_handling);
@@ -2313,7 +2881,8 @@ s3_read(S3Handle *hdl,
 
     g_assert(hdl != NULL);
     g_assert(write_func != NULL);
-    result = perform_request(hdl, "GET", bucket, key, NULL, NULL,
+
+    result = perform_request(hdl, "GET", bucket, key, NULL, NULL, NULL, NULL,
         NULL, NULL, NULL, NULL, NULL, write_func, reset_func, write_data,
         progress_func, progress_data, result_handling);
 
@@ -2337,16 +2906,73 @@ s3_delete(S3Handle *hdl,
 
     g_assert(hdl != NULL);
 
-    result = perform_request(hdl, "DELETE", bucket, key, NULL, NULL,
+    result = perform_request(hdl, "DELETE", bucket, key, NULL, NULL, NULL, NULL,
                  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                  result_handling);
 
     return result == S3_RESULT_OK;
 }
 
+int
+s3_multi_delete(S3Handle *hdl,
+               const char *bucket,
+               const char **key)
+{
+    GString *query;
+    CurlBuffer data;
+    s3_result_t result = S3_RESULT_FAIL;
+    static result_handling_t result_handling[] = {
+        { 200,  0,                     0, S3_RESULT_OK },
+        { 204,  0,                     0, S3_RESULT_OK },
+        { 400,  0,                     0, S3_RESULT_NOTIMPL },
+        { 404,  S3_ERROR_NoSuchBucket, 0, S3_RESULT_OK },
+        RESULT_HANDLING_ALWAYS_RETRY,
+        { 0,    0,                     0, /* default: */ S3_RESULT_FAIL  }
+        };
+
+    g_assert(hdl != NULL);
+
+    query = g_string_new(NULL);
+    g_string_append(query, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+    g_string_append(query, "<Delete>\n");
+    if (!hdl->verbose) {
+       g_string_append(query, "  <Quiet>true</Quiet>\n");
+    }
+    while (*key != NULL) {
+       g_string_append(query, "  <Object>\n");
+       g_string_append(query, "    <Key>");
+       g_string_append(query, *key);
+       g_string_append(query, "</Key>\n");
+       g_string_append(query, "  </Object>\n");
+       key++;
+    }
+    g_string_append(query, "</Delete>\n");
+
+    data.buffer_len = query->len;
+    data.buffer = query->str;
+    data.buffer_pos = 0;
+    data.max_buffer_size = data.buffer_len;
+
+    result = perform_request(hdl, "POST", bucket, NULL, "delete", NULL,
+                "application/xml", NULL,
+                s3_buffer_read_func, s3_buffer_reset_func,
+                s3_buffer_size_func, s3_buffer_md5_func,
+                &data, NULL, NULL, NULL, NULL, NULL,
+                 result_handling);
+
+    g_string_free(query, TRUE);
+    if (result == S3_RESULT_OK)
+       return 1;
+    else if (result == S3_RESULT_NOTIMPL)
+       return 2;
+    else
+       return 0;
+}
+
 gboolean
 s3_make_bucket(S3Handle *hdl,
-               const char *bucket)
+               const char *bucket,
+              const char *project_id)
 {
     char *body = NULL;
     s3_result_t result = S3_RESULT_FAIL;
@@ -2393,7 +3019,8 @@ s3_make_bucket(S3Handle *hdl,
         }
     }
 
-    result = perform_request(hdl, "PUT", bucket, NULL, NULL, NULL,
+    result = perform_request(hdl, "PUT", bucket, NULL, NULL, NULL, NULL,
+                project_id,
                  read_func, reset_func, size_func, md5_func, ptr,
                  NULL, NULL, NULL, NULL, NULL, result_handling);
 
@@ -2404,11 +3031,11 @@ s3_make_bucket(S3Handle *hdl,
          * the one that's configured.
          */
        if (is_non_empty_string(hdl->bucket_location)) {
-            result = perform_request(hdl, "GET", bucket, NULL, "location", NULL,
+            result = perform_request(hdl, "GET", bucket, NULL, "location", NULL, NULL, NULL,
                                      NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                      NULL, NULL, result_handling);
        } else {
-            result = perform_request(hdl, "GET", bucket, NULL, NULL, NULL,
+            result = perform_request(hdl, "GET", bucket, NULL, NULL, NULL, NULL, NULL,
                                      NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                      NULL, NULL, result_handling);
        }
@@ -2459,11 +3086,81 @@ cleanup:
 
 }
 
+static s3_result_t
+oauth2_get_access_token(
+    S3Handle *hdl)
+{
+    GString *query;
+    CurlBuffer data;
+    s3_result_t result = S3_RESULT_FAIL;
+    static result_handling_t result_handling[] = {
+        { 200,  0,                    0, S3_RESULT_OK },
+        { 204,  0,                    0, S3_RESULT_OK },
+        RESULT_HANDLING_ALWAYS_RETRY,
+        { 0, 0,                       0, /* default: */ S3_RESULT_FAIL  }
+        };
+    char *body;
+    regmatch_t pmatch[2];
+
+    g_assert(hdl != NULL);
+
+    query = g_string_new(NULL);
+    g_string_append(query, "client_id=");
+    g_string_append(query, hdl->client_id);
+    g_string_append(query, "&client_secret=");
+    g_string_append(query, hdl->client_secret);
+    g_string_append(query, "&refresh_token=");
+    g_string_append(query, hdl->refresh_token);
+    g_string_append(query, "&grant_type=refresh_token");
+
+    data.buffer_len = query->len;
+    data.buffer = query->str;
+    data.buffer_pos = 0;
+    data.max_buffer_size = data.buffer_len;
+
+    hdl->x_storage_url = "https://accounts.google.com/o/oauth2/token";
+    hdl->getting_oauth2_access_token = 1;
+    result = perform_request(hdl, "POST", NULL, NULL, NULL, NULL,
+                            "application/x-www-form-urlencoded", NULL,
+                            s3_buffer_read_func, s3_buffer_reset_func,
+                            s3_buffer_size_func, s3_buffer_md5_func,
+                             &data, NULL, NULL, NULL, NULL, NULL,
+                            result_handling);
+    hdl->x_storage_url = NULL;
+    hdl->getting_oauth2_access_token = 0;
+
+    /* use strndup to get a null-terminated string */
+    body = g_strndup(hdl->last_response_body, hdl->last_response_body_size);
+    if (!body) {
+        hdl->last_message = g_strdup(_("No body received for location request"));
+        goto cleanup;
+    } else if ('\0' == body[0]) {
+        hdl->last_message = g_strdup(_("Empty body received for location request"));
+        goto cleanup;
+    }
+
+    if (!s3_regexec_wrap(&access_token_regex, body, 2, pmatch, 0)) {
+        hdl->access_token = find_regex_substring(body, pmatch[1]);
+        hdl->x_auth_token = g_strdup(hdl->access_token);
+    }
+    if (!s3_regexec_wrap(&expires_in_regex, body, 2, pmatch, 0)) {
+        char *expires_in = find_regex_substring(body, pmatch[1]);
+       hdl->expires = time(NULL) + atoi(expires_in) - 600;
+       g_free(expires_in);
+    }
+
+cleanup:
+    g_free(body);
+    return result == S3_RESULT_OK;
+}
+
 gboolean
 s3_is_bucket_exists(S3Handle *hdl,
-                     const char *bucket)
+                   const char *bucket,
+                   const char *project_id)
 {
     s3_result_t result = S3_RESULT_FAIL;
+    char *query;
     static result_handling_t result_handling[] = {
         { 200,  0,                    0, S3_RESULT_OK },
         { 204,  0,                    0, S3_RESULT_OK },
@@ -2471,8 +3168,15 @@ s3_is_bucket_exists(S3Handle *hdl,
         { 0, 0,                       0, /* default: */ S3_RESULT_FAIL  }
         };
 
-    result = perform_request(hdl, "GET", bucket, NULL, NULL,
-                            hdl->openstack_swift_api?"limit=1":"max-keys=1",
+    if (hdl->s3_api == S3_API_SWIFT_1 ||
+       hdl->s3_api == S3_API_SWIFT_2) {
+       query = "limit=1";
+    } else {
+       query = "max-keys=1";
+    }
+
+    result = perform_request(hdl, "GET", bucket, NULL, NULL, query,
+                            NULL, project_id,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, result_handling);
 
index 24ad9603fa70a237ba8fbb3d1209c4d7d1490969..e8fd74dc7231c1598be8283886b039f4988a8af5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
  * Data types
  */
 
+typedef enum {
+   S3_API_S3,
+   S3_API_SWIFT_1,
+   S3_API_SWIFT_2,
+   S3_API_OAUTH2
+} S3_api;
+
 /* An opaque handle.  S3Handles should only be accessed from a single
  * thread at any given time, although it is fine to use different handles
  * in different threads simultaneously. */
@@ -171,6 +178,7 @@ typedef curl_progress_callback s3_progress_func;
     S3_ERROR(Accepted), \
     S3_ERROR(Forbidden), \
     S3_ERROR(Conflict), \
+    S3_ERROR(AuthenticationRequired), \
     S3_ERROR(END)
 
 typedef enum {
@@ -245,7 +253,26 @@ s3_open(const char * access_key, const char *secret_key,
         const char * user_token,
         const char * bucket_location, const char * storage_class,
        const char * ca_info, const char * server_side_encryption,
-       const gboolean openstack_swift_api);
+       const char *proxy,
+       const S3_api s3_api,
+       const char *username,
+       const char *password,
+       const char *tenant_id,
+       const char *tenant_name,
+       const char *client_id,
+       const char *client_secret,
+       const char *refresh_token,
+       const gboolean reuse_connection);
+
+/* latest step of setting up the S3Handle.
+ *
+ * Must be done after all properties are set.
+ *
+ * @param hdl: the S3Handle to set up.
+ * @returns: false if an error occured
+ */
+gboolean
+s3_open2(S3Handle *hdl);
 
 /* Deallocate an S3Handle
  *
@@ -423,6 +450,19 @@ s3_delete(S3Handle *hdl,
           const char *bucket,
           const char *key);
 
+/* Delete multiple file.
+ *
+ * @param hdl: the S3Handle object
+ * @param bucket: the bucket to delete from
+ * @param key: the key array to delete
+ * @returns: 0 on sucess, 1 if multi_delete is not supported, 2 if an error
+ *           occurs; a non-existent file is I{not} considered an error.
+ */
+int
+s3_multi_delete(S3Handle *hdl,
+                const char *bucket,
+                const char **key);
+
 /* Create a bucket.
  *
  * @param hdl: the S3Handle object
@@ -431,7 +471,8 @@ s3_delete(S3Handle *hdl,
  */
 gboolean
 s3_make_bucket(S3Handle *hdl,
-               const char *bucket);
+               const char *bucket,
+              const char *project_id);
 
 /* Check if a bucket exists.
  *
@@ -441,7 +482,8 @@ s3_make_bucket(S3Handle *hdl,
  */
 gboolean
 s3_is_bucket_exists(S3Handle *hdl,
-                    const char *bucket);
+                    const char *bucket,
+                   const char *project_id);
 
 /* Delete a bucket
  *
index 5e4b44970ac4d2f184edd4634c5659883727e2dd..0c7fe243b34536c8852bb8f586c72f7b3ab040f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -995,6 +995,9 @@ tape_device_write_block(Device * pself, guint size, gpointer data) {
     }
 
     pself->block++;
+    g_mutex_lock(pself->device_mutex);
+    pself->bytes_written += size;
+    g_mutex_unlock(pself->device_mutex);
 
     return TRUE;
 }
@@ -1025,6 +1028,9 @@ static int tape_device_read_block (Device * pself, gpointer buf,
     case RESULT_SUCCESS:
         *size_req = size;
         pself->block++;
+       g_mutex_lock(pself->device_mutex);
+       pself->bytes_read += size;
+       g_mutex_unlock(pself->device_mutex);
         return size;
     case RESULT_SMALL_BUFFER: {
         gsize new_size;
@@ -1059,7 +1065,9 @@ static int tape_device_read_block (Device * pself, gpointer buf,
     }
     case RESULT_NO_DATA:
         pself->is_eof = TRUE;
+       g_mutex_lock(pself->device_mutex);
        pself->in_file = FALSE;
+       g_mutex_unlock(pself->device_mutex);
        device_set_error(pself,
            stralloc(_("EOF")),
            DEVICE_STATUS_SUCCESS);
@@ -1160,7 +1168,9 @@ tape_device_start (Device * d_self, DeviceAccessMode mode, char * label,
     }
 
     d_self->access_mode = mode;
+    g_mutex_lock(d_self->device_mutex);
     d_self->in_file = FALSE;
+    g_mutex_unlock(d_self->device_mutex);
 
     if (IS_WRITABLE_ACCESS_MODE(mode)) {
         if (self->write_open_errno != 0) {
@@ -1272,10 +1282,13 @@ static gboolean tape_device_start_file(Device * d_self,
     amfree(amanda_header);
 
     /* arrange the file numbers correctly */
-    d_self->in_file = TRUE;
     d_self->block = 0;
     if (d_self->file >= 0)
         d_self->file ++;
+    g_mutex_lock(d_self->device_mutex);
+    d_self->in_file = TRUE;
+    d_self->bytes_written = 0;
+    g_mutex_unlock(d_self->device_mutex);
     return TRUE;
 }
 
@@ -1295,7 +1308,9 @@ tape_device_finish_file (Device * d_self) {
         return FALSE;
     }
 
+    g_mutex_lock(d_self->device_mutex);
     d_self->in_file = FALSE;
+    g_mutex_unlock(d_self->device_mutex);
     return TRUE;
 }
 
@@ -1323,9 +1338,12 @@ tape_device_seek_file (Device * d_self, guint file) {
         difference --;
     }
 
-    d_self->in_file = FALSE;
     d_self->is_eof = FALSE;
     d_self->block = 0;
+    g_mutex_lock(d_self->device_mutex);
+    d_self->in_file = FALSE;
+    d_self->bytes_read = 0;
+    g_mutex_unlock(d_self->device_mutex);
 
 reseek:
     if (difference > 0) {
@@ -1452,7 +1470,9 @@ reseek:
         return NULL;
     }
 
+    g_mutex_lock(d_self->device_mutex);
     d_self->in_file = TRUE;
+    g_mutex_unlock(d_self->device_mutex);
     d_self->file = file;
 
     return rval;
@@ -1546,9 +1566,14 @@ tape_device_finish (Device * d_self) {
     }
 
     /* Polish off this file, if relevant. */
+    g_mutex_lock(d_self->device_mutex);
     if (d_self->in_file && IS_WRITABLE_ACCESS_MODE(d_self->access_mode)) {
-        if (!device_finish_file(d_self))
+       g_mutex_unlock(d_self->device_mutex);
+        if (!device_finish_file(d_self)) {
            goto finish_error;
+       }
+    } else {
+       g_mutex_unlock(d_self->device_mutex);
     }
 
     /* Straighten out the filemarks.  We already wrote one in finish_file, and
index 122a6efb8e479cdf21713b93c31a13af2d9e5d7c..5733995ad83fff71dae3ed45eb5d5e09d410b606 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -795,9 +795,10 @@ static gboolean vfs_device_write_block(Device * pself, guint size, gpointer data
        pself->is_eom = TRUE;
 
     if (check_at_peom(self, size)) {
+       /* check_at_peom() only checks against MAX_VOLUME_USAGE limit */
        pself->is_eom = TRUE;
        device_set_error(pself,
-           stralloc(_("No space left on device")),
+           stralloc(_("No space left on device: more than MAX_VOLUME_USAGE bytes written")),
            DEVICE_STATUS_VOLUME_ERROR);
        return FALSE;
     }
@@ -811,6 +812,9 @@ static gboolean vfs_device_write_block(Device * pself, guint size, gpointer data
     self->volume_bytes += size;
     self->checked_bytes_used += size;
     pself->block ++;
+    g_mutex_lock(pself->device_mutex);
+    pself->bytes_written += size;
+    g_mutex_unlock(pself->device_mutex);
 
     return TRUE;
 }
@@ -837,11 +841,16 @@ vfs_device_read_block(Device * pself, gpointer data, int * size_req) {
     switch (result) {
     case RESULT_SUCCESS:
         *size_req = size;
+       g_mutex_lock(pself->device_mutex);
+       pself->bytes_read += size;
+       g_mutex_unlock(pself->device_mutex);
        pself->block++;
         return size;
     case RESULT_NO_DATA:
         pself->is_eof = TRUE;
+       g_mutex_lock(pself->device_mutex);
         pself->in_file = FALSE;
+       g_mutex_unlock(pself->device_mutex);
        device_set_error(pself,
            stralloc(_("EOF")),
            DEVICE_STATUS_SUCCESS);
@@ -867,7 +876,9 @@ vfs_device_start(Device * dself,
         return FALSE;
     }
 
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = FALSE;
+    g_mutex_unlock(dself->device_mutex);
 
     if (mode == ACCESS_WRITE) {
         promote_volume_lock(self);
@@ -907,7 +918,9 @@ vfs_device_finish (Device * pself) {
     release_file(self);
 
     pself->access_mode = ACCESS_NULL;
+    g_mutex_lock(pself->device_mutex);
     pself->in_file = FALSE;
+    g_mutex_unlock(pself->device_mutex);
 
     if (device_in_error(self)) return FALSE;
 
@@ -1059,9 +1072,10 @@ vfs_device_start_file (Device * dself, dumpfile_t * ji) {
        dself->is_eom = TRUE;
 
     if (check_at_peom(self, VFS_DEVICE_LABEL_SIZE)) {
+       /* check_at_peom() only checks against MAX_VOLUME_USAGE limit */
        dself->is_eom = TRUE;
        device_set_error(dself,
-               stralloc(_("No space left on device")),
+               stralloc(_("No space left on device: more than MAX_VOLUME_USAGE bytes written")),
                DEVICE_STATUS_DEVICE_ERROR);
        return FALSE;
     }
@@ -1102,8 +1116,11 @@ vfs_device_start_file (Device * dself, dumpfile_t * ji) {
     /* handle some accounting business */
     self->volume_bytes += VFS_DEVICE_LABEL_SIZE;
     self->checked_bytes_used += VFS_DEVICE_LABEL_SIZE;
-    dself->in_file = TRUE;
     dself->block = 0;
+    g_mutex_lock(dself->device_mutex);
+    dself->in_file = TRUE;
+    dself->bytes_written = 0;
+    g_mutex_unlock(dself->device_mutex);
     /* make_new_file_name set pself->file for us */
 
     return TRUE;
@@ -1117,7 +1134,9 @@ vfs_device_finish_file(Device * dself) {
 
     release_file(self);
 
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = FALSE;
+    g_mutex_unlock(dself->device_mutex);
 
     return TRUE;
 }
@@ -1137,9 +1156,12 @@ vfs_device_seek_file (Device * dself, guint requested_file) {
 
     if (device_in_error(self)) return NULL;
 
-    dself->in_file = FALSE;
     dself->is_eof = FALSE;
     dself->block = 0;
+    g_mutex_lock(dself->device_mutex);
+    dself->in_file = FALSE;
+    dself->bytes_read = 0;
+    g_mutex_unlock(dself->device_mutex);
 
     release_file(self);
 
@@ -1232,7 +1254,9 @@ vfs_device_seek_file (Device * dself, guint requested_file) {
     if (requested_file == 0) {
        dself->header_block_size = header_buffer_size;
     }
+    g_mutex_lock(dself->device_mutex);
     dself->in_file = TRUE;
+    g_mutex_unlock(dself->device_mutex);
     dself->file = file;
 
     return rval;
index 09c3942babaf09563937113b5e34606a500c1a0a..e37346f26a5c016b87d753a3e6c0d7cb17c83cc8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005-2008, 2010 Zmanda Inc.  All Rights Reserved.
+ * Copyright (c) 2005-2012 Zmanda Inc.  All Rights Reserved.
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License version 2.1 as
index 28fd0580c2592268fbed81bedcaea07b448bf708..7836f5610d41f8bc23d34d5bff6b3b4d8fca4891 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 75643047b3b98f065fe2e82c1d1466505e12ba99..0bf02cd8a68901e6012feb09bea628b2652b0643 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -1328,7 +1328,12 @@ get_part_bytes_written_impl(
     /* NOTE: this access is unsafe and may return inconsistent results (e.g, a
      * partial write to the 64-bit value on a 32-bit system).  This is ok for
      * the moment, as it's only informational, but be warned. */
-    return self->bytes_written + self->slab_bytes_written;
+    if (self->device) {
+       return device_get_bytes_written(self->device);
+    } else {
+       return self->bytes_written + self->slab_bytes_written;
+    }
+
 }
 
 static void
index 6d9d12d23cfc8d965b568b7780fedc4f0887e214..91738d012c725d4f40c25c524553463d8d4da422 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -74,6 +74,7 @@ typedef struct XferDestTaperDirectTCP {
      * corresponding condition variable. */
     volatile gboolean paused;
     GCond *paused_cond;
+    GCond *abort_accept_cond; /* condition to trigger to abort an accept */
 
 } XferDestTaperDirectTCP;
 
@@ -108,6 +109,7 @@ worker_thread(
     XferElement *elt = (XferElement *)data;
     XferDestTaperDirectTCP *self = (XferDestTaperDirectTCP *)data;
     GTimer *timer = g_timer_new();
+    int result;
 
     /* This thread's job is to accept() an incoming connection, then call
      * write_from_connection for each part, and then close the connection */
@@ -124,12 +126,18 @@ worker_thread(
 
     /* first, accept a new connection from the device */
     DBG(2, "accepting DirectTCP connection on device %s", self->device->device_name);
-    if (!device_accept(self->device, &self->conn, NULL, NULL)) {
+    result = device_accept_with_cond(self->device, &self->conn,
+                                    self->state_mutex,
+                                    self->abort_accept_cond);
+    if (result == 2) {
        xfer_cancel_with_error(XFER_ELEMENT(self),
            "accepting DirectTCP connection: %s",
            device_error_or_status(self->device));
        g_mutex_unlock(self->state_mutex);
        return NULL;
+    } else if (result == 1) {
+       g_mutex_unlock(self->state_mutex);
+       return NULL;
     }
 
     DBG(2, "connection accepted; sending XMSG_READY");
@@ -327,6 +335,7 @@ cancel_impl(
      * longer paused */
     g_mutex_lock(self->state_mutex);
     g_cond_broadcast(self->paused_cond);
+    g_cond_broadcast(self->abort_accept_cond);
     g_mutex_unlock(self->state_mutex);
 
     return rv;
@@ -418,6 +427,7 @@ instance_init(
     self->conn = NULL;
     self->state_mutex = g_mutex_new();
     self->paused_cond = g_cond_new();
+    self->abort_accept_cond = g_cond_new();
 }
 
 static void
@@ -440,6 +450,7 @@ finalize_impl(
 
     g_mutex_free(self->state_mutex);
     g_cond_free(self->paused_cond);
+    g_cond_free(self->abort_accept_cond);
 
     if (self->part_header)
        dumpfile_free(self->part_header);
index ccd7fdec5deb6dae76362f4bf55700d53e060334..081e9b8dda5aaeec41ecaf7888a0982fdcc56bf2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -873,7 +873,11 @@ get_part_bytes_written_impl(
     /* NOTE: this access is unsafe and may return inconsistent results (e.g, a
      * partial write to the 64-bit value on a 32-bit system).  This is ok for
      * the moment, as it's only informational, but be warned. */
-    return self->part_bytes_written;
+    if (self->device) {
+       return device_get_bytes_written(self->device);
+    } else {
+       return self->part_bytes_written;
+    }
 }
 
 static void
index 88ef24785ef9b28e2185f2df6f79d1c0e9c75d57..4b7a4818549e08c10d22211d347cd88cc2c3ab08 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index e7b853796aeed545c30676270bc7d68c4df39cb7..c157a1938a7026d0d41ab1b738541dd85e07fa5f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index f18916b3df6d4836a77bc7eee2884df29c91abcf..cad34d009bd69cd056a14d3f32c0c6c40f4b2391 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -143,4 +143,8 @@ void xfer_source_recovery_use_device(
     XferElement *self,
     Device *device);
 
+guint64
+xfer_source_recovery_get_bytes_read(
+    XferElement *elt);
+
 #endif
index c709313c04956b5fb8e29fe3f0c797917a2c931e..e89a72ad584540f24e246850eb05b2e04d4fc427 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 16673e0d1932abecda5f1ba130320e81bf797b81..f305f0cb7f1e23fd91b2a5f99a6416d78563bcf1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -76,6 +76,9 @@ typedef struct XferSourceRecovery {
      * part) */
     size_t block_size;
 
+    /* bytes read for this image */
+    guint64 bytes_read;
+
     /* part size (potentially including any zero-padding from the
      * device) */
     guint64 part_size;
@@ -426,6 +429,7 @@ pull_buffer_impl(
            self->paused = TRUE;
            g_object_unref(self->device);
            self->device = NULL;
+           self->bytes_read += self->part_size;
            self->part_size = 0;
            self->block_size = 0;
            if (self->part_timer) {
@@ -700,3 +704,17 @@ xfer_source_recovery_use_device(
     klass = XFER_SOURCE_RECOVERY_GET_CLASS(elt);
     klass->use_device(XFER_SOURCE_RECOVERY(elt), device);
 }
+
+guint64
+xfer_source_recovery_get_bytes_read(
+    XferElement *elt)
+{
+    XferSourceRecovery *self = XFER_SOURCE_RECOVERY(elt);
+    guint64 bytes_read = self->bytes_read;
+
+    if (self->device)
+       bytes_read += device_get_bytes_read(self->device);
+
+    return bytes_read;
+}
+
index a4b63bda6090faa41e731abb6548a8ac43ba7cd1..9827d7a8e1bc16a885f35c87a352d4b40648f47d 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for sample configuration files
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -261,7 +261,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -803,6 +804,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 6c669fd1e84f52f4f89e854f5d88f585166158f1..cfd6f9b7f7153bd27ae18d878d26b7c706268053 100644 (file)
@@ -199,7 +199,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -779,6 +780,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 1a0e0e6e839425c06d09f6cf418390d2bd2b52db..09c8c1e358a6eee43abb908efb0fba5e22da9b79 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 58d8ed255a7aaef730153708a9f24fdfc274187a..8bfa7043b2f02266707dac2c06e7d86ac1c1c7f5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index ce3dbab57f7ad84032ef0e3e1dfe343b0644c277..416586591c0eabd2239fa8f5e6a35d5fa8349d10 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -256,7 +256,8 @@ my $chg = Amanda::Changer->new("mychanger", tapelist => $tl);
 is($chg->{'config'}->get_property("testprop"), "testval",
     "changer properties are correctly represented");
 is($chg->have_inventory(), 1, "changer have inventory");
-is($chg->make_new_tape_label(), undef, "no make_new_tape_label");
+my @new_tape_label = $chg->make_new_tape_label();
+is_deeply(\@new_tape_label, [undef, "template is not set, you must set autolabel"], "no make_new_tape_label");
 is($chg->make_new_meta_label(), undef, "no make_new_meta_label");
 
 $chg = Amanda::Changer->new("mychanger", tapelist => $tl,
index b2e311e13f60ff4dd1a20db2387150e86f67ba98..29c69525679ad53d5874eee78f6e47b15c16b418 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index c5b144baf4c0e1d48784d185a8d2e184bd35abbf..e88d214b0b72b679ce67454679b4c6885b0b6346 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index ae3466d8c8be065cf5588f5ba71d5682707b3568..dfcc99fff56bad016e92554ccb8b2d6799291832 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 209a60e70c7785d994b1bc140c54049da0fc36f9..70a9eeda9b17001aaafc8b3bd2a6894ed80138fb 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 50a98c190bf889deaf169f635a7405eadc69fbc0..eccca06e6749e45e2f875968bf030aa74cccc022 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 2139296bfbba131a705519ab18c88109c1f2dd18..c0cb9663a2cc5bb23d88132b0479b73e152422f3 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7eadaa25e9e3d6462728f1972e55e4890faa7472..d7ddb60bbef535c91945fddc8a855510e325b344 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 1f876d69f1e643f2ed3d0f60592a89456a6054ec..e95c8371f96f632273e88bc9a8aba68d511eaa78 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7975a57f2abdea22fe26f86584d79b65cb0dcfca..5aa7127348b0220d3ade5279a1a98af42304d23b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index e752fc7a2c5850b3e0e6bc17903ebb8eb79929a4..d8f412df18c0950a1552ae9567ec5a09d6e4f57e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 4a00337a70bfbfd24187b56b8ade3b1abab4e589..362dcb5cdbe7e42b222a2c9eabc59e2c6eecde48 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -602,7 +602,7 @@ is($error_level, $CFGERR_ERRORS, "bogus config overwrite flagged as an error");
 my $pid = open(my $kid, "-|");
 die "Can't fork: $!" unless defined($pid);
 if (!$pid) {
-    Amanda::Config::dump_configuration();
+    Amanda::Config::dump_configuration(1, 0);
     exit 1;
 }
 my $dump_first_line = <$kid>;
index 582e497155f8fd6941e6b71ac4d50b02ae47c1d1..50648e68a579ea785acf6064570bb3d44764b961 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 465b4d53ecd349190c913e59eef7aa9e5be294e0..e37704380b55ae8eb6bcf08c3d3fad9691876a90 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 41a5d8a87ab0a1a8cd220389ad8b0e751f8bddb0..4a87c7b8bfe32f3d87240aaf1ee7332b2880811c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index d6dee29c03237133583c20b0a148acf1faf242aa..98f63450b35c1655e3b77552b4efb702f037ad13 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7fdccef1ca015821e0556d5f40347418f62cc285..92ab1626920609dc617716a497f5ec5c3f066a92 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -16,7 +16,7 @@
 # Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
 
-use Test::More tests => 593;
+use Test::More tests => 609;
 use File::Path qw( mkpath rmtree );
 use Sys::Hostname;
 use Carp;
@@ -33,6 +33,7 @@ use Amanda::Config qw( :getconf :init );
 use Amanda::Xfer qw( :constants );
 use Amanda::Header qw( :constants );
 use Amanda::Paths;
+use Amanda::Constants;
 use Amanda::Util;
 use Amanda::MainLoop;
 use IO::Socket;
@@ -1312,7 +1313,7 @@ SKIP: {
 }
 
 SKIP: {
-    skip "not built with ndmp and server", 78 unless
+    skip "not built with ndmp and server", 94 unless
        Amanda::Util::built_with_component("ndmp") and
        Amanda::Util::built_with_component("server");
 
@@ -1548,6 +1549,106 @@ SKIP: {
        }
     }
 
+    #
+    # Test indirecttcp
+    # 
+
+    {
+       ok($dev->directtcp_supported(), "is a directtcp target");
+
+       $dev->property_set("indirect", 1);
+
+       my $addrs = $dev->listen(1);
+       ok($addrs, "listen returns successfully") or die($dev->error_or_status());
+
+       # fork off to evaluate the indirecttcp addresses and then set up an
+       # xfer to write to the device
+       if (POSIX::fork() == 0) {
+           # allow other process to start listening.
+           sleep 1;
+           my $nc = $Amanda::Constants::NC;
+           $nc = $Amanda::Constants::NC6 if !$nc;
+           $nc = $Amanda::Constants::NETCAT if !$nc;
+           my $sockresult = `$nc localhost $addrs->[0][1] < /dev/null`;
+
+           my @sockresult = map { [ split(/:/, $_) ] } split(/ /, $sockresult);
+           $addrs = [ map { $_->[1] = 0 + $_->[1]; $_ } @sockresult ];
+
+           my $xfer = Amanda::Xfer->new([
+                   Amanda::Xfer::Source::Random->new(32768*34, 0xB00),
+                   Amanda::Xfer::Dest::DirectTCPConnect->new($addrs) ]);
+
+           $xfer->start(make_cb(xmsg_cb => sub {
+               my ($src, $msg, $xfer) = @_;
+               if ($msg->{'type'} == $XMSG_ERROR) {
+                   die $msg->{'elt'} . " failed: " . $msg->{'message'};
+               } elsif ($msg->{'type'} == $XMSG_DONE) {
+                   Amanda::MainLoop::quit();
+               }
+           }));
+
+           Amanda::MainLoop::run();
+           exit(0);
+       }
+
+       # write files from the connection until EOF
+       my @messages;
+       my $num_files;
+       my $conn;
+       my ($call_accept, $start_device, $write_file_cb);
+
+       $call_accept = make_cb(call_accept => sub {
+           $conn = $dev->accept();
+           Amanda::MainLoop::call_later($start_device);
+       });
+
+       $start_device = make_cb(start_device => sub {
+           ok($dev->start($ACCESS_WRITE, "TEST2", "20090915000000"),
+               "start device in write mode")
+               or diag $dev->error_or_status();
+
+           Amanda::MainLoop::call_later($write_file_cb);
+       });
+
+       $write_file_cb = make_cb(write_file_cb => sub {
+           ++$num_files < 20 or die "I seem to be in a loop!";
+
+           ok($dev->start_file($hdr), "start file $num_files for writing");
+           is($dev->file, $num_files, "..file number is correct");
+
+           my ($ok, $size) = $dev->write_from_connection(32768*15);
+           push @messages, sprintf("WRITE-%s-%d-%s-%s",
+               $ok?"OK":"ERR", $size,
+               $dev->is_eof()? "EOF":"!eof",
+               $dev->is_eom()? "EOM":"!eom");
+           ok($ok, "..write from connection succeeds");
+           my $eof = $dev->is_eof();
+
+           ok($dev->finish_file(), "..finish file after writing");
+
+           if (!$eof) {
+               Amanda::MainLoop::call_later($write_file_cb);
+           } else {
+               Amanda::MainLoop::quit();
+           }
+       });
+
+       Amanda::MainLoop::call_later($call_accept);
+       Amanda::MainLoop::run();
+       is_deeply([@messages], [
+               'WRITE-OK-491520-!eof-!eom',
+               'WRITE-OK-491520-!eof-!eom',
+               'WRITE-OK-131072-EOF-!eom',
+           ],
+           "a sequence of write_from_connection calls works correctly");
+
+       $dev->finish();
+
+       if (my $err = $conn->close()) {
+           die $err;
+       }
+    }
+
     # now try reading that back piece by piece
 
     {
index 4d649349703c08ac2ef7c5fd8ea5ebaf01a74c6a..da3a59ee8e9c2218663ec10739a6a5d34dad738d 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7940f0536dc8bd31b8639339b1456b9f07318b39..89288bbb19000325009ec6d39b937ec6f95ef239 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index a09134ff4563ef57d0e8ef5e791184b1cb863305..3deca3039781de5ef09d868fc18ea5f039cbb7e4 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 3f354dc61fb3e4c22aca14308b40dc778ee6b4c3..649763759720fe3d27c98e93990d15bd3a259583 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index ca646e067e945c1b04d73ee0812fef7b0620d107..ee3d6ff262cce7161d15e8de3fdb5e54fb4d03a7 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 5717bfceaad8a19cd222080f1513b3b37e206766..b1f14841947da12ee4295aa8b67d09d36eb5a03f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -305,6 +305,8 @@ my $NMSGS = 10000;
        POSIX::exit(0);
     };
 
+    $wrh->write("SIMPLE\n");
+
     # and sleep forever, or until killed.
     while (1) { sleep(100); }
 });
@@ -313,6 +315,15 @@ $proto = TestProtocol->new(
     rx_fh => $rx_fh, tx_fh => $tx_fh,
     message_cb => $message_cb);
 $proto->set_message_cb(TestProtocol::QUIT, $quit_cb);
+$proto->set_message_cb(TestProtocol::SIMPLE, sub {
+       push @events, [ shift @_ ];
+       # send $NMSGS messages to the child, which isn't listening yet!
+       for (my $i = 0; $i < $NMSGS; $i++) {
+           $proto->send(TestProtocol::SIMPLE);
+       }
+       # and then send it SIGUSR1, so it reads those
+       kill USR1 => $pid;
+    });
 $proto->set_message_cb(TestProtocol::BAR, sub {
        push @events, [ shift @_, { @_ } ];
     });
@@ -320,19 +331,13 @@ $proto->set_message_cb(TestProtocol::BAR, sub {
 # die after 10 minutes
 alarm 600;
 
-# send $NMSGS messages to the child, which isn't listening yet!
-for (my $i = 0; $i < $NMSGS; $i++) {
-    $proto->send(TestProtocol::SIMPLE);
-}
-# and then send it SIGUSR1, so it reads those
-kill USR1 => $pid;
-
 Amanda::MainLoop::run();
 waitpid($pid, 0);
 alarm 0; # cancel the alarm
 
 is_deeply([ @events ],
     [
+       [ "SIMPLE" ],
        [ "BAR", { mandatory => "got your inputs" } ],
        [ "QUIT" ],
     ],
index 9aaf3049fdc48fd68435dfee7ebf42f951bfcad8..deec0e534d7fdc2fa046149bb1333f21a2f0e63c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 5ce0b52f46940996bafc80a841d292c3fbc78655..13abc47da06617946714dfc9689d4595346d0f5c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 25e80c127c0d6e9267596bf2db523a89fcc4e1bd..0456d693a98c264b7d082fdbf30a5b45169cae0b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index da943463bad9ff22ba0041f74e2835edf6685231..b82ac3571f028898ac1f856a25967b8ff4317424 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7841f9900905e50f5be13f25e4a802cc061f1827..5a14d1b159e5e60d827a1b5dc651781187e6dad5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 3e382c4e124ffff5286293719949d988f05e0676..61a59858910e45f73334a1876d131147d51e6505 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index dd704c7a17ef59dea96f4d55c0d004518ffe3469..354d0f9d3d824eeb477d13845c8d4a3dc8514c43 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f30e985ad63cc963a9b0fbbafea350067c4f1bf5..ebfd0952fb6ea5925881d37cb26a9467d1b71ed2 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 1509ed94be6964cee61e086e448fca62a8124a0c..37dac019fdd2cba52806d4942f66ced3b52f74c2 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f6200f3580356de803a7542128035db0ec095f56..ad853efb08e6cd649259655464df2082664f11b3 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index fd218acd61a10818db3479ca448186ff60c1ef4c..2b38b66ea68d81fba2b42287a29ff63ded3b1156 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 97f3595f622ccf917dcee316111a0bf522fff487..4e51bf6c162d70c92957430f18ec8e06053cc738 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 607013aee9e7739cf69ba968772586dea0695d1a..630334aa73c27de4f571abd488d94e8c30d1a146 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 352e2574d335e075b38579bb770bcb6e3cbb69ee..0a83d0df95a9d88fd5a5e85aefd4869dc3f55308 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7a97c378e51976e679e48a9819852ff751434e0d..5e86e12faa82a24866a0e7f2e7429e2768a7db6e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7d8cf361ecc6119ec2952eb539a148b3d81888bc..ff5eb555659a7947bc517aeb69178cb935029ade 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 4c41157121c1efbbd79f54089a81d83067e07582..daaef5b7e40ba1fddbe97194e59d44b2d4bc5acc 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 5c38b1bad33d5d0d678e535475371713480f4977..6c8fe5ae12838df947b57bc77e6e634975903f0b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 3864868316603a13492cd6372d0f7e54901d47ac..8c4432dee7c00da6ff918a889ee4b000f2c83b6a 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 92b98dfab50ae9a98bb381c90a449ea6a1154810..e77b659e343fb774f70c179c0e3194d783ecafc5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 835bcf934f6372d543ef9a6919b97f56c4533e29..cf69801da98162b1aedbcf768368626a5b3a005d 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 784d6f9356381f39d59cfcb07f219a9c153787d5..7358428a5e41ad4446180122228b4d02920c9103 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 0e46418d02a0e2d88de6a92126833b96dbee9a5c..631b1178ad01500895042bf2594da50db8f0f09a 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 4b1d3a2680dd51e3cbd9207b468f976febc93f0e..e3e29c3f66a72196aee92a282e3b1d44fc377a51 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 73b4c832ec70848d30a2a3d9d46cbad2ca9438b3..4388a2f37cb91e139dcc7e6978cf59c986e04a31 100644 (file)
@@ -16,7 +16,7 @@
 @SET_MAKE@
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -38,7 +38,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -299,7 +299,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -816,6 +817,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 38681174096643c454ba26532ea1f025d9a08522..657c460535054ebe4bba05832f8028d577ee4918 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -16,7 +16,7 @@
 # Contact information: Zmanda Inc, 465 S Mathilda Ave, Suite 300
 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
 
-use Test::More tests => 17;
+use Test::More tests => 18;
 use strict;
 use warnings;
 
@@ -120,3 +120,7 @@ amadmin: localhost:\\\\windows\\share-b is set to a forced level 0 at next run.$
 like(run_get('amadmin TESTCONF force localhost share-a share-a'),
    qr/^amadmin: localhost:\\\\windows\\share-a is set to a forced level 0 at next run.$/,
    "shell 13");
+
+like(run_get('amadmin TESTCONF balance --days 12'),
+   qr/No data to report on yet.$/,
+   "shell 13");
index 0c58e30fb07e6ba02dac1c856b89c2cd629dc7b8..c0c6dff631b0519aeb77d9c88e97220dee38d512 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 02f1acbb1094575d790c4353c43982484a745ae1..45caa2fb23967088d8fcaa7303cd753b735f9838 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f186d25812d2a2598658b5626aa5ded3d91710e7..c9214c666c015cb35a543ae4e6fa2c5e49de77c5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 21fbdd501bbb445177f7e22ae58a10cc05218390..7e7d97a64a92365efff745e8bd82dd5d8d8a797a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index b26f4871041d1e9abffd883a543d793a172bf2d4..d8423a5deba9ef4d2c0038dc24df1ade6f08b2e8 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 603d45978ae698d6d7bfc480842082425843042f..5c7e9fee71ec21df09add293c64c627b8d635179 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 893a9e5749a5ba66b24ecca9f4ac1c1fa243f9c1..f938367bd8596a384469f26d6c11e2756e32f787 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 6cebfb8fd722dc4ffce67af76a4e597777bd6ed9..a1adf9a31b106cea700b10e109ecfe30acca49f4 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 526b92e1c30a6a5740daedfba338bcdd0cbdcd07..009b207bfc390529ea59dd2b83befa851a042156 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 5ae66d92887362d551af9ba5f4a4c4dd0f0492cb..2854d20f1670072f007b4ce12d6e009e6409ad68 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -216,7 +216,7 @@ is_deeply([sort(+split(qr/\n/, run_get('amgetconf', 'TESTCONF', 'device_property
 $testconf = Installcheck::Config->new();
 $testconf->add_tapetype("cassette", [ length => "32 k" ]);
 $testconf->add_tapetype("reel2reel", [ length => "1 M" ]);
-$testconf->add_tapetype("scotch", [ length => "500 bytes" ]); # (use a sharpie)
+$testconf->add_tapetype("scotch", [ length => "512000 bytes" ]);
 $testconf->add_dumptype("testdump", [ comment => '"testdump-dumptype"',
                                      auth => '"bsd"' ]);
 $testconf->add_dumptype("testdump1", [ inherit => 'testdump' ]);
index 2d87e5b21234e405ac7f13945f05d69d6edcc17d..14bdb42f4dda168f3b4b20433a1440ed83724d58 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index e6ebc65564ac01abdc104ced3137aa82dece3421..b29ac6feee70c443a081bce308cc608d124c8007 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 5326f0b8b3a56c2d0993468c6418de2c3a393a1c..dea6ea334f60d9d8bc494fbcaf8bcd032f878851 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 60ef71cc77c037daceae607ec4b5155c0cf0d059..65d6ceb06d7cbe8c1a5cc8e8824f2cf43f37391f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index a2aa380de18267114ae0137fcd680be8ae61143a..4c21d86d563d08aa6bc12170cfff79216aaf9d76 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 6931e123d0c5855a5f018bf13342582cc7e0cea7..c8eb5aab8bad8d5c4c95643f8f0022fc72344b19 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 2362d9737460ecdb2be35ec2db75564e7be510b6..f7bedcc7b01a11a39359e66e549c843c1f374903 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 3b4886189d6d7801c259f28fc63041a82fa3a671..d8532d5398bb4580f69f0a6c0b055a4f4b3dc36e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 68fa8811f9e2cf4518eb7c33433632e7727039b0..032c9a6ad192128c1c7480a9b78d45fca942e4eb 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 585a3539ea13c637166da4c95b46825f456aa050..1ddfa89373db7d6c1d8cb13faf391f00c287a585 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 22e7c1818b010ac577fac5cf1d6f5e238bf72bff..8c1567d5c6959924d2077a99c82ef6f7a93662a0 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 560ca277e645d6b8cdd15c83c2aa102e10f60fe8..9a93bc7587f9ee67a66e5192c66d67bb74873d87 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index fd2a1c3f695bab101c0385859517c4df08a1e84e..1b71d9fb4d514f05c96a766a822b2c8c7184359b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 3220e70f0cf9a99dbeb8d54f9d70b98a3eb62b64..9601b51fd8e3669f2bb7e44aba5b9f819aff0dba 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index c8cd108b7150b5c389fab4927cbf13cc938afdb7..38b70cc501f33b58aacc9a0f60f8ebdea3f7ae80 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index b8a3971fe6db89355bedd67b3f89d7050470513a..917d6b4527ee4af20d3bcdfef0800a9768f29c40 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 6fa8a3561311fa6cf6e1da2e2a173f718b8582b3..011ac762f5375cba161fbca2d9b8dfff1c74fe2e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 37623f152959577b569b7cf01c147c89d63a937b..41351b730a4ee4f2cd918011266cee219727d9d1 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7883b75f0ca594ebe673aa931ac6674ec00a496a..5af7180c6f87dc81890c38621239a9b975961619 100644 (file)
@@ -54,9 +54,9 @@ NOTES:
 
 DUMP SUMMARY:
                                         DUMPER STATS                 TAPER STATS
-HOSTNAME     DISK        L  ORIG-kB   OUT-kB  COMP%  MMM:SS    KB/s MMM:SS    KB/s
--------------------------- ---------------------------------------- --------------
-home.slikon. /opt/public 0 72987320 50917369   69.8   46:57 18078.1  31:06 27287.8
+HOSTNAME          DISK        L  ORIG-kB   OUT-kB  COMP%  MMM:SS    KB/s MMM:SS    KB/s
+------------------------------- ---------------------------------------- --------------
+home.slikon.local /opt/public 0 72987320 50917369   69.8   46:57 18078.1  31:06 27287.8
 
 (brought to you by Amanda version x.y.z)
 
index 9023244323edee5ba29dfecc1230ac6f7ed18461..67387f78068ebf913fdbf0f3dddf8b951a7b7268 100644 (file)
@@ -108,9 +108,9 @@ NOTES:
 
 DUMP SUMMARY:
                                        DUMPER STATS               TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS   KB/s
--------------------------- ------------------------------------- --------------
-ns-new.sliko /opt/var    0           54929    --      PARTIAL      0:04 15451.0 PARTIAL
+HOSTNAME            DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS   KB/s
+--------------------------------- ------------------------------------- --------------
+ns-new.slikon.local /opt/var    0           54929    --      PARTIAL      0:04 15451.0 PARTIAL
 
 (brought to you by Amanda version x.y.z)
 
index e5a4af36d6607e44489edb729e7090948e9d78d5..d7c78d4db49c4c390557185ba9e0e264718eab97 100644 (file)
@@ -66,9 +66,9 @@ NOTES:
 
 DUMP SUMMARY:
                                       DUMPER STATS                TAPER STATS
- HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS     KB/s
- -------------------------- ------------------------------------- ---------------
- localhost.lo /boot       2   10240   10240    --      FLUSH        0:00 446100.0
- localhost.lo /boot       1   20480   20480    --      FLUSH        0:00 446100.0
+ HOSTNAME             DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS     KB/s
+ ----------------------------------- ------------------------------------- ---------------
+ localhost.localdomain /boot       2   10240   10240    --      FLUSH        0:00 446100.0
+ localhost.localdomain /boot       1   20480   20480    --      FLUSH        0:00 446100.0
 
 (brought to you by Amanda version x.y.z)
index 70f0f4bad2b60bc35d63272d73ba15a1e11136ec..2fe98ed2e5adba1a098607882a2168d8766456f4 100644 (file)
@@ -1177,8 +1177,8 @@ sendbackup: info end
 
 DUMP SUMMARY:
                                        DUMPER STATS               TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
--------------------------- ------------------------------------- --------------
-bsdfw.slikon /           0 5401240 2293470   42.5   29:36 1305.4   2:37 14596.6
+HOSTNAME           DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
+-------------------------------- ------------------------------------- --------------
+bsdfw.slikon.local /           0 5401240 2293470   42.5   29:36 1305.4   2:37 14596.6
 
 (brought to you by Amanda version x.y.z)
index cfff2bc66daffdda799699383e6a405914a19dcc..f53b040ade166cfa39151a9d769bd4d1f8aa8ea9 100644 (file)
@@ -140,13 +140,13 @@ NOTES:
 
 DUMP SUMMARY:
                                       DUMPER STATS               TAPER STATS
- HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
- -------------------------- ------------------------------------- --------------
- localhost.lo /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
- localhost.lo /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
- localhost.lo /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
- localhost.lo /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
- localhost.lo /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
+ HOSTNAME              DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
+ ----------------------------------- ------------------------------------- --------------
+ localhost.localdomain /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
+ localhost.localdomain /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
+ localhost.localdomain /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
+ localhost.localdomain /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
+ localhost.localdomain /bootAMGTAR 1   44610   44610     --     FLUSH        0:01 44610.0
 
 (brought to you by Amanda version 3.2.0alpha.git.8dca8d1f)
 
index 1e73d43e71656a3e9c7808d7e7e9ecfe4f9edf80..9a1acfb2723ea71d6f6a5618b31c12b683a065a6 100644 (file)
@@ -293,17 +293,17 @@ NOTES:
 \f
 DUMP SUMMARY:
                                           DUMPER STATS                    TAPER STATS
-HOSTNAME     DISK        L    ORIG-kB     OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
--------------------------- -------------------------------------------- ---------------
-localhost.lo /boot1      0         16         12   75.0    0:02 24748.4   0:00 156611.1
-localhost.lo /boot2      0        167        123   73.7    0:02 24748.4   0:00 156611.1
-localhost.lo /boot3      0       1678       1234   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot4      0      16789      12345   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot5      0     167890     123456   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot6      0    1678901    1234567   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot7      0   16789012   12345678   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot8      0  167890123  123456789   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot9      0 1678901234 1234567890   73.5    0:02 24748.4   0:00 156611.1
+HOSTNAME              DISK   L    ORIG-kB     OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
+----------------------------------- -------------------------------------------- ---------------
+localhost.localdomain /boot1 0         16         12   75.0    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot2 0        167        123   73.7    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot3 0       1678       1234   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot4 0      16789      12345   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot5 0     167890     123456   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot6 0    1678901    1234567   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot7 0   16789012   12345678   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot8 0  167890123  123456789   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot9 0 1678901234 1234567890   73.5    0:02 24748.4   0:00 156611.1
 
 (brought to you by Amanda version x.y.z)
 %T rpt2
@@ -347,17 +347,17 @@ NOTES:
 \f
 DUMP SUMMARY:
                                             DUMPER STATS                     TAPER STATS
-HOSTNAME     DISK        L       ORIG-kB     OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
--------------------------- ----------------------------------------------- ---------------
-localhost.lo /boot1      0         16.00         12   75.0    0:02 24748.4   0:00 156611.1
-localhost.lo /boot2      0        167.00        123   73.7    0:02 24748.4   0:00 156611.1
-localhost.lo /boot3      0       1678.00       1234   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot4      0      16789.00      12345   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot5      0     167890.00     123456   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot6      0    1678901.00    1234567   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot7      0   16789012.00   12345678   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot8      0  167890123.00  123456789   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot9      0 1678901234.00 1234567890   73.5    0:02 24748.4   0:00 156611.1
+HOSTNAME              DISK        L       ORIG-kB     OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
+----------------------------------- ----------------------------------------------- ---------------
+localhost.localdomain /boot1      0         16.00         12   75.0    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot2      0        167.00        123   73.7    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot3      0       1678.00       1234   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot4      0      16789.00      12345   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot5      0     167890.00     123456   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot6      0    1678901.00    1234567   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot7      0   16789012.00   12345678   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot8      0  167890123.00  123456789   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot9      0 1678901234.00 1234567890   73.5    0:02 24748.4   0:00 156611.1
 
 (brought to you by Amanda version x.y.z)
 %T rpt3
@@ -401,17 +401,17 @@ NOTES:
 \f
 DUMP SUMMARY:
                                         DUMPER STATS                 TAPER STATS
-HOSTNAME     DISK        L ORIG-kB     OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
--------------------------- --------------------------------------- ---------------
-localhost.lo /boot1      0    16         12   75.0    0:02 24748.4   0:00 156611.1
-localhost.lo /boot2      0   167        123   73.7    0:02 24748.4   0:00 156611.1
-localhost.lo /boot3      0  1678       1234   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot4      0 16789      12345   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot5      0 167890     123456   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot6      0 1678901    1234567   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot7      0 16789012   12345678   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot8      0 167890123  123456789   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot9      0 1678901234 1234567890   73.5    0:02 24748.4   0:00 156611.1
+HOSTNAME              DISK        L ORIG-kB     OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
+----------------------------------- --------------------------------------- ---------------
+localhost.localdomain /boot1      0    16         12   75.0    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot2      0   167        123   73.7    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot3      0  1678       1234   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot4      0 16789      12345   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot5      0 167890     123456   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot6      0 1678901    1234567   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot7      0 16789012   12345678   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot8      0 167890123  123456789   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot9      0 1678901234 1234567890   73.5    0:02 24748.4   0:00 156611.1
 
 (brought to you by Amanda version x.y.z)
 %T rpt4
@@ -455,17 +455,17 @@ NOTES:
 \f
 DUMP SUMMARY:
                                         DUMPER STATS                 TAPER STATS
-HOSTNAME     DISK        L ORIG-kB     OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
--------------------------- --------------------------------------- ---------------
-localhost.lo /boot1 0 16.000000 12 75.0 0:02 24748.4 0:00 156611.1
-localhost.lo /boot2 0 167.000000 123 73.7 0:02 24748.4 0:00 156611.1
-localhost.lo /boot3 0 1678.000000 1234 73.5 0:02 24748.4 0:00 156611.1
-localhost.lo /boot4 0 16789.000000 12345 73.5 0:02 24748.4 0:00 156611.1
-localhost.lo /boot5 0 167890.000000 123456 73.5 0:02 24748.4 0:00 156611.1
-localhost.lo /boot6 0 1678901.000000 1234567 73.5 0:02 24748.4 0:00 156611.1
-localhost.lo /boot7 0 16789012.000000 12345678 73.5 0:02 24748.4 0:00 156611.1
-localhost.lo /boot8 0 167890123.000000 123456789 73.5 0:02 24748.4 0:00 156611.1
-localhost.lo /boot9 0 1678901234.000000 1234567890 73.5 0:02 24748.4 0:00 156611.1
+HOSTNAME         DISK             L ORIG-kB     OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
+----------------------------------- --------------------------------------- ---------------
+localhost.localdomain /boot1      0 16.000000 12 75.0 0:02 24748.4 0:00 156611.1
+localhost.localdomain /boot2      0 167.000000 123 73.7 0:02 24748.4 0:00 156611.1
+localhost.localdomain /boot3      0 1678.000000 1234 73.5 0:02 24748.4 0:00 156611.1
+localhost.localdomain /boot4      0 16789.000000 12345 73.5 0:02 24748.4 0:00 156611.1
+localhost.localdomain /boot5      0 167890.000000 123456 73.5 0:02 24748.4 0:00 156611.1
+localhost.localdomain /boot6      0 1678901.000000 1234567 73.5 0:02 24748.4 0:00 156611.1
+localhost.localdomain /boot7      0 16789012.000000 12345678 73.5 0:02 24748.4 0:00 156611.1
+localhost.localdomain /boot8      0 167890123.000000 123456789 73.5 0:02 24748.4 0:00 156611.1
+localhost.localdomain /boot9      0 1678901234.000000 1234567890 73.5 0:02 24748.4 0:00 156611.1
 
 (brought to you by Amanda version x.y.z)
 %T rpt5
@@ -509,16 +509,16 @@ NOTES:
 \f
 DUMP SUMMARY:
                                        DUMPER STATS                 TAPER STATS
-HOSTNAME     DISK        L ORIG-MB  OUT-MB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
--------------------------- -------------------------------------- ---------------
-localhost.lo /boot1      0       0       0   75.0    0:02 24748.4   0:00 156611.1
-localhost.lo /boot2      0       0       0   73.7    0:02 24748.4   0:00 156611.1
-localhost.lo /boot3      0       2       1   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot4      0      16      12   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot5      0     164     121   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot6      0    1640    1206   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot7      0   16396   12056   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot8      0  163955  120563   73.5    0:02 24748.4   0:00 156611.1
-localhost.lo /boot9      0 1639552 1205633   73.5    0:02 24748.4   0:00 156611.1
+HOSTNAME              DISK        L ORIG-MB  OUT-MB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
+----------------------------------- -------------------------------------- ---------------
+localhost.localdomain /boot1      0       0       0   75.0    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot2      0       0       0   73.7    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot3      0       2       1   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot4      0      16      12   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot5      0     164     121   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot6      0    1640    1206   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot7      0   16396   12056   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot8      0  163955  120563   73.5    0:02 24748.4   0:00 156611.1
+localhost.localdomain /boot9      0 1639552 1205633   73.5    0:02 24748.4   0:00 156611.1
 
 (brought to you by Amanda version x.y.z)
index dee6e55f66bae472ccc9de7a6398b3edc25f3341..353446198638e570f86e7ebaa7184886c43c9e65 100644 (file)
@@ -64,11 +64,11 @@ NOTES:
 
 DUMP SUMMARY:
                                        DUMPER STATS               TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS   KB/s
--------------------------- ------------------------------------- -------------
-1.2.3.4      "C:/"         FAILED
-1.2.3.4      "-/Scripts"   FAILED
-1.2.3.4      "G:/"         FAILED
-1.2.3.4      SystemState   FAILED
+HOSTNAME                  DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS   KB/s
+--------------------------------------- ------------------------------------- -------------
+1.2.3.4      "C:/"                      FAILED
+1.2.3.4      "E:/Replication/Scripts"   FAILED
+1.2.3.4      "G:/"                      FAILED
+1.2.3.4      SystemState                FAILED
 
 (brought to you by Amanda version x.y.z)
index a57d482d5b934096b0a2fd6092c33dd6379cc3e7..39ba2108473193db4e139474bc941dcf8e56a480 100644 (file)
@@ -67,13 +67,13 @@ USAGE BY TAPE:
 
 DUMP SUMMARY:
                                        DUMPER STATS               TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
--------------------------- ------------------------------------- --------------
-cnc.slikon.l /             MISSING --------------------------------------------
-cnc.slikon.l /boot       0   20670   17245   83.4    0:04 4052.7   0:01 23216.5
-ns-new.sliko //usr/local 0      30       1    3.3    0:00   24.6   0:00   153.5
-ns-new.sliko /boot         FAILED
-ns-new.sliko /home         MISSING --------------------------------------------
+HOSTNAME            DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
+--------------------------------- ------------------------------------- --------------
+cnc.slikon.local    /             MISSING --------------------------------------------
+cnc.slikon.local    /boot       0   20670   17245   83.4    0:04 4052.7   0:01 23216.5
+ns-new.slikon.local //usr/local 0      30       1    3.3    0:00   24.6   0:00   153.5
+ns-new.slikon.local /boot         FAILED
+ns-new.slikon.local /home         MISSING --------------------------------------------
 
 (brought to you by Amanda version x.y.z)
 
index 0e477e04586ff2f134fd8202243b023c49e3b78d..d3c55f18017aa2a1dc298627e5d3b01c58e9d3fc 100644 (file)
@@ -66,8 +66,8 @@ NOTES:
 
 DUMP SUMMARY:
                                        DUMPER STATS               TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
--------------------------- ------------------------------------- --------------
-jamon.slikon /var        0 2985670  268356    9.0    0:53 5029.5   0:16 17213.6
+HOSTNAME           DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
+-------------------------------- ------------------------------------- --------------
+jamon.slikon.local /var        0 2985670  268356    9.0    0:53 5029.5   0:16 17213.6
 
 (brought to you by Amanda version x.y.z)
index 6286eb8874181e7a312df14c6e2711b5667588b4..006218b5f448493bc7232369dc68be88052d768b 100644 (file)
@@ -134,8 +134,8 @@ NOTES:
 
 DUMP SUMMARY:
                                        DUMPER STATS                TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS    KB/s MMM:SS    KB/s
--------------------------- ------------------------------------------ --------------
-lead.zmanda. -asurements 0 539140000 258237053 47.9 817:48 10987.7 57:16 75156.3
+HOSTNAME                  DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS    KB/s MMM:SS    KB/s
+--------------------------------------- ------------------------------------------ --------------
+lead.zmanda.com /tensile-measurements 0 539140000 258237053 47.9 817:48 10987.7 57:16 75156.3
 
 (brought to you by Amanda version x.y.z)
index cf5ad06c5fea3218caa121390d48c2703b68a1aa..7cebd7ef81fd69b1a58fd5295f53f836d28840d7 100644 (file)
@@ -66,9 +66,9 @@ NOTES:
 
 DUMP SUMMARY:
                                        DUMPER STATS               TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
--------------------------- ------------------------------------- --------------
-jamon.slikon /var        0 2985670  268356    9.0    0:53 5029.5   0:16 17213.6
+HOSTNAME           DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
+-------------------------------- ------------------------------------- --------------
+jamon.slikon.local /var        0 2985670  268356    9.0    0:53 5029.5   0:16 17213.6
 
 (brought to you by Amanda version x.y.z)
 
index 5c529c4ab69bd0beaa6346b792ce30e9a0ccbb2a..cc0ff9d9b0e60722e1d96f3e68e634609179e0e0 100644 (file)
@@ -84,9 +84,9 @@ sendbackup: end
 
 DUMP SUMMARY:
                                        DUMPER STATS               TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
--------------------------- ------------------------------------- --------------
-bsdfw.slikon /           0 5401240 2293470   42.5   29:36 1305.4   2:37 14596.6
+HOSTNAME           DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
+-------------------------------- ------------------------------------- --------------
+bsdfw.slikon.local /           0 5401240 2293470   42.5   29:36 1305.4   2:37 14596.6
 
 (brought to you by Amanda version x.y.z)
 
index 314b0687c56d89f7bf49a3c187c9300753e3ba40..b51dc3023d60abbcf2fc47c746cbe0d97ec1dfd3 100644 (file)
@@ -45,8 +45,8 @@ USAGE BY TAPE:
 
 DUMP SUMMARY:
                                        DUMPER STATS               TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
--------------------------- ------------------------------------- -------------
-ns-new.sliko /boot         SKIPPED -------------------------------------------
+HOSTNAME            DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS    KB/s
+--------------------------------- ------------------------------------- -------------
+ns-new.slikon.local /boot         SKIPPED -------------------------------------------
 
 (brought to you by Amanda version x.y.z)
index 9328d6a031b03efedc16de01626db8f54783c96e..1e06ca62d365687920127dcbec20e4b24c5685f7 100644 (file)
@@ -87,9 +87,9 @@ NOTES:
 
 DUMP SUMMARY:
                                        DUMPER STATS                 TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
--------------------------- -------------------------------------- ---------------
-euclid       -server-src 0   21830   21830    --     0:00 82641.8   0:00 244170.0
+HOSTNAME         DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS    KB/s MMM:SS     KB/s
+------------------------------ -------------------------------------- ---------------
+euclid       /A/b/server-src 0   21830   21830    --     0:00 82641.8   0:00 244170.0
 
 (brought to you by Amanda version x.y.z)
 
index 9503a71d1c4f945a9695a3e9e5bfeeb3da5154cf..6bc536f343459e184c35d4f0bc13f3d2b4540900 100644 (file)
@@ -105,13 +105,13 @@ NOTES:
 
 
 DUMP SUMMARY:
-                                       DUMPER STATS                TAPER STATS
-HOSTNAME     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS     KB/s
--------------------------- ------------------------------------- ---------------
-strontium    /etc        1     270     270    --     0:00 1146.3   0:00 140918.6
-strontium    -me/elantra 1      10      10    --     0:00   65.6   0:00   9033.4
-strontium    /local      0      20      20    --     0:00  133.9   0:00  27624.3
-strontium    -ository_13 1    1350    1350    --     0:01 2568.5   0:00 175006.5
+                                                                          DUMPER STATS                TAPER STATS
+HOSTNAME                                                     DISK        L ORIG-kB  OUT-kB  COMP%  MMM:SS   KB/s MMM:SS     KB/s
+--------------------------------------------------------------------------- ------------------------------------- ---------------
+strontium    /etc                                                         1     270     270    --     0:00 1146.3   0:00 140918.6
+strontium    /home/elantra                                                1      10      10    --     0:00   65.6   0:00   9033.4
+strontium    /local                                                       0      20      20    --     0:00  133.9   0:00  27624.3
+strontium    /zones/data/strontium.example.com/repositories/repository_13 1    1350    1350    --     0:01 2568.5   0:00 175006.5
 
 (brought to you by Amanda version x.y.z)
 
index ccafbd7957d6c473a91e6bf2dc27f8f4184eabbb..540492b1c9f843585955b320eefea91333453b7a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7d90484c6202039d7c92a787e0841a11aa3bfcf8..3e889e7d09c034195308cb59e35e7d27ea2c5904 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 41367801d1a9fa102446873d49ac92402e28a795..d54617af108c03de57ef03fc4c10cd6033c5e18f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f08ecf3636c6a9cb437c80df039cf13f680795f8..438f9ee02e1bb01e005ff5f5d4bb2abd41e0fd7a 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index d77983fe9054bf1245965335a1e3b25ebb3850f7..dd88a1ac356316fd5969819688914f1086c99adb 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index e2bedf9fe834ce41d63a2fc7c049d29fe29b263d..6d154e7ecc1f11d04e6dd9add724bae7a42da8aa 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 84a4970a8fa19d9c15e520dd7a2228a0b8fbdf60..ffc81f6f94f3bf6518028c4c78420664915db646 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 285118feedf1cc202f00f4a18f3dc8ed5d5c5a84..9e1318ba8911ed9673d68beb637d9e6470b76fa9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 311e6331a9fcf326e15265242be581dfacdff5e9..6451a933b5b683ac755915af18698bbafe97c492 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 4f56fb19c03375807c7e35711cd28d2815e09455..6b76e096d08edb2e6d69e8456238c2beb8a4861e 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 17a63e437d75a42d5f33527fddfc8cd754f9ff30..9e56234aa66c2c6df1d1eb2f0f8aa16812f2f781 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -643,7 +643,7 @@ taper_cmd("START-SCAN worker0 $handle");
 taper_cmd("NEW-TAPE worker0 $handle");
 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
        "got proper NEW-TAPE worker0 $handle") or die;
-like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes 0 kps [\d.]+\]" "" "No space left on device, splitting not enabled"$/,
+like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes 0 kps [\d.]+\]" "" "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$/,
        "got PARTIAL") or die;
 # retry on the next tape
 $handle = "11-88899";
@@ -671,7 +671,7 @@ check_logs([
     qr(^INFO taper Slot 1 without label can be labeled$),
     qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
     qr(^PARTPARTIAL taper TESTCONF01 1 localhost /var/log $datestamp 1/-1 0 \[sec [\d.]+ bytes 983040 kps [\d.]+\] "No space left on device"$),
-    qr(^PARTIAL taper localhost /var/log $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+\] "No space left on device, splitting not enabled"$),
+    qr(^PARTIAL taper localhost /var/log $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+\] "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$),
     qr(^INFO taper tape TESTCONF01 kb 0 fm 1 \[OK\]$),
     qr(^INFO taper Slot 2 without label can be labeled$),
     qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
@@ -1201,7 +1201,7 @@ taper_cmd("START-SCAN worker0 $handle");
 taper_cmd("NEW-TAPE worker0 $handle");
 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
        "got proper NEW-TAPE worker0 $handle") or die;
-like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes \d* kps [\d.]+ orig-kb 1612\]" "" "No space left on device, splitting not enabled"$/,
+like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes \d* kps [\d.]+ orig-kb 1612\]" "" "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$/,
        "got PARTIAL for filenum 1") or die;
 taper_cmd("QUIT");
 wait_for_exit();
@@ -1210,7 +1210,7 @@ check_logs([
     qr(^INFO taper Slot 1 without label can be labeled$),
     qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
     qr(^PARTPARTIAL taper TESTCONF01 1 localhost /usr $datestamp 1/-1 0 \[sec [\d.]+ bytes 983040 kps [\d.]+ orig-kb 1612\] \"No space left on device\"$),
-    qr(^PARTIAL taper localhost /usr $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+ orig-kb 1612\] "No space left on device, splitting not enabled"$),
+    qr(^PARTIAL taper localhost /usr $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+ orig-kb 1612\] "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$),
     qr(^INFO taper tape TESTCONF01 kb 0 fm 1 \[OK\]$),
 ], "without LEOM and without allow-split logged correctly");
 cleanup_log();
index d396ddd4456e3c15d54c731cd57060d931cb1824..854aa64fe859b71cb1a5f547497556f6828b04e7 100644 (file)
@@ -190,7 +190,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -735,6 +736,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 9272624febe18eff493f57414550009273d110f4..775c21cdd67b5e7a9b3856d7a4adadad2008ce84 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amaddclient
 .\"    Author: Kevin Till <kevin.till@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMADDCLIENT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMADDCLIENT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 85513f0584a1fd5223027f2422ccddd3f55526fd..5e829857e92a9a62f32bb4a0fb6041b2038ed819 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amadmin
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMADMIN" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMADMIN" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -31,7 +31,7 @@
 amadmin \- administrative interface to control Amanda backups
 .SH "SYNOPSIS"
 .HP \w'\fBamadmin\fR\ 'u
-\fBamadmin\fR [\fB\-o\fR\ \fIconfigoption\fR...] \fIconfig\fR \fIcommand\fR [\fIcommand_options\fR...]
+\fBamadmin\fR [\-\-version] [\-\-no\-default] [\-\-print\-source] [\fB\-o\fR\ \fIconfigoption\fR...] \fIconfig\fR \fIcommand\fR [\fIcommand_options\fR...]
 .SH "DESCRIPTION"
 .PP
 \fBAmadmin\fR
@@ -42,6 +42,30 @@ Amanda configuration\&.
 See the
 \fBamanda\fR(8)
 man page for more details about Amanda\&.
+.SH "OPTIONS"
+.PP
+\fB\-\-version\fR
+.RS 4
+Print the version and exit\&.
+.RE
+.PP
+\fB\-\-no\-default\fR
+.RS 4
+Do not print default values for
+\fBconfig\fR
+and
+\fBdisklist\fR
+commands\&.
+.RE
+.PP
+\fB\-\-print\-source\fR
+.RS 4
+Print where a value is definedi for
+\fBconfig\fR
+and
+\fBdisklist\fR
+commands\&.
+.RE
 .SH "COMMANDS"
 .PP
 Commands that take a
index c01a2d4396d572076749ca4a198e826aba2cf2f6..36f9e89664a9421943a2e63e534ef0bbf8e2038b 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amaespipe
 .\"    Author: Kevin Till <kevin.till@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMAESPIPE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMAESPIPE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a43f7f86827193b21625cc6ca6937695b73cba80..a52a711224f413c6c0623eec32a1373910123a4e 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-applications
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-APPLICATIONS" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-APPLICATIONS" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index e673887c804d1c6cdbb7a5702a78fb4f94209f41..19cfe808dc59b64dd91f26f7149f2a948f56ff8e 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-archive-format
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: File formats and conventions
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-ARCHIVE\-FOR" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions"
+.TH "AMANDA\-ARCHIVE\-FOR" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index b9d39336fac341641f593adb69ae4f90e33b6646..c4d9db13f5763f85eeb682b577d6651c4b52f7a0 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-auth
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-AUTH" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-AUTH" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 230657fa9ff744cd87aa08ba233c669f1d1bec40..1cef29efc8dbcbcbe38ad3c25c8bb0b57dee4459 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-changers
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-CHANGERS" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-CHANGERS" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index c907c1903c7df1d91c7f04c8d4a6192cd120e2f1..b040bd35cb33fa933f97857a24dbd021bb0da2e5 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-client.conf
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: File formats and conventions
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-CLIENT\&.CON" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions"
+.TH "AMANDA\-CLIENT\&.CON" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 44850b0df48116762722416a21705f02aa0d4276..afea373248bb71572fa83dd1b78226325ce7eea3 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-compatibility
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-COMPATIBILIT" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-COMPATIBILIT" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 732fce50d69a19d2141a9dbc8f531c4909ab9952..3248c19b1659d5c8a7aa95d637f6c613225e5108 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-devices
 .\"    Author: Ian Turner <ian@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-DEVICES" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-DEVICES" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -397,6 +397,30 @@ device\-property "S3_ACCESS_KEY" "27D3B8C6C4E7AA423C2B37C72A0D22C8"
 device\-property "S3_SECRET_KEY" "agphc2Q7Zmxragphc2RmO2xragpzZGY7a2xqCgr"
 .fi
 .PP
+CLIENT_ID
+.RS 4
+
+(read\-write) The client_id for oauth2\&.
+.RE
+.PP
+CLIENT_SECRET
+.RS 4
+
+(read\-write) The client_secret for oauth2\&.
+.RE
+.PP
+CREATE\-BUCKET
+.RS 4
+
+(read\-write) Default: yes\&. If amanda create/delete the bucket\&.
+.RE
+.PP
+REFRESH_TOKEN
+.RS 4
+
+(read\-write) The refresh\-token for oauth2\&.
+.RE
+.PP
 MAX_RECV_SPEED
 .RS 4
 
@@ -413,6 +437,13 @@ data to S3\&.  If the average speed exceeds this value, the device will stop
 writing long enough to bring the average below this value\&.
 .RE
 .PP
+S3_MULTI_DELETE
+.RS 4
+
+(read\-write) If the server support the multi delete protocol (only Amazon S3),
+default is "YES"\&. If it fail, it revert to single delete\&.
+.RE
+.PP
 NB_THREADS_BACKUP
 .RS 4
 
@@ -428,7 +459,31 @@ NB_THREADS_RECOVERY
 OPENSTACK_SWIFT_API
 .RS 4
 
- (read\-write) Set to yes if it is an openstack storage device\&.
+ (read\-write) Deprecated, set "STORAGE_API to "SWIFT\-1\&.0"\&.
+.RE
+.PP
+PROXY
+.RS 4
+
+ (read\-write) The proxy hostname or IP in the format "host[:port]"\&.
+.RE
+.PP
+PASSWORD
+.RS 4
+
+(read\-write) The password (for swift v2)\&.
+.RE
+.PP
+PROJECT\-ID
+.RS 4
+
+(read\-write) The projectid (for google)\&.
+.RE
+.PP
+REUSE\-CONNECTION
+.RS 4
+
+(read\-write) Default: YES\&. Set it to "NO" if reusing a connection cause some bug, this is sometime the case with big block size\&.
 .RE
 .PP
 S3_ACCESS_KEY
@@ -512,6 +567,35 @@ S3_USER_TOKEN
 (read\-write) This property specifies the user token for Amanda Enterprise Edition customers\&.
 .RE
 .PP
+STORAGE_API
+.RS 4
+
+ (read\-write) Which API to use for the cloud:
+.nf
+  S3            Amanzon S3 api
+  SWITF\-1\&.0     Openstack swift v1\&.0
+  SWIFT\-2\&.0     Openstack swift v2\&.0
+.fi
+.RE
+.PP
+TENANT_ID
+.RS 4
+
+(read\-write) The tenant_id (for swift v2)\&.
+.RE
+.PP
+TENANT_NAME
+.RS 4
+
+(read\-write) The tenant_name (for swift v2)\&.
+.RE
+.PP
+USERNAME
+.RS 4
+
+(read\-write) The username (for swift v2)\&.
+.RE
+.PP
 VERBOSE
 .RS 4
 
@@ -627,6 +711,13 @@ and
 \fBNDMP_PASSWORD\fR
 set the username and password with which to access the NDMP server\&. The default for both is "ndmp"\&.
 .PP
+INDIRECT
+.RS 4
+
+(read\-write) Set to "yes" if the ndmp server doesn\*(Aqt allow to set a window length to 0\&.
+The default is "no"\&.
+.RE
+.PP
 NDMP_AUTH
 .RS 4
 
index 682da04fad14ac9efb3f6ea8722b055adb8cf9d4..c3e801971d8a24ed37cbf9099ebef8a3999a99c3 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-interactivity
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-INTERACTIVIT" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-INTERACTIVIT" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 8a5a7dc9ba69280e1ceab5929016ea66b1c116e7..5777aec93cb843ac9a02895aec42414717f4baa1 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-match
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-MATCH" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-MATCH" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 762698d6ea344a32c6914c07fb030d104ede2db2..62e5d1ac20801144f6a07a74712c1091f29a94da 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-scripts
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-SCRIPTS" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-SCRIPTS" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index e3801486cf3726b78344144aa45ab99ce65e0f01..e0da8fd939b7df0fa5c3a7aafce105ea0fd58542 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda-taperscan
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: Miscellanea
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\-TAPERSCAN" "7" "02/21/2012" "Amanda 3\&.3\&.1" "Miscellanea"
+.TH "AMANDA\-TAPERSCAN" "7" "07/25/2012" "Amanda 3\&.3\&.2" "Miscellanea"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a0fac58d13ec9883fdb36e9c455bfcc61a2321d8..d18764da23c2c20da3850433e53e28afd0609849 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMANDA" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 0fba0e25cf37c68fb7661bb9d973366f0b972736..d71edaeabe2212fa2c12b068f3141e6cb929c429 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amanda.conf
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: File formats and conventions
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMANDA\&.CONF" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions"
+.TH "AMANDA\&.CONF" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -887,7 +887,7 @@ setting\&.
 .PP
 \fBcolumnspec\fR \fIstring\fR
 .RS 4
-default: "HostName=0:12:12,Disk=1:11:11,Level=1:1:1,OrigKB=1:\-7:0,OutKB=1:\-7:0,Compress=1:\-6:1,DumpTime=1:\-7:7,Dumprate=1:\-6:1,TapeTime=1:\-6:6,TapeRate=1:\-6:1"
+default: "HostName=0:\-12:12,Disk=1:\-11:11,Level=1:\-1:1,OrigKB=1:\-7:0,OutKB=1:\-7:0,Compress=1:\-6:1,DumpTime=1:\-7:7,Dumprate=1:\-6:1,TapeTime=1:\-6:6,TapeRate=1:\-6:1"
 .sp
 Defines the width of columns
 \fBamreport\fR
@@ -1130,6 +1130,11 @@ The error messages that appear in amrecover are intentionally vague to avoid inf
 .sp
 Recovery limits can be refined on a per\-DLE basis using the dumptype parameter of the same name\&. Note that the default value will apply to any dumpfiles for disks which no longer appear in the disklist; thus leaving the global parameter at its default value but setting it for all DLEs is not sufficient to maintain secure backups\&.
 .RE
+.PP
+\fBtmpdir\fR \fIstring\fR
+.RS 4
+Default: none (system default)\&. Set it to a directory with lots of free space if sort in amindexd fail with \*(AqNo space left on device\*(Aq\&.
+.RE
 .SH "HOLDINGDISK SECTION"
 .PP
 The
@@ -1650,6 +1655,12 @@ Default:
 \fI10000\fR\&. The maximum number of day for a promotion, set it 0 if you don\*(Aqt want promotion, set it to 1 or 2 if your disks get overpromoted\&.
 .RE
 .PP
+\fBmax\-warnings\fR \fIint\fR
+.RS 4
+Default:
+\fI20\fR\&. The maximum number of error lines in the report for a dle\&. A value of \*(Aq0\*(Aq means unlimited\&. This is useful to reduce the size of the log file and the size of the report\&. All errors are put in separate files if a dle have more errors\&.
+.RE
+.PP
 \fBpriority\fR [ \fBlow\fR | \fBmedium\fR | \fBhigh\fR ]
 .RS 4
 Default:
@@ -2443,7 +2454,7 @@ Default: not set\&. A comment string describing this taperscan\&.
 \fBplugin\fR \fIstring\fR
 .RS 4
 No default\&. Must be set to the name of the taperscan module\&. See
-<man></man>
+\fBamanda-taperscan\fR(7)
 for a list of defined taperscan modules\&.
 .RE
 .PP
index 18e802bc3bc7cf4bf1bcef409d93850e70fb82a9..460de8a7767d2294f7dab363742d740daed642a9 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amarchiver
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMARCHIVER" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMARCHIVER" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a8d414cc092f2bba8729d021f8069de0152cda15..717690fdfa5584ee096780012fbfe4d6f4fa5854 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcheck
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCHECK" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCHECK" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 1fda719ca9236f147b68d5089e1fcba3e511225f..faa358628c8a010b4b6df3e37354f73aa76ba733 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcheckdb
 .\"    Author: Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCHECKDB" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCHECKDB" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 7a73f7d8a9c0c6cbaee156406abb7eda06d97d0c..0879e843e4ac4855d394a30d185e830b3758385e 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcheckdump
 .\"    Author: Ian Turner <ian@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCHECKDUMP" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCHECKDUMP" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 600e2725afe5f0d517f79af646fd4dd3360a1347..5f6376d8bc007eb4a1c2e089524df2cafab8247d 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcleanup
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCLEANUP" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCLEANUP" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index e7409b6b14e07060fea834c62108fb6a73e13f7b..80568c95e9838b3d14f8f1c328ac26d52054ff2d 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcleanupdisk
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCLEANUPDISK" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCLEANUPDISK" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index e2c19b954b855e6b2e1ace7b9a06a6196d3c71d4..1f53dec20225ed50f74721be225d568090ffa09b 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcrypt-ossl-asym
 .\"    Author: Kevin Till <kevin.till@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCRYPT\-OSSL\-ASYM" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCRYPT\-OSSL\-ASYM" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 4f23318b87541724cf606ae55436f6253f36cfb4..598913ea08fb96e1c0abf12e2ec5c6c7db2edfef 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcrypt-ossl
 .\"    Author: Kevin Till <kevin.till@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCRYPT\-OSSL" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCRYPT\-OSSL" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a8cadc1a58a5b966a6ab50e25691ce72096c6cd5..294a3c687bb5bdad59a64532701bd008c6692ca2 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcrypt
 .\"    Author: Kevin Till <kevin.till@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCRYPT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCRYPT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 282ac80ca4be63e877a8254b90259b7bc1a7fe89..60ac4d785b58270880d2eed5bab4d181787a4b45 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amcryptsimple
 .\"    Author: Kevin Till <kevin.till@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMCRYPTSIMPLE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMCRYPTSIMPLE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 7dce8a98f88a435bec4ab9650d963ace309741f1..c3c4fc4be66a89587a8c733fa71ce6ec2a33b6f5 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amdevcheck
 .\"    Author: Ian Turner <ian@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMDEVCHECK" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMDEVCHECK" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 59d1e9c4e42906f0fc8bfc0202446669a4f4d3b5..47365552048947ce20c637f4935be0a1d588b506 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amdump
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMDUMP" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMDUMP" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 8408481b211532d348698cd064ee4caafc01fafc..05dab6fbb8f2a98ab4b7381106ce3a3dd3dbe672 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amdump_client
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMDUMP_CLIENT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMDUMP_CLIENT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 63e155a16d8b4eaad4a3d7e47458a0b5b6a266fb..b039c3721341e161409da6112d2b6743007ab17f 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amfetchdump
 .\"    Author: John Stange <building@nap.edu>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMFETCHDUMP" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMFETCHDUMP" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 amfetchdump \- extract backup images from multiple Amanda tapes\&.
 .SH "SYNOPSIS"
 .HP \w'\fBamfetchdump\fR\ 'u
-\fBamfetchdump\fR [\-c|\-C|\-L] [\-p|\-n] [\-a] [\-O\ \fIdirectory\fR] [\-d\ \fIdevice\fR] [\-h] [\-\-header\-file\ \fIfilename\fR] [\-\-header\-fd\ \fIfd\fR] [\fB\-o\fR\ \fIconfigoption\fR...] \fIconfig\fR \fIhostname\fR [\fIdisk\fR\ [\ \fIdate\fR\ [\ \fIlevel\fR\ [\ \fIhostname\fR\ [\&.\&.\&.]\ ]\ ]\ ]]
+\fBamfetchdump\fR [\-c | \-C | \-l] [\-p | \-n] [\-a] [\-O\ \fIdirectory\fR] [\-d\ \fIdevice\fR] [\-h | \-\-header\-file\ \fIfilename\fR | \-\-header\-fd\ \fIfd\fR] [\-\-decompress | \-\-no\-decompress | \-\-server\-decompress | \-\-client\-decompress] [\-\-decrypt | \-\-no\-decrypt | \-\-server\-decrypt | \-\-client\-decrypt] [\fB\-o\fR\ \fIconfigoption\fR...] \fIconfig\fR \fIhostname\fR [\fIdisk\fR\ [\ \fIdate\fR\ [\ \fIlevel\fR\ [\ \fIhostname\fR\ [\&.\&.\&.]\ ]\ ]\ ]]
 .SH "DESCRIPTION"
 .PP
 \fBAmfetchdump\fR
-pulls one or more matching dumps from tape or from the holding disk, handling the reassembly of multi\-tape split dump files as well as any tape autochanger operations\&.
+pulls one or more matching dumps from tape or from the holding disk, handling the reassembly of multi\-tape split dump files as well as any tape autochanger operations\&. The dump are by default decompressed and decrypted\&.
 .PP
 It will automatically use the Amanda catalog to locate available dumps on tape, in the same way that the
 \fBfind\fR
@@ -105,11 +105,51 @@ Compress output, fastest method available\&.
 Compress output, smallest file size method available\&.
 .RE
 .PP
+\fB\-\-decompress\fR
+.RS 4
+Always do the decompression, this is the default\&.
+.RE
+.PP
+\fB\-\-no\-decompress\fR
+.RS 4
+Never do the decompression\&.
+.RE
+.PP
+\fB\-\-server\-decompress\fR
+.RS 4
+Do the decompression only if the compression was done on the server\&.
+.RE
+.PP
+\fB\-\-client\-decompress\fR
+.RS 4
+Do the decompression only if the compression was done on the client\&.
+.RE
+.PP
+\fB\-\-decrypt\fR
+.RS 4
+Always do the decryption, this is the default\&.
+.RE
+.PP
+\fB\-\-no\-decrypt\fR
+.RS 4
+Never do the decryption\&.
+.RE
+.PP
+\fB\-\-server\-decrypt\fR
+.RS 4
+Do the decryption only if the encryption was done on the server\&.
+.RE
+.PP
+\fB\-\-client\-decrypt\fR
+.RS 4
+Do the decryption only if the encryption was done on the client\&.
+.RE
+.PP
 \fB\-l\fR
 .RS 4
-Leave dumps in the compressed/uncompressed state in which they were found on tape\&. By default,
-\fBamfetchdump\fR
-will automatically uncompress when restoring\&.
+Leave dumps in the compressed/uncompressed and encrypted/unencrypted state in which they were found on tape\&. It is a synonym for
+\fB\-\-no\-decompression\fR
+\fB\-\-no\-decryption\fR
 .RE
 .PP
 \fB\-a\fR
index a36d55b25d3f4ac600ac9e809a52ea03f0a3cb6d..d37d0631a156ba1f2b4c9b51ab8c01d43b047f80 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amflush
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMFLUSH" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMFLUSH" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index adcc61d346cff59ceb45e5c183c8a23d0bb54b56..fe77723c1b0665bab71fe2d25395f3e568c491ae 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amgetconf
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMGETCONF" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMGETCONF" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index fc8e3e4e0798467fd5a0eee115feae577b1daa9e..6489a6d0508460ea491dff9bd6ab4393376bcd5e 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amgpgcrypt
 .\"    Author: Kevin Till <kevin.till@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMGPGCRYPT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMGPGCRYPT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index e6d1f8e5537668a2fde976cd6a41fe41f00a8678..9cc2abdd6e06202978f0d32a98052c8f5bc1e25f 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amgtar
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMGTAR" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMGTAR" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -87,6 +87,13 @@ GNUTAR\-PATH
 The path to the gnutar binary\&.  The default is set when Amanda is built\&.
 .RE
 .PP
+IGNORE\-ZEROS
+.RS 4
+
+If "YES" (the default), use the \fI\-\-ignore\-zeros\fR argument of gtar on recovery,
+set it to "NO" if you do not want that argument\&.
+.RE
+.PP
 INCLUDE\-LIST\-GLOB
 .RS 4
 
@@ -251,7 +258,7 @@ A dumptype using this application might look like:
 Note that the
 \fIprogram\fR
 parameter must be set to
-\fI"APPLCIATION"\fR
+\fI"APPLICATION"\fR
 to use the
 \fIapplication\fR
 parameter\&.
index 66c1862d30d47bda780ba9aa3e7e2c56687aed27..0d8203cf2a89c15002f464b8db92e8a0f903066a 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amlabel
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMLABEL" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMLABEL" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 8041bb8955e6eacdc830c1b476843463c5b27802..dc93d120092e47f192fc4f969b9efc317aedd645 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amoverview
 .\"    Author: Stefan G. Weichinger <sgw@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMOVERVIEW" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMOVERVIEW" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 2ef913a5abbb3ef9a737e3f1207eb4aab0e216b1..a51fbf304f66ba5e61160b1a3925b1ba17c93b97 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: ampgsql
 .\"    Author: Nikolas Coukouma <atrus@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMPGSQL" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMPGSQL" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a26efa0da1c067dd7090ec96a0ee8bbd7c3f65cd..5b8b4e8e97a69301cedc9175c55596d48647d4eb 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amplot
 .\"    Author: Olafur Gudmundsson <ogud@tis.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMPLOT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMPLOT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 66133d0fcfa902b43002c03969dd211327193c09..81e9894af2a921734a72cbd123e9668f0bf4e3ac 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amraw
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMRAW" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMRAW" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 6c6dd4de0c71a944bb7081b0dd18db316cca7490..c52e7659fd767bf0a417a78046b63992c7738245 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amrecover
 .\"    Author: Alan M. McIvor <alan@kauri.auck.irl.cri.nz>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMRECOVER" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMRECOVER" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 95b8a7f9dfe3dc7bac2143d796756f824da25133..dd3ccdab239a944e4227e1d3ac48fa2d73adb61b 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amreport
 .\"    Author: Stefan G. Weichinger <sgw@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMREPORT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMREPORT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a6bb8e9ea8999ae81296e02ff54c7de2cc185f85..2dfb3b50f4c5fa47bf8f7326ae5ebe2d5d28a56c 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amrestore
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMRESTORE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMRESTORE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 66699bfad47bf30560d42e7ad5e58663ed20ea6c..18c67e467927fc49cb97b51ab5dfb519dab8c5c2 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amrmtape
 .\"    Author: Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMRMTAPE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMRMTAPE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 291e71f6d1fd6a878f7525a1f6bf9ac6cbb5870d..afd7ae42228f510027cf6c3a868ec1c2ff4365fb 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amsamba
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMSAMBA" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMSAMBA" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a038d9a6b11c55026ccee202a9107e2facc59de0..fb5607d367a16bf9cca4e5f073303914b97f3173 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amserverconfig
 .\"    Author: Kevin Till <kevin.till@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMSERVERCONFIG" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMSERVERCONFIG" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 1cd27688af70e769e76b8d74f4f0edc6837f2c2b..f68ce63540ca50cf3e713cf6dab8a07642b7a807 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amservice
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMSERVICE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMSERVICE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 1434d7ee06487361d8b74c3b6b31b96b1798104c..854757c5fcc8e2de3bb8ca661154ae2bd72a03e6 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amstar
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMSTAR" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMSTAR" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 3c7663e09dd99737bb6e277edb3956e5820d4c91..cf2716c44f174c5a7d61ff4f78446259b302db31 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amstatus
 .\"    Author: Stefan G. Weichinger <sgw@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMSTATUS" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMSTATUS" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index cb6d161bc47eabea97b82c2f591f438ead0dcda5..6e10904beb752cc78636b2d235cd6f1f8456d9e2 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amsuntar
 .\"    Author: Satya Ganga <gast@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMSUNTAR" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMSUNTAR" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index ce9be5c64966d82da5b4e9a9aa466679e2140f5d..3c68faba834064178baf51ed474cab2af0277fd3 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amtape
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMTAPE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMTAPE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a3f8c4ef6875193d4879e2aca52fee5888eb17d6..174dcd0b14beabc7c37fa1053b42546271b912e5 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amtapetype
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMTAPETYPE" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMTAPETYPE" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index baf93a4a13e855b57d71a12a8fd9b02f5eb71ec6..25df1ec65eb9fc58021f238b30cacc3444e97b94 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amtoc
 .\"    Author: Nicolas Mayencourt <Nicolas.Mayencourt@cui.unige.ch>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMTOC" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMTOC" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 8fbc66101eb0129c290e0e7699b3e314b56fba13..8e211a3d35b7f9ac21bae32611cfd4c151ea5b94 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amvault
 .\"    Author: Dustin J. Mitchell <dustin@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMVAULT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMVAULT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index bdaacba22c0e8a722011fd419fca54b09f3f2e39..bef01fb3363e4ac284f532fd1346b3f9380f64da 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amzfs-sendrecv
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMZFS\-SENDRECV" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMZFS\-SENDRECV" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -111,7 +111,7 @@ In this example, a dumptype is defined to use amzfs\-sendrecv application to bac
  }
 
  define dumptype user\-zfs\-sendrecv {
-   program "APPLICATAION"
+   program "APPLICATION"
    application "amzfs_sendrecv"
  }
 .fi
index e32a9abd4a3ab37b051b6efe3d725d4c4c500c20..acdc3f2f78514ca808a65fc695a51034c6bec06f 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: amzfs-snapshot
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "AMZFS\-SNAPSHOT" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "AMZFS\-SNAPSHOT" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 84bd2d4fc3afab0d01142f9e445eef1731763e67..83d9687ff7efcb67392753f4661e418ab7f9ee84 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: disklist
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: File formats and conventions
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "DISKLIST" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions"
+.TH "DISKLIST" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -33,7 +33,19 @@ disklist \- List of partitions to back up for Amanda
 .PP
 The
 \fIdisklist\fR
-file determines which disks will be backed up by Amanda\&. The file usually contains one line per disk:
+file determines which disks will be backed up by Amanda\&. The file contains
+\fBincludefile\fR
+directive or disklist entry (\fBDLE\fR)\&.
+.PP
+\fBincludefile\fR \fIstring\fR
+.RS 4
+Default:
+\fIno default\fR\&. The name of a disklist file to include within the current file\&. Useful for sharing disklist among several configurations\&. Relative pathnames are relative to the configuration directory\&.
+.RE
+.PP
+A
+\fBDLE\fR
+usually contains one line per disk:
 .nf
 \fIhostname diskname\fR [\fIdiskdevice\fR] \fIdumptype\fR [\fIspindle\fR [\fIinterface\fR] ]
 .fi
index bd636da248a4a9b63528286bf9863de617c14a41..4681668d3c532b739ad900635338950c6c808339 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: script-email
 .\"    Author: Jean-Louis Martineau <martineau@zmanda.com>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: System Administration Commands
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "SCRIPT\-EMAIL" "8" "02/21/2012" "Amanda 3\&.3\&.1" "System Administration Commands"
+.TH "SCRIPT\-EMAIL" "8" "07/25/2012" "Amanda 3\&.3\&.2" "System Administration Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 83fce3ecbdb166420ab5c0d1b8613cbfcc4c9cec..eed93ba0b712a8791f575d8ad969be99bc0709b7 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: tapelist
 .\"    Author: James da Silva <jds@amanda.org>
 .\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\"      Date: 02/21/2012
+.\"      Date: 07/25/2012
 .\"    Manual: File formats and conventions
-.\"    Source: Amanda 3.3.1
+.\"    Source: Amanda 3.3.2
 .\"  Language: English
 .\"
-.TH "TAPELIST" "5" "02/21/2012" "Amanda 3\&.3\&.1" "File formats and conventions"
+.TH "TAPELIST" "5" "07/25/2012" "Amanda 3\&.3\&.2" "File formats and conventions"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index 5d0905a5ef265d4df8fee9e1462396918b93a38c..4b4aafd42c6de5b625774b7db66bcd3051e37745 100644 (file)
@@ -30,6 +30,9 @@
 <refsynopsisdiv>
 <cmdsynopsis>
   <command>amadmin</command>    
+    <arg choice='opt'>--version</arg>
+    <arg choice='opt'>--no-default</arg>
+    <arg choice='opt'>--print-source</arg>
     &configoverride.synopsis;
     <arg choice='plain'><replaceable>config</replaceable></arg>
     <arg choice='plain'><replaceable>command</replaceable></arg>
@@ -49,6 +52,26 @@ Amanda configuration.</para>
 man page for more details about Amanda.</para>
 </refsect1>
 
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+ <varlistentry>
+    <term><option>--version</option></term>
+<listitem><para>Print the version and exit.</para></listitem>
+  </varlistentry>
+ <varlistentry>
+    <term><option>--no-default</option></term>
+<listitem><para>Do not print default values for <emphasis remap='B'>config</emphasis>
+and <emphasis remap='B'>disklist</emphasis> commands.</para></listitem>
+  </varlistentry>
+ <varlistentry>
+    <term><option>--print-source</option></term>
+<listitem><para>Print where a value is definedi for <emphasis remap='B'>config</emphasis>
+and <emphasis remap='B'>disklist</emphasis> commands.</para></listitem>
+  </varlistentry>
+
+</variablelist>
+</refsect1>
+
 <refsect1><title>COMMANDS</title>
 <para>Commands that take a <emphasis remap='I'>hostname</emphasis> [ <emphasis remap='I'>disks</emphasis> ]
 parameter pair operate on all disks in the &disklist; for that
index 575b0651c7588526c38bc8d7576fc8a6af452b04..f122e98fa3bb4c4664ac693b1b472ebd5c5eab16 100644 (file)
@@ -423,6 +423,22 @@ device-property "S3_SECRET_KEY" "agphc2Q7Zmxragphc2RmO2xragpzZGY7a2xqCgr"
 
 <!-- PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER -->
 <variablelist>
+ <!-- ==== -->
+ <varlistentry><term>CLIENT_ID</term><listitem>
+(read-write) The client_id for oauth2.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>CLIENT_SECRET</term><listitem>
+(read-write) The client_secret for oauth2.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>CREATE-BUCKET</term><listitem>
+(read-write) Default: yes. If amanda create/delete the bucket.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>REFRESH_TOKEN</term><listitem>
+(read-write) The refresh-token for oauth2.
+</listitem></varlistentry>
  <!-- ==== -->
  <varlistentry><term>MAX_RECV_SPEED</term><listitem>
 (read-write) Maximum speed, in bytes per second, that this device will receive
@@ -434,6 +450,11 @@ reading long enough to bring the average below this value.
 (read-write) Maximum speed, in bytes per second, that this device will send
 data to S3.  If the average speed exceeds this value, the device will stop
 writing long enough to bring the average below this value.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>S3_MULTI_DELETE</term><listitem>
+(read-write) If the server support the multi delete protocol (only Amazon S3),
+default is "YES". If it fail, it revert to single delete.
 </listitem></varlistentry>
  <!-- ==== -->
  <varlistentry><term>NB_THREADS_BACKUP</term><listitem>
@@ -445,7 +466,23 @@ writing long enough to bring the average below this value.
 </listitem></varlistentry>
  <!-- ==== -->
  <varlistentry><term>OPENSTACK_SWIFT_API</term><listitem>
- (read-write) Set to yes if it is an openstack storage device.
+ (read-write) Deprecated, set "STORAGE_API to "SWIFT-1.0".
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>PROXY</term><listitem>
+ (read-write) The proxy hostname or IP in the format "host[:port]".
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>PASSWORD</term><listitem>
+(read-write) The password (for swift v2).
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>PROJECT-ID</term><listitem>
+(read-write) The projectid (for google).
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>REUSE-CONNECTION</term><listitem>
+(read-write) Default: YES. Set it to "NO" if reusing a connection cause some bug, this is sometime the case with big block size.
 </listitem></varlistentry>
  <!-- ==== -->
  <varlistentry><term>S3_ACCESS_KEY</term><listitem>
@@ -507,6 +544,27 @@ for the most up-to-date list.
  <!-- ==== -->
  <varlistentry><term>S3_USER_TOKEN</term><listitem>
 (read-write) This property specifies the user token for Amanda Enterprise Edition customers.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>STORAGE_API</term><listitem>
+ (read-write) Which API to use for the cloud:
+<programlisting>
+  S3            Amanzon S3 api
+  SWITF-1.0     Openstack swift v1.0
+  SWIFT-2.0     Openstack swift v2.0
+</programlisting>
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>TENANT_ID</term><listitem>
+(read-write) The tenant_id (for swift v2).
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>TENANT_NAME</term><listitem>
+(read-write) The tenant_name (for swift v2).
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>USERNAME</term><listitem>
+(read-write) The username (for swift v2).
 </listitem></varlistentry>
  <!-- ==== -->
  <varlistentry><term>VERBOSE</term><listitem>
@@ -634,6 +692,11 @@ access the NDMP server.  The default for both is "ndmp".</para>
 <!-- PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER -->
 <variablelist>
  <!-- ==== -->
+<varlistentry><term>INDIRECT</term><listitem>
+(read-write) Set to "yes" if the ndmp server doesn't allow to set a window length to 0.
+The default is "no".
+</listitem></varlistentry>
+ <!-- ==== -->
 <varlistentry><term>NDMP_AUTH</term><listitem>
 (read-write) Authentication method to use to connect to the NDMP server.  One of
 "md5" (default), "text", "none" (for an empty authentication attempt) or "void" (for
index 33353ebf08aa91167f4ecc34b79f082b9460911c..e8d1fc091597c716e6024c9657eb25e279cf27d4 100644 (file)
@@ -1159,7 +1159,7 @@ is the same as the <amkeyword>amrecover-changer</amkeyword> setting.</para>
   <varlistentry>
   <term><amkeyword>columnspec</amkeyword> <amtype>string</amtype></term>
   <listitem>
-<para> default: "HostName=0:12:12,Disk=1:11:11,Level=1:1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1"</para>
+<para> default: "HostName=0:-12:12,Disk=1:-11:11,Level=1:-1:1,OrigKB=1:-7:0,OutKB=1:-7:0,Compress=1:-6:1,DumpTime=1:-7:7,Dumprate=1:-6:1,TapeTime=1:-6:6,TapeRate=1:-6:1"</para>
 <para>Defines the width of columns <emphasis remap='B'>amreport</emphasis>
 should use.
 <emphasis remap='I'>String</emphasis>
@@ -1465,6 +1465,13 @@ Range is inclusive.</para>
   </listitem>
   </varlistentry>
 
+  <varlistentry>
+  <term><amkeyword>tmpdir</amkeyword> <amtype>string</amtype></term>
+  <listitem>
+<para>Default: none (system default).  Set it to a directory with lots of free
+space if sort in amindexd fail with 'No space left on device'.</para>
+  </listitem>
+  </varlistentry>
 </variablelist>
 </refsect1>
 
@@ -2114,6 +2121,17 @@ See also the main section parameter <amkeyword>inparallel</amkeyword>.</para>
 <amdefault>10000</amdefault>.
 The maximum number of day for a promotion, set it 0 if you don't want
 promotion, set it to 1 or 2 if your disks get overpromoted.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><amkeyword>max-warnings</amkeyword> <amtype>int</amtype></term>
+  <listitem>
+<para>Default:
+<amdefault>20</amdefault>.
+The maximum number of error lines in the report for a dle. A value of '0'
+means unlimited. This is useful to reduce the size of the log file and the
+size of the report. All errors are put in separate files if a dle have more
+errors.</para>
   </listitem>
   </varlistentry>
   <varlistentry>
@@ -3081,7 +3099,7 @@ A comment string describing this taperscan.</para>
   <varlistentry>
   <term><amkeyword>plugin</amkeyword> <amtype>string</amtype></term>
   <listitem>
-<para>No default. Must be set to the name of the taperscan module.  See <man name="amanda-taperscan" vol="7" /> for a list of defined taperscan modules.</para>
+<para>No default. Must be set to the name of the taperscan module.  See <manref name="amanda-taperscan" vol="7" /> for a list of defined taperscan modules.</para>
   </listitem>
   </varlistentry>
   <varlistentry>
index 89ee3c73dce93ffbd1d91d5707c5a1a13480c49e..b934b2d6e68a98cc8585bb17e1ac1ee17fc7fb59 100644 (file)
 <refsynopsisdiv>
 <cmdsynopsis>
   <command>amfetchdump</command>
-    <arg choice='opt'>-c|-C|-L</arg>
-    <arg choice='opt'>-p|-n</arg>
+    <group choice='opt'>
+      <arg choice='plain'>-c</arg>
+      <arg choice='plain'>-C</arg>
+      <arg choice='plain'>-l</arg>
+    </group>
+    <group choice='opt'>
+      <arg choice='plain'>-p</arg>
+      <arg choice='plain'>-n</arg>
+    </group>
     <arg choice='opt'>-a</arg>
     <arg choice='opt'>-O <replaceable>directory</replaceable></arg>
     <arg choice='opt'>-d <replaceable>device</replaceable></arg>
-    <arg choice='opt'>-h</arg>
-    <arg choice='opt'>--header-file <replaceable>filename</replaceable></arg>
-    <arg choice='opt'>--header-fd <replaceable>fd</replaceable></arg>
+    <group choice='opt'>
+      <arg choice='plain'>-h</arg>
+      <arg choice='plain'>--header-file <replaceable>filename</replaceable></arg>
+      <arg choice='plain'>--header-fd <replaceable>fd</replaceable></arg>
+    </group>
+    <group choice='opt'>
+      <arg choice='plain'>--decompress</arg>
+      <arg choice='plain'>--no-decompress</arg>
+      <arg choice='plain'>--server-decompress</arg>
+      <arg choice='plain'>--client-decompress</arg>
+    </group>
+    <group choice='opt'>
+      <arg choice='plain'>--decrypt</arg>
+      <arg choice='plain'>--no-decrypt</arg>
+      <arg choice='plain'>--server-decrypt</arg>
+      <arg choice='plain'>--client-decrypt</arg>
+    </group>
     &configoverride.synopsis;
     <arg choice='plain'><replaceable>config</replaceable></arg>
     <arg choice='plain'><replaceable>hostname</replaceable></arg>
@@ -60,7 +81,8 @@
 <para><emphasis remap='B'>Amfetchdump</emphasis>
 pulls one or more matching dumps from tape or from the holding disk,
 handling the reassembly of multi-tape split dump files as well as any
-tape autochanger operations.</para>
+tape autochanger operations. The dump are by default decompressed and decrypted.
+</para>
 
 <para>It will automatically use the Amanda catalog
 to locate available dumps on tape, in the same way that the <emphasis
@@ -132,12 +154,48 @@ prompting for each volume.</para></listitem>
     <listitem><para>Compress output, smallest file size method
     available.</para></listitem>
   </varlistentry>
+  <varlistentry>
+    <term><option>--decompress</option></term>
+    <listitem><para>Always do the decompression, this is the default.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><option>--no-decompress</option></term>
+    <listitem><para>Never do the decompression.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><option>--server-decompress</option></term>
+    <listitem><para>Do the decompression only if the compression was done on
+the server.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><option>--client-decompress</option></term>
+    <listitem><para>Do the decompression only if the compression was done on
+the client.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><option>--decrypt</option></term>
+    <listitem><para>Always do the decryption, this is the default.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><option>--no-decrypt</option></term>
+    <listitem><para>Never do the decryption.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><option>--server-decrypt</option></term>
+    <listitem><para>Do the decryption only if the encryption was done on
+the server.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><option>--client-decrypt</option></term>
+    <listitem><para>Do the decryption only if the encryption was done on
+the client.</para></listitem>
+  </varlistentry>
   <varlistentry>
     <term><option>-l</option></term>
-<listitem><para>Leave dumps in the compressed/uncompressed state in which they
-were found on tape. By default, <emphasis
-remap='B'>amfetchdump</emphasis> will automatically uncompress when
-restoring.</para></listitem>
+<listitem><para>Leave dumps in the compressed/uncompressed and
+encrypted/unencrypted state in which they were found on tape.
+It is a synonym for <option>--no-decompression</option>
+<option>--no-decryption</option></para></listitem>
   </varlistentry>
   <varlistentry>
     <term><option>-a</option></term>
index 852b31ed1f4edf4e462d34033566655b2442c3ab..557e5637db78987380617eb3969cc054307f62b6 100644 (file)
@@ -75,6 +75,11 @@ The directory where gnutar stores the database it uses to generate incremental d
  <!-- ==== -->
  <varlistentry><term>GNUTAR-PATH</term><listitem>
 The path to the gnutar binary.  The default is set when Amanda is built.
+</listitem></varlistentry>
+ <!-- ==== -->
+ <varlistentry><term>IGNORE-ZEROS</term><listitem>
+If "YES" (the default), use the <emphasis>--ignore-zeros</emphasis> argument of gtar on recovery,
+set it to "NO" if you do not want that argument.
 </listitem></varlistentry>
  <!-- ==== -->
  <varlistentry><term>INCLUDE-LIST-GLOB</term><listitem>
@@ -218,7 +223,7 @@ A dumptype using this application might look like:
   }
 </programlisting>
 Note that the <emphasis>program</emphasis> parameter must be set to
-<emphasis>"APPLCIATION"</emphasis> to use the <emphasis>application</emphasis>
+<emphasis>"APPLICATION"</emphasis> to use the <emphasis>application</emphasis>
 parameter.
 </para>
 </refsect1>
index 5fbfbcc254b969fed9425bd719668a739dd78719..f76823b1b98b27bfca910aa0a01bb9e39ffb7782 100644 (file)
@@ -108,7 +108,7 @@ In this example, a dumptype is defined to use amzfs-sendrecv application to back
  }
 
  define dumptype user-zfs-sendrecv {
-   program "APPLICATAION"
+   program "APPLICATION"
    application "amzfs_sendrecv"
  }
 </programlisting>
index d8abab6bdd2324b2430fc05e580ae8714d615d21..80c0c96e02f9962e9d3a058caf929792e9c580f6 100644 (file)
 <refsect1><title>DESCRIPTION</title>
 <para>The
 <emphasis remap='I'>disklist</emphasis>
-file determines which disks will be backed up by Amanda.
-The file usually contains one line per disk:</para>
+file determines which disks will be backed up by Amanda. The file contains
+<amkeyword>includefile</amkeyword> directive or disklist entry
+(<amkeyword>DLE</amkeyword>).</para>
+
+<variablelist remap='TP'>
+  <varlistentry>
+  <term><amkeyword>includefile</amkeyword> <amtype>string</amtype></term>
+  <listitem>
+<para>Default:
+<amdefault>no default</amdefault>.
+The name of a disklist file to include within the current file.
+Useful for sharing disklist among several configurations.
+Relative pathnames are relative to the configuration directory.
+</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>A <amkeyword>DLE</amkeyword> usually contains one line per disk:</para>
 
 <programlisting>
 <emphasis>hostname diskname</emphasis> [<emphasis>diskdevice</emphasis>] <emphasis>dumptype</emphasis> [<emphasis>spindle</emphasis> [<emphasis>interface</emphasis>] ]
index 0d5dbd5804765072bf1db774c228401fe1000c18..f75e3ad4cfe0f0b8f3c7074540cdf0736b49c7af 100644 (file)
@@ -82,7 +82,7 @@
 #NDMOS_OPTIONS = -DNDMOS_OPTION_NO_NDMP4
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -332,7 +332,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -938,6 +939,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index dc0e473a253ef53f975bd39c64549c3efd1a2974..f31f59797e1984eeebd3533850bfdf5627525f30 100644 (file)
@@ -117,6 +117,7 @@ char *help_text[] = {
        "  -o use-eject=N",
        "           -- use eject when unloading tapes (default 0)",
         "  -o tape-tcp=hostname:port -- send the data directly to that tcp port.",
+        "  -o D-agent-fd=<fd> -- file descriptor to read the -D agent.",
        "CONTROL of ROBOT agent parameters",
        "  -R AGENT -- robot agent if different than -T (see AGENT below)",
        "  -m MEDIA -- add entry to media table (see below)",
@@ -660,6 +661,22 @@ handle_long_option (char *str)
                o_config_file = value;
        } else if (strcmp (name, "tape-tcp") == 0 && value) {
                o_tape_tcp = value;
+       } else if (strcmp (name, "D-agent-fd") == 0 && value) {
+               char d_agent[1025];
+               int fd = atoi(value);
+               int size;
+
+               if (AGENT_GIVEN(D_data_agent)) {
+                       error_byebye ("more than one of -D or -D-agent-fd");
+               }
+
+               size = full_read(fd, d_agent, 1024);
+               d_agent[size] = '\0';
+               if (size > 0 && d_agent[size-1] == '\n')
+                   d_agent[size-1] = '\0';
+               if (ndmagent_from_str (&D_data_agent, d_agent)) {
+                       error_byebye ("bad -D-agent-fd argument");
+               }
        } else if (strcmp (name, "tape-limit") == 0) {
                if (!value) {
                        error_byebye ("tape-limit argument is required");
index a1180f0a56afcbe360ee2fa1fdecae411e5a2f0f..d92cfd3575e3129fe961ec94d38fe25800089d2f 100644 (file)
@@ -317,6 +317,10 @@ extern char *ndml_strend(char *s); /* ndml_util.c */
 #define NDMOS_MACRO_NEWN(T,N)  ((T *) NDMOS_API_MALLOC(sizeof (T) * (N)))
 #endif /* !NDMOS_MACRO_NEWN */
 
+#ifndef NDMOS_MACRO_FREE
+#define NDMOS_MACRO_FREE(T) free(T)
+#endif
+
 #ifndef NDMOS_MACRO_ZEROFILL
 #define NDMOS_MACRO_ZEROFILL(P)        NDMOS_API_BZERO(P,sizeof *(P))
 #endif /* !NDMOS_MACRO_ZEROFILL */
index b8e5cd0952d605cda901ea51dafc2d05031f3cec..0c5e72f9d2de02ad9219ee096d7edade3fd069e7 100644 (file)
@@ -83,6 +83,7 @@
 #define NDMOS_MACRO_SRAND() g_random_set_seed(time(0))
 #define NDMOS_MACRO_RAND() g_random_int()
 /* default: NDMOS_MACRO_OK_TAPE_REC_LEN */
+#define NDMOS_MACRO_FREE(T) g_free(T)
 
 /* extra */
 #ifdef assert
index edeb9adab5afe9d795485ac9c9ee764bd87444b9..69a9adbbfa0132766ccf4db36b8e1d7ebc1d5b2c 100644 (file)
@@ -194,6 +194,27 @@ ndmp_9to4_pval_vec_dup (
        return ndmp_9to4_pval_vec (pval9, *pval4_p, n_pval);
 }
 
+int
+ndmp_4to9_pval_free(
+  ndmp9_pval *pval9)
+{
+       CNVT_FREE(pval9, name);
+        CNVT_FREE(pval9, value);
+
+       return 0;
+}
+
+int
+ndmp_4to9_pval_vec_free (
+  ndmp9_pval *pval9,
+  unsigned n_pval)
+{
+       unsigned int    i;
+
+       for (i = 0; i < n_pval; i++)
+               ndmp_4to9_pval_free(&pval9[i]);
+       NDMOS_MACRO_FREE(pval9);
+}
 
 /*
  * ndmp_addr
@@ -271,6 +292,15 @@ ndmp_9to4_addr (
        return 0;
 }
 
+int
+ndmp_9to4_addr_free (
+  ndmp4_addr *addr4)
+{
+       if (addr4->addr_type == NDMP4_ADDR_TCP) {
+           NDMOS_MACRO_FREE(addr4->ndmp4_addr_u.tcp_addr.tcp_addr_val);
+       }
+       return 0;
+}
 
 /*
  * CONNECT INTERFACES
@@ -1569,6 +1599,15 @@ ndmp_4to9_tape_open_request (
        return n_error;
 }
 
+int
+ndmp_4to9_tape_open_free_request (
+  ndmp9_tape_open_request *request9)
+{
+       NDMOS_API_FREE(request9->device);
+       request9->device = NULL;
+       return 0;
+}
+
 int
 ndmp_9to4_tape_open_request (
   ndmp9_tape_open_request *request9,
@@ -2026,6 +2065,13 @@ ndmp_9to4_mover_get_state_reply (
        return 0;
 }
 
+int
+ndmp_9to4_mover_get_state_free_reply(
+  ndmp4_mover_get_state_reply *reply4)
+{
+//     ndmp_9to4_addr_free(&reply4->data_connection_addr);
+       return 0;
+}
 
 /*
  * ndmp_mover_listen
@@ -2559,6 +2605,13 @@ ndmp_4to9_data_get_env_reply (
        return 0;
 }
 
+int
+ndmp_4to9_data_get_env_free_reply (
+  ndmp9_data_get_env_reply *reply9)
+{
+       ndmp_4to9_pval_vec_free(reply9->env.env_val, reply9->env.env_len);
+}
+
 int
 ndmp_9to4_data_get_env_reply (
   ndmp9_data_get_env_reply *reply9,
@@ -2979,6 +3032,14 @@ ndmp_4to9_log_message_request (
        return 0;
 }
 
+int
+ndmp_4to9_log_message_free_request (
+  ndmp9_log_message_request *request9)
+{
+       CNVT_FREE(request9, entry);
+       return 0;
+}
+
 int
 ndmp_9to4_log_message_request (
   ndmp9_log_message_request *request9,
@@ -3167,6 +3228,19 @@ ndmp_4to9_fh_add_file_request (
        return 0;
 }
 
+int
+ndmp_4to9_fh_add_file_free_request (
+  ndmp9_fh_add_file_request *request9)
+{
+       int i;
+
+       for (i = 0; i < request9->files.files_len; i++) {
+               NDMOS_API_FREE(request9->files.files_val[i].unix_path);
+       }
+
+       NDMOS_MACRO_FREE(request9->files.files_val);
+}
+
 int
 ndmp_9to4_fh_add_file_request (
   ndmp9_fh_add_file_request *request9,
@@ -3602,7 +3676,7 @@ struct reqrep_xlate       ndmp4_reqrep_xlate_table[] = {
        ndmp_4to9_tape_open_request,
        ndmp_9to4_tape_open_request,
        JUST_ERROR_REPLY,
-       NO_MEMUSED /* no memory free routines written yet */
+       ndmp_4to9_tape_open_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused
     },
     {
        NDMP4_TAPE_CLOSE,       NDMP9_TAPE_CLOSE,
@@ -3680,7 +3754,7 @@ struct reqrep_xlate       ndmp4_reqrep_xlate_table[] = {
        NO_ARG_REQUEST,
        ndmp_4to9_data_get_env_reply,
        ndmp_9to4_data_get_env_reply,
-       NO_MEMUSED /* no memory free routines written yet */
+       ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_4to9_data_get_env_free_reply, ndmp_xtox_no_memused
     },
     {
        NDMP4_DATA_STOP,        NDMP9_DATA_STOP,
@@ -3758,7 +3832,7 @@ struct reqrep_xlate       ndmp4_reqrep_xlate_table[] = {
        ndmp_4to9_log_message_request,
        ndmp_9to4_log_message_request,
        JUST_ERROR_REPLY,               /* no reply actually */
-       NO_MEMUSED /* no memory free routines written yet */
+       ndmp_4to9_log_message_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused
     },
 
     {
@@ -3766,7 +3840,7 @@ struct reqrep_xlate       ndmp4_reqrep_xlate_table[] = {
        ndmp_4to9_fh_add_file_request,
        ndmp_9to4_fh_add_file_request,
        JUST_ERROR_REPLY,               /* no reply actually */
-       NO_MEMUSED /* no memory free routines written yet */
+       ndmp_4to9_fh_add_file_free_request, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused
     },
     {
        NDMP4_FH_ADD_DIR,               NDMP9_FH_ADD_DIR,
@@ -3792,7 +3866,7 @@ struct reqrep_xlate       ndmp4_reqrep_xlate_table[] = {
        NO_ARG_REQUEST,
        ndmp_4to9_mover_get_state_reply,
        ndmp_9to4_mover_get_state_reply,
-       NO_MEMUSED /* no memory free routines written yet */
+       ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_xtox_no_memused, ndmp_9to4_mover_get_state_free_reply
     },
     {
        NDMP4_MOVER_LISTEN,     NDMP9_MOVER_LISTEN,
index cc2d08fad5f4642496981198a7469650490e29a1..2f8f2fc1e741c7e9dbab7993d426220a5dc92d77 100644 (file)
 #define CNVT_STRDUP_FROM_9x(PX, P9, MEMBERX, MEMBER9) \
     convert_strdup ((P9)->MEMBER9, &(PX)->MEMBERX)
 
+#define CNVT_FREE(PX, MEMBERX) \
+    { NDMOS_API_FREE((PX)->MEMBERX) ; (PX)->MEMBERX = NULL; };
 
 
 /*
index 1fe040a922b6548e75f077f33bcc502f82118de6..41d14ed0e884515ab6c850dfb96c82c65e0a49c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -19,6 +19,7 @@
  */
 
 #include "amanda.h"
+#include "event.h"
 #include "sockaddr-util.h"
 #include "ndmpconnobj.h"
 
@@ -736,6 +737,165 @@ ndmp_connection_wait_for_notify(
     }
 }
 
+typedef struct notify_data {
+    NDMPConnection *self;
+    ndmp9_data_halt_reason *data_halt_reason;
+    ndmp9_mover_halt_reason *mover_halt_reason;
+    ndmp9_mover_pause_reason *mover_pause_reason;
+    guint64 *mover_pause_seek_position;
+    GMutex *abort_mutex;
+    GCond *abort_cond;
+    int status;
+    event_handle_t *read_event;
+} notify_data;
+
+static void handle_notify(void *cookie);
+
+int
+ndmp_connection_wait_for_notify_with_cond(
+       NDMPConnection *self,
+       ndmp9_data_halt_reason *data_halt_reason,
+       ndmp9_mover_halt_reason *mover_halt_reason,
+       ndmp9_mover_pause_reason *mover_pause_reason,
+       guint64 *mover_pause_seek_position,
+       GMutex *abort_mutex,
+       GCond *abort_cond)
+{
+    struct ndmp_msg_buf nmb;
+    notify_data ndata;
+    gboolean found = FALSE;
+
+    ndata.self = self;
+    ndata.data_halt_reason= data_halt_reason;
+    ndata.mover_halt_reason= mover_halt_reason;
+    ndata.mover_pause_reason= mover_pause_reason;
+    ndata.mover_pause_seek_position = mover_pause_seek_position;
+    ndata.abort_mutex = abort_mutex;
+    ndata.abort_cond = abort_cond;
+    ndata.status = 2;
+
+    g_assert(!self->startup_err);
+
+    /* initialize output parameters */
+    if (data_halt_reason)
+       *data_halt_reason = NDMP4_DATA_HALT_NA;
+    if (mover_halt_reason)
+       *mover_halt_reason = NDMP4_MOVER_HALT_NA;
+    if (mover_pause_reason)
+       *mover_pause_reason = NDMP4_MOVER_PAUSE_NA;
+    if (mover_pause_seek_position)
+       *mover_pause_seek_position = 0;
+
+    /* if any desired notifications have been received, then we're
+     * done */
+    if (data_halt_reason && self->data_halt_reason) {
+       found = TRUE;
+       *data_halt_reason = self->data_halt_reason;
+       self->data_halt_reason = NDMP4_DATA_HALT_NA;
+    }
+
+    if (mover_halt_reason && self->mover_halt_reason) {
+       found = TRUE;
+       *mover_halt_reason = self->mover_halt_reason;
+       self->mover_halt_reason = NDMP4_MOVER_HALT_NA;
+    }
+
+    if (mover_pause_reason && self->mover_pause_reason) {
+       found = TRUE;
+       *mover_pause_reason = self->mover_pause_reason;
+       if (mover_pause_seek_position)
+           *mover_pause_seek_position = self->mover_pause_seek_position;
+       self->mover_pause_reason = NDMP4_MOVER_PAUSE_NA;
+       self->mover_pause_seek_position = 0;
+    }
+
+    if (found)
+       return TRUE;
+
+       /* otherwise, wait for an incoming packet and handle it, then try
+        * again.  There's some select trickery here to avoid hogging the
+        * ndmlib_mutex - basically, we want to block as long as possible
+        * outside of the ndmlib_mutex critical section.  This will also be
+        * useful to allow the wait to be aborted. */
+
+    ndata.read_event = event_register(self->conn->chan.fd,
+                                     EV_READFD, handle_notify, &ndata);
+
+    g_cond_wait(abort_cond, abort_mutex);
+
+    if (ndata.read_event) {
+       event_release(ndata.read_event);
+    }
+    if (ndata.status == 2) {
+       ndmp_connection_mover_abort(self);
+       ndmp_connection_mover_stop(self);
+    }
+    return ndata.status;
+
+}
+
+static void
+handle_notify(void *cookie)
+{
+    notify_data *ndata = cookie;
+    struct ndmp_msg_buf nmb;
+    gboolean found = FALSE;
+
+    g_mutex_lock(ndata->abort_mutex);
+
+    event_release(ndata->read_event);
+    ndata->read_event = NULL;
+
+    g_static_mutex_lock(&ndmlib_mutex);
+    NDMOS_MACRO_ZEROFILL(&nmb);
+    nmb.protocol_version = NDMP4VER;
+    ndata->self->last_rc = ndmconn_recv_nmb(ndata->self->conn, &nmb);
+    g_static_mutex_unlock(&ndmlib_mutex);
+
+    if (ndata->self->last_rc) {
+       /* (nothing to free) */
+       ndata->status = 1;
+       goto notify_done;
+    }
+
+    ndmconn_handle_notify(ndata->self, &nmb);
+
+
+    /* if any desired notifications have been received, then we're
+     * done */
+    if (ndata->data_halt_reason && ndata->self->data_halt_reason) {
+       found = TRUE;
+       *ndata->data_halt_reason = ndata->self->data_halt_reason;
+       ndata->self->data_halt_reason = NDMP4_DATA_HALT_NA;
+    }
+
+    if (ndata->mover_halt_reason && ndata->self->mover_halt_reason) {
+       found = TRUE;
+       *ndata->mover_halt_reason = ndata->self->mover_halt_reason;
+       ndata->self->mover_halt_reason = NDMP4_MOVER_HALT_NA;
+    }
+
+    if (ndata->mover_pause_reason && ndata->self->mover_pause_reason) {
+       found = TRUE;
+       *ndata->mover_pause_reason = ndata->self->mover_pause_reason;
+       if (ndata->mover_pause_seek_position)
+           *ndata->mover_pause_seek_position = ndata->self->mover_pause_seek_position;
+       ndata->self->mover_pause_reason = NDMP4_MOVER_PAUSE_NA;
+       ndata->self->mover_pause_seek_position = 0;
+    }
+
+    if (!found) {
+       ndata->read_event = event_register(ndata->self->conn->chan.fd,
+                                          EV_READFD, handle_notify, ndata);
+       g_mutex_unlock(ndata->abort_mutex);
+       return;
+    }
+
+    ndata->status = 0;
+notify_done:
+    g_cond_broadcast(ndata->abort_cond);
+    g_mutex_unlock(ndata->abort_mutex);
+}
 /*
  * Class Mechanics
  */
index 350243b21313204a1e715f5db2b25cc1795359b6..f34577ba384e41819e56cc20b2edb672decc4688 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -224,6 +224,20 @@ gboolean ndmp_connection_wait_for_notify(
        ndmp9_mover_pause_reason *mover_pause_reason,
        guint64 *mover_pause_seek_position);
 
+/* Synchronous notification interface.  This handles all types of notification,
+ * returning the result in the appropriate output parameter. */
+gboolean ndmp_connection_wait_for_notify_with_cond(
+       NDMPConnection *self,
+       /* NDMP_NOTIFY_DATA_HALTED */
+       ndmp9_data_halt_reason *data_halt_reason,
+       /* NDMP_NOTIFY_MOVER_HALTED */
+       ndmp9_mover_halt_reason *mover_halt_reason,
+       /* NDMP_NOTIFY_MOVER_PAUSED */
+       ndmp9_mover_pause_reason *mover_pause_reason,
+       guint64 *mover_pause_seek_position,
+       GMutex *abort_mutex,
+       GCond *abort_cond);
+
 /*
  * Constructor
  */
index 48d3930fd7dc836b0749dc8f8a05cdeb97b6522b..b2750e6445f8374f9126cf55c5fa004db04dc040 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda file recovery programs.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -268,7 +268,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -819,6 +820,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 880e260088f0634250339437977afaa1569ff89c..cf7267629ab6f6c1b7ec409591a3bebfbe6219e0 100644 (file)
@@ -184,7 +184,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -700,6 +701,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 28351d9df8d94d451e301b3774e29f62a786b984..788d15c9bc383e3606713a71de94d2628976b6d1 100644 (file)
@@ -10,13 +10,13 @@ logger() {
        # A non-annoying way to log stuff
        # ${@} is all the parameters, also known as the message.  Quoting the input
        # preserves whitespace.
-       msg="`date +'%b %e %Y %T'`: ${@}" 
+       msg="`date +'%b %e %Y %T'`: ${@}"
        echo "${msg}" >> ${LOGFILE}
 }
 
 log_output_of() {
        # A non-annoying way to log output of commands
-       # ${@} is all the parameters supplied to the function.  just execute it, 
+       # ${@} is all the parameters supplied to the function.  just execute it,
        # and capture the output in a variable.  then log that.
        output=`"${@}" 2>&1`
        ret=$?
@@ -38,10 +38,10 @@ check_superserver() {
 
 check_xinetd() {
        # Checks for an xinetd install and a config name passed as the first
-       # parameter.  
+       # parameter.
        # Returns:
-       #        0 if the file exists, 
-       #        1 if it does not, 
+       #        0 if the file exists,
+       #        1 if it does not,
        #        2 if xinetd.d/ does not exist or is a file
 
        if [ -d ${SYSCONFDIR}/xinetd.d ] ; then
@@ -59,7 +59,7 @@ check_xinetd() {
 
 check_inetd() {
     case $os in
-        SunOS) inetd_conf=${BASEDIR}/${SYSCONFDIR}/inet/inetd.conf ;;
+        SunOS) inetd_conf=${SYSCONFDIR}/inet/inetd.conf ;;
         *) inetd_conf=${SYSCONFDIR}/inetd.conf ;;
     esac
     if [ -e ${inetd_conf} ] ; then
@@ -129,7 +129,7 @@ backup_xinetd() {
 
 backup_inetd() {
     case $os in
-        SunOS) inetd_conf=${BASEDIR}/${SYSCONFDIR}/inet/inetd.conf ;;
+        SunOS) inetd_conf=${SYSCONFDIR}/inet/inetd.conf ;;
         *) inetd_conf=${SYSCONFDIR}/inetd.conf ;;
     esac
     # Backs up any amanda configuration it finds
@@ -148,7 +148,7 @@ backup_inetd() {
 
 backup_smf() {
     # Solaris only. I *think* this should be consistent across all smf installs
-    svccfg -s *amanda* > ${BASEDIR}/${AMANDAHOMEDIR}/example/amanda_smf.xml.orig || {\
+    svccfg -s *amanda* > ${AMANDAHOMEDIR}/example/amanda_smf.xml.orig || {\
         logger "Warning: export of existing amanda service failed.";
         return 1; }
 
@@ -169,7 +169,7 @@ install_xinetd() {
 
 install_inetd() {
     case $os in
-        SunOS) inetd_conf=${BASEDIR}/${SYSCONFDIR}/inet/inetd.conf ;;
+        SunOS) inetd_conf=${SYSCONFDIR}/inet/inetd.conf ;;
         *) inetd_conf=${SYSCONFDIR}/inetd.conf ;;
     esac
     # This one is hard to log because we're just appending.
@@ -184,13 +184,13 @@ install_smf() {
     case $ver in
       5.10)
         # Use inetadm and svcadm.
-        log_output_of ${BASEDIR}/usr/sbin/inetconv -f -i ${AMANDAHOMEDIR}/example/inetd.conf.${1} || { \
+        log_output_of ${basedir}/usr/sbin/inetconv -f -i ${AMANDAHOMEDIR}/example/inetd.conf.${1} || { \
             logger "Warning: Failed to create Amanda SMF manifest. Check the system log.";
             return 1; }
-        log_output_of ${BASEDIR}/usr/sbin/inetadm -e svc:/network/amanda/tcp || { \
+        log_output_of ${basedir}/usr/sbin/inetadm -e svc:/network/amanda/tcp || { \
             logger "Warning: Failed to enable Amanda service. See system log for more information.";
             return 1; }
-        log_output_of ${BASEDIR}/usr/sbin/svcadm restart network/amanda/tcp || { \
+        log_output_of ${basedir}/usr/sbin/svcadm restart network/amanda/tcp || { \
             logger "Warning: Failed to restart Amanda service.  See system log for details.";
             return 1; }
       ;;
@@ -212,7 +212,7 @@ reload_xinetd() {
     # Default action is to try reload.
     if [ "x$1" = "x" ]; then
        action="reload"
-    elif [ "$1" = "reload" -o "$1" = "restart" ]; then
+    elif [ "$1" = "reload" ] || [ "$1" = "restart" ]; then
        action="$1"
     else
        logger "WARNING: bad argument to reload_xinetd: $1"
@@ -238,7 +238,7 @@ reload_inetd() {
     # Default action is to try reload.
     if [ "x$1" = "x" ]; then
        action="reload"
-    elif [ "$1" = "reload" -o "$1" = "restart" ]; then
+    elif [ "$1" = "reload" ] || [ "$1" = "restart" ]; then
        action="$1"
     else
        logger "WARNING: bad argument to reload_inetd: $1"
index a0989c2bc79c1f08ee6c54ba9fd5bf8f4fe2fb8c..1db24f86f3869e9b8db287f4ccfbf6c176100275 100644 (file)
@@ -11,6 +11,8 @@
 MOCKDIR=$TMPDIR/mocks; export MOCKDIR
 [ -d $MOCKDIR ] || mkdir $MOCKDIR
 PATH=${MOCKDIR}:$PATH; export PATH
+# A list of flag files that must be present to avoid spurious output.
+# Each mock util gets one whether it is used or not.
 mock_flag_files=""
 
 mk_mock_util() {
@@ -61,24 +63,88 @@ EOF
 ###############
 # id replacemnt
 
-# Set defaults for deb_uid and amanda_group, if running outside test_sh_libs
+# Set vars for output of -Gn
+id_0="biff"
+id_1="biff foo"
+id_2="biff bar baz"
+id_3="biff zip bop whir"
+
+# Set defaults for uid and amanda_group, if running outside test_sh_libs
 deb_uid=${deb_uid:=12345}
 amanda_group=${amanda_group:=disk}
 
 mk_mock_util "id"
 cat << EOF >> "${MOCKDIR}/id"
-echo "id args: \${1}" > $mock_id_flags
+echo "id args: \${@}" > $mock_id_flags
 [ -n "\${1}" ] || { echo "Missing a username to id!"; exit 1; }
 
-# We have to return the most basic form of id to be portable
-# group file is used for supplemental groups.
-if [ -f "${MOCKDIR}/is_member" ]; then
-    echo "uid=${deb_uid}(\${1}) gid=6(${amanda_group})"
+# We can only use id with no flags to have consistent results.  Solaris
+# /usr/bin/id does not provide any standard flags. Since /usr/xpg4/bin is
+# not part of a minimal install we can't depend on it. Any flags *at all*
+# should raise an error in the tests.
+# group file and /usr/bin/groups can be used (with some tweaks).
+for f in "\$@"; do
+    case \$f in
+        # -- is ok, surprisingly.
+        --) : ;;
+        -?*) echo "id: no options are portable! '\$f'"
+             # Solaris exits with 2, others with 1. ugh.
+             exit 2
+        ;;
+        *) : ;;
+    esac
+done
+
+# Use id_group to control primary group name.
+[ -f ${MOCKDIR}/id_group ] && group=\`cat ${MOCKDIR}/id_group\` || group=bar
+
+# Solaris, Linux and OSX differ in the exact format of the output from id,
+# so we provide sample output based on the contents of id_os.  We don't
+# parse it, but its presence can't break things.
+test_os=\`cat ${MOCKDIR}/id_os\`
+case \${test_os} in
+    linux) sup_groups=" groups=999(\${group}),1000(foo)" ;;
+    solaris) sup_groups="" ;;
+    osx) sup_groups=" groups=999(\${group}), 1000(foo)" ;;
+esac
+
+if [ -f ${MOCKDIR}/id_exists ]; then
+    # Note: uid is set when the mock is created.
+    echo "uid=${deb_uid}(\${1}) gid=6(\${group})\${sup_groups}"
 else
-    echo "uid=123(\${1}) gid=123(foobar)"
+    echo "id: \${1}: no such user" >&2
+    exit 1
 fi
 EOF
 
+###############
+# groupadd replacement
+mk_mock_util "groupadd"
+cat << EOF >> "${MOCKDIR}/groupadd"
+echo "groupadd args: \${@}" > $mock_groupadd_flags
+# We check for return codes of 0 (group added) or 9 (group existed) to
+# continue in the function that uses groupadd
+groupadd_rc=\`cat ${MOCKDIR}/groupadd_rc\`
+exit \${groupadd_rc}
+EOF
+
+###############
+# groups replacement
+mk_mock_util "groups"
+cat << EOF >> "${MOCKDIR}/groups"
+echo "groups args: \${@}" > $mock_groups_flags
+cat ${MOCKDIR}/groups_output
+EOF
+
+###############
+# usermod replacement
+mk_mock_util "usermod"
+cat << EOF >> "${MOCKDIR}/usermod"
+echo "usermod args: \${@}" > $mock_usermod_flags
+# Protect against passing a blank username.
+[ "x\${1}" = "x" ] && exit 2 || exit 0
+EOF
+
 ###############
 # svcs replacement
 mk_mock_util "svcs"
@@ -96,7 +162,7 @@ EOF
 # xinetd init script replacement
 mk_mock_util xinetd
 cat << EOF >> "${MOCKDIR}/xinetd"
-echo "xinetd args: \${1}" > $mock_xinetd_flags
+echo "xinetd args: \${@}" > $mock_xinetd_flags
 [ -f ${MOCKDIR}/success ] && exit 0
 echo "xinetd did not \${1}"
 exit 1
@@ -106,7 +172,7 @@ EOF
 # inetd init script replacement
 mk_mock_util inetd
 cat << EOF >> "${MOCKDIR}/inetd"
-echo "inetd args: \${1}" > $mock_inetd_flags
+echo "inetd args: \${@}" > $mock_inetd_flags
 [ -f ${MOCKDIR}/success ] && exit 0
 echo "inetd did not \${1}"
 exit 1
@@ -116,7 +182,7 @@ EOF
 # install replacement
 mk_mock_util install
 cat << EOF >> "${MOCKDIR}/install"
-echo "install args: \$@" > $mock_install_flags
+echo "install args: \${@}" > $mock_install_flags
 [ -f ${MOCKDIR}/success ] && exit 0
 echo "Some funky install error, yo!"
 exit 1
index 1b131c4a1d1ceaeed985dfe5e7d18a8bf5244860..23a20ba1560f72825afa28923e2d310b31249e30 100644 (file)
@@ -18,16 +18,16 @@ add_service() {
     # Only needed on Solaris!
     entry="amanda       10080/tcp    # amanda backup services"
     # make sure amanda is in /etc/services
-    if [ -z "`grep 'amanda' /${SYSCONFDIR}/services |grep '10080/tcp'`" ] ; then
-        logger "Adding amanda entry to /${SYSCONFDIR}/services."
-        echo "${entry}" >> /${SYSCONFDIR}/services
+    if [ -z "`grep 'amanda' ${SYSCONFDIR}/services |grep '10080/tcp'`" ] ; then
+        logger "Adding amanda entry to ${SYSCONFDIR}/services."
+        echo "${entry}" >> ${SYSCONFDIR}/services
     fi
 
     # make sure kamanda is in /etc/services
     entry_2="amanda       10081/tcp    famdc    # amanda backup services (kerberos)"
     if [ -z "`grep 'kamanda' /etc/services |grep '10081/tcp'`" ] ; then
-        logger "Adding kamanda entry to /${SYSCONFDIR}/services."
-        echo "${entry_2}" >> /${SYSCONFDIR}/services
+        logger "Adding kamanda entry to ${SYSCONFDIR}/services."
+        echo "${entry_2}" >> ${SYSCONFDIR}/services
     fi
 }
 
index d0d43a82e941e23a4477f427464fc790e8d70e47..3833644e4618d28441d7e1ee3c90473122827e07 100644 (file)
@@ -28,7 +28,7 @@ remove_smf() {
 rm_user() {
     # Delete the user provided as first parameter ($1)
     logger "Deleting user: $1"
-    log_output_of userdel $1 
+    log_output_of userdel $1
 }
 
 # ------------- End Post Removal Functions -----------------
index 878a8afd14b315fad9d0536b3608ab64f874a0a8..c2aecac13daf17cf7a14861cba3d6a25833689d2 100644 (file)
@@ -9,6 +9,7 @@
 # dist: used on linux for the distro.
 # LOGFILE: a log file we append to
 # os: Linux, Darwin, SunOS, `uname`...
+# wanted_shell:  Linux/SunOS/OSX all keep them in different places
 # SYSCONFDIR: location of system config files (ie, /etc)
 # LOGDIR: logging directory for amanda
 
@@ -21,7 +22,7 @@ create_user() {
     case $os in
         Linux|SunOS)
             # Create the amanda user with a specific uid on deb systems
-            if [ ${dist} = "Debian" -o ${dist} = "Ubuntu" ] ; then
+            if [ "x${dist}" = "xDebian" ] || [ "x${dist}" = "xUbuntu" ] ; then
                 uid_flag="-u ${deb_uid}"
             else
                 uid_flag=
@@ -36,28 +37,35 @@ create_user() {
                             -g ${amanda_group} \
                             ${uid_flag} \
                             -d ${AMANDAHOMEDIR} \
-                            -s /bin/bash ${amanda_user}  || \
+                            -s ${wanted_shell} ${amanda_user}  || \
                 { logger "WARNING:  Could not create user ${amanda_user}. Installation will fail." ; return 1 ; }
-                r=`uname -r`
-                if [ "$os" = "Linux"] && [ ${dist} != "SuSE" ]; then
+                logger "Created ${amanda_user} with blank password."
+
+                if [ "x$os" = "xLinux" ] && [ "x${dist}" != "xSuSE" ]; then
                     # Lock the amanda account until admin sets password
-                    log_output_of passwd -l ${amanda_user} || { \
+                    log_output_of passwd -l ${amanda_user} && { \
+                        logger "${info_create_user_success}"
+                        logger "${info_unlock_account}"
+                    } || { \
                         logger "${warning_user_passwd}"; }
                 fi
-                if [ "$os" = "SunOS" ]; then
+                if [ "x$os" = "xSunOS" ]; then
+                    r=`uname -r`
                     case $r in
-                        5.8|5.9) log_output_of passwd -l ${amanda_user};;
+                        5.8|5.9) log_output_of passwd -l ${amanda_user} ;;
                         5.10) # Special login-lock, while allowing execution.
-                            log_ouptut_of passwd -N ${amanda_user} || { \
+                            log_output_of passwd -N ${amanda_user} && { \
+                                logger "${info_create_user_success_sol}"
+                                logger "${info_unlock_account}"
+                            } || { \
                                 logger "${warning_user_passwd}"; }
                         ;;
                     esac
                 fi
 
-                logger "${info_create_user_success}"
             else
                 # The user already existed
-                logger "${info_user_params}"
+                logger "The Amanda user '${amanda_user}' exists on this system."
             fi
         ;;
         Darwin) : #TODO
@@ -66,120 +74,136 @@ create_user() {
 }
 
 add_group() {
-    # Try to add the group, detect via return code if it already exists.
-    # This works on linux and solaris...
-    log_output_of groupadd ${1}
+    # First, try to add the group, detect via return code if it
+    # already exists. Then add ${amanda_user} to the group without
+    # checking if account is already a member.  (check_user should
+    # already have been called).
+    #
+    # Works on linux and solaris.  OSX has different tools.
+
+    [ "x${1}" = "x" ] && { logger "Error: first argument was not a group to add." ; return 1 ; }
+    group_to_add=${1}
+    log_output_of groupadd ${group_to_add}
+    rc=$?
     # return of 0 means group was added; 9 means group existed.
-    if [ $? = "0" ] || [ $? = "9" ]; then
-        logger "Adding ${amanda_user} to ${1}"
-        case $os in
-            Linux) um_flags="-a -G";;
-            # Solaris does not have -a flag.
-            SunOS) um_flags="-G `groups ${amanda_user}`";;
-        esac
+    if [ $rc -eq 0 ] || [ $rc -eq 9 ]; then
+        logger "Adding ${amanda_user} to ${group_to_add}"
+        # Generate a comma separated list of existing supplemental groups.
+        # Linux prefaces output with '<username> : '.
+        existing_sup_groups=`groups ${amanda_user}|sed 's/.*: //;s/ /,/g'`
+        # usermod append is -A on Suse, all other linux use -a, and
+        # -A means something else entirely on solaris. So we just use
+        # -G, and append a list of the current groups from id.
         # So far, all linux distros have usermod
-        log_output_of usermod -a -G ${1} ${amanda_user} || \
-            { logger "${error_group_member}" ; return 1 ; }
+        log_output_of usermod -G ${existing_sup_groups},${group_to_add} ${amanda_user} || { \
+            logger "Nonfatal ERROR: Failed to add ${group_to_add}."
+            logger "${error_group_member}" ; return 1 ; }
     else
-        logger "Error: groupadd failed in an unexpected way."
+        logger "Error: groupadd failed in an unexpected way. return code='$rc'"
         return 1
     fi
 }
 
-check_user() {
-    # Check parameters of ${amanda_user}'s account.
-    # $1= user field $2= value to check
-    # group, shell, homedir, UID are valid for $1.
-    # group:  checks the system group file for ${amanda_user}'s
-    #   membership in the group named $2.
-    # shell:  confirms the passwd file's shell field for
-    #   ${amanda_user} is $2
-    # homedir: confirm the passwd file's homedir field for
-    #   ${amanda_user} is $2
-    # UID: confirm that ${amanda_user}'s UID is $2.
-    #
-    # Extra information about the failed check is written to the log.
-    #
-    # Return codes:
-    # 0 = success
-    # 1 = error
-    # 2 = usage error
+
+# All check_user_* functions check various parameters of ${amanda_user}'s
+# account. Return codes:
+# 0 = success
+# 1 = error
+# 2 = usage or other error.  more info will be logged
+
+check_user_group() {
+    # checks the system group file for ${amanda_user}'s membership in
+    # the group named $1.
     err=0
-    if [ ! $# -eq 2 ]; then
-       echo "check_user(): Wrong number of parameters"
-       return 2
+    [ "x" = "x$1" ] && { logger "check_user_group: no group given"; return 1; }
+    logger "Verify ${amanda_user}'s primary group = $1 "
+    # Check if the group exists, disregarding membership.
+    group_entry=`grep "^${2}" ${SYSCONFDIR}/group 2> /dev/null`
+    if [ ! "x" = "x${group_entry}" ]; then
+        # Assume the user exists, and check the user's primary group.
+        GROUP=`id ${amanda_user} 2> /dev/null |\
+            cut -d " " -f 2 |\
+            sed 's/.*gid=[0-9]*(\([^ ()]*\))/\1/'`
+        if [ ! "x${GROUP}" = "x${1}" ] ; then
+            logger "${amanda_user} not a member of ${1}"
+            err=1
+        fi
+    else
+        logger "User's primary group '${1}' does not exist"
+        err=1
     fi
-    logger "Verify ${amanda_user}'s $1 = $2 "
-    case $1 in
-       "group")
-           # Check if the group exists, disregarding membership.
-           if `grep "^${2}" ${SYSCONFDIR}/group > /dev/null` ; then
-               # Assume the user exists, and check the user's primary group.
-               GROUP=`id ${amanda_user} 2> /dev/null | sed 's/.*gid=[0-9]*(\([^ ()]*\))/\1/'`
-               if [ ! "x${GROUP}" = "x${2}" ] ; then
-                   logger "${amanda_user} not a member of ${2}"
-                   err=1
-               fi
-           else
-               logger "User group '${2}' does not exist"
-               err=1
-           fi
-       ;;
-        "group-sup*")
-            # Check if a supplementary group exists.
-           SUP_MEM=`awk -F: "\$1 ~ ${2} { print \$4; }" 2> /dev/null`
-            if [ -n "$SUP_MEM" ] ; then
-                # Check if our user is a member.
-                if echo "${SUP_MEM}"|grep "${amanda_user}" &> /dev/null ; then
-                    :
-                else
-                    logger "${amanda_user} is not a member of supplemental group ${2}."
-                    err=1
-                fi
-            else
-                logger "Supplemental group ${2} does not exist"
-                err=1
-            fi
+    return $err
+}
+
+check_user_supplemental_group() {
+    # Checks for the group ${1}, and adds ${amanda_user} if missing.
+    # Other groups are preserved.
+    err=0
+    [ "x" = "x$1" ] && { logger "check_user_supplemental_group: no supplemental group given"; return 1; }
+    sup_group=${1}
+    logger "Verify ${amanda_user} is a member of ${sup_group}."
+    # First, check if the supplementary group exists.
+    sup_group_entry=`grep "${sup_group}" ${SYSCONFDIR}/group 2>/dev/null`
+    if [ ! "x" = "x${sup_group_entry}" ]; then
+        SUP_MEM=`echo ${sup_group_entry} | cut -d: -f4`
+        # Check if our user is a member.
+        case ${SUP_MEM} in
+            *${amanda_user}*) : ;;
+            *)
+            logger "${amanda_user} is not a member of supplemental group ${sup_group}."
+            err=1
             ;;
-       "shell")
-           SHELL=`grep "^${amanda_user}" ${SYSCONFDIR}/passwd | cut -d: -f7`
-            wanted_shell=$2; export wanted_shell
-           if [ ! "x${SHELL}" = "x${2}" ] ; then
-               logger "${warning_user_shell}"
-               err=1
-           fi
-       ;;
-       "homedir")
-           HOMEDIR=`grep "^${amanda_user}" ${SYSCONFDIR}/passwd | cut -d: -f6`
-           if [ ! "x${HOMEDIR}" = "x${2}" ] ; then
-               logger "${warning_user_homedir}"
-               err=1
-           fi
-       ;;
-       "UID")
-           # Debian systems must use a specific UID
-           ID=`id ${amanda_user} 2> /dev/null | sed 's/uid=\([0-9]*\).*/\1/'`
-           if [ ! "${ID}" -eq "${2}" ] ; then
-               checked_uid=${2}; export checked_uid
-               logger "${warning_user_uid_debian}"
-               err=1
-           fi
-       ;;
-       *)
-           echo "check_user(): unknown user parameter."
-           err=2
-       ;;
-    esac
-       
+        esac
+    else
+        logger "Supplemental group ${sup_group} does not exist"
+        err=1
+    fi
     return $err
 }
 
+check_user_shell() {
+    # Confirms the passwd file's shell field for ${amanda_user} is $1
+    [ "x" = "x$1" ] && { logger "check_user_shell: no shell given"; return 1; }
+    wanted_shell=$1; export wanted_shell
+    logger "Verify ${amanda_user}'s shell is ${wanted_shell}."
+    real_shell=`grep "^${amanda_user}" ${SYSCONFDIR}/passwd | cut -d: -f7`
+    export real_shell
+    if [ ! "x${real_shell}" = "x${wanted_shell}" ] ; then
+        logger "WARNING:  ${amanda_user} default shell= ${wanted_shell}"
+        logger "WARNING: ${amanda_user} existing shell: ${real_shell}"
+        logger "${warning_user_shell}"
+        return 1
+    fi
+}
+
+check_user_homedir() {
+    # Confirm the passwd file's homedir field for ${amanda_user} is $1
+    [ "x" = "x$1" ] && { logger "check_user_homedir: no homedir given"; return 1; }
+    HOMEDIR=`grep "^${amanda_user}" ${SYSCONFDIR}/passwd | cut -d: -f6`
+    if [ ! "x${HOMEDIR}" = "x${1}" ] ; then
+        logger "${warning_user_homedir}"
+        return 1
+    fi
+}
+
+check_user_uid() {
+    # Confirm that ${amanda_user}'s UID is $1.
+    # Debian systems must use a specific UID
+    [ "x" = "x$1" ] && { logger "check_user_uid: no uid given"; return 1; }
+    ID=`id ${amanda_user} 2> /dev/null | sed 's/uid=\([0-9]*\).*/\1/'`
+    if [ ! ${ID} -eq ${1} ] ; then
+        checked_uid=${1}; export checked_uid
+        logger "${warning_user_uid_debian}"
+        return 1
+    fi
+}
+
 check_homedir() {
        # Checks that the homedir has correct permissions and belongs to correct
        # user.  Uses $amanda_user and  $amanda_group.
        if [ -d ${AMANDAHOMEDIR} ] ; then
            OWNER_GROUP=`ls -dl ${AMANDAHOMEDIR} | awk '{ print $3" "$4; }'`
-           [ "$OWNER_GROUP" = "${amanda_user} ${amanda_group}" ] || \
+           [ "x$OWNER_GROUP" = "x${amanda_user} ${amanda_group}" ] || \
                logger "${warning_homedir_owner}"
            return $?
        else
@@ -218,63 +242,39 @@ create_logdir() {
 
 # Info, Warning, and Error strings used by the installer
 
-info_create_user_success="The '${amanda_user}' user account has been successfully created. 
- Furthermore, the account has been automatically locked for you for security 
- purposes.  Once a password for the '${amanda_user}' account has been set, 
- the user can be unlocked by issuing the following command as root.: 
+info_create_user_success="NOTE: Set a password and unlock the ${amanda_user} account before
+ running Amanda."
+
+info_create_user_success_sol="NOTE: Account is set as non-login.  If interactive login
+is required: a password must be set, and the account activated for login."
+
+info_unlock_account=" The superuser can unlock the account by running:
 
  # passwd -u ${amanda_user}
+"
 
- If this is not a new installation of Amanda and you have pre-existing Amanda
- configurations in ${SYSCONFDIR}/amanda you should ensure that 'dumpuser'
- is set to '${amanda_user}' in those configurations.  Additionally, you
- should ensure that ${AMANDAHOMEDIR}/.amandahosts on your client systems
- is properly configured to allow connections for the user '${amanda_user}'." 
+info_existing_installs="Pre-existing Amanda installations must confirm:
+  -${SYSCONFDIR}/amanda/* should have 'dumpuser' set to '${amanda_user}'.
+  -${AMANDAHOMEDIR}/.amandahosts on client systems should allow connections by
+   '${amanda_user}'."
 
-warning_user_password="!!! WARNING! WARNING! WARNING! WARNING! WARNING! !!!
-!!!                                                             !!!
-!!!  The '${amanda_user}' user account for this system has been   !!!
-!!!  created, however the user has no password set. For         !!!
-!!!  security purposes this account is normally locked after    !!!
-!!!  creation.  Unfortunately, when locking this account an     !!!
-!!!  error occurred.  To ensure the security of your system,    !!!
-!!!  you should set a password for the user account             !!!
-!!!  '${amanda_user}' immediately!  To set such a password,     !!!
-!!!  please issue the following command:                        !!!
-!!!                                                             !!!
-!!!   # passwd ${amanda_user}                                   !!!
-!!!                                                             !!!
-!!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!       !!!"
+warning_user_password="WARNING:  '${amanda_user}' no password. An error occured when locking the
+ account.  SET A PASSWORD NOW:
 
-info_user_params="The Amanda backup software is configured to operate as the user 
- '${amanda_user}'.  This user exists on your system and has not been modified. 
- To ensure that Amanda functions properly, please see that the following 
- parameters are set for that user:
- SHELL:          /bin/bash
- HOME:           ${AMANDAHOMEDIR} 
- Default group:  ${amanda_group}"
+ # passwd ${amanda_user}"
 
-error_group_member="!!!      Nonfatal ERROR.     Nonfatal ERROR.     !!!
-!!! user '${amanda_user}' is not part of the '${amanda_group}' group,  !!!
-!!! Amanda will not run until '${amanda_user}' is a member of '${amanda_group}'.  !!!
-!!!    Nonfatal ERROR.    Nonfatal ERROR.    Nonfatal Error.    !!!"
+error_group_member="Nonfatal ERROR:  Amanda will not run until '${amanda_user}' is a member the
+ preceeding group.  Install will continue..."
 
-warning_user_shell="WARNING: The user '${amanda_user}' has a non-default shell.
-the default shell is ${wanted_shell}.  Other shells have not been tested."
+warning_user_shell="WARNING: The user '${amanda_user}' has a non-default shell. Other shells have not been tested."
 
-warning_user_homedir="!!! WARNING! WARNING! WARNING! WARNING! WARNING! !!!
-!!! The user '${amanda_user}' must have its home directory set to   !!!
-!!! '${AMANDAHOMEDIR}' Please correct before using Amanda     !!!
-!!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!  !!!"
+warning_user_homedir="WARNING: The user '${amanda_user}' must have its home directory set to
+'${AMANDAHOMEDIR}' Please correct before using Amanda."
 
-warning_user_uid_debian="!!! WARNING! WARNING! WARNING! WARNING! WARNING! !!!
-!!! Debian packages were built assuming that ${amanda_user} !!!
-!!! uid = ${checked_uid}.  The uid of ${amanda_user} is different     !!!
-!!! different on this system.  Files owned by ${checked_uid} must    !!!
-!!! be chowned to ${amanda_user}.                           !!!
-!!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!  !!!"
+warning_user_uid_debian="WARNING: Debian packages were built assuming that ${amanda_user}
+uid = ${checked_uid}.  The uid of ${amanda_user} is different on this system.  Files
+owned by ${checked_uid} must be chowned to ${amanda_user}."
 
-warning_homedir_owner="!!! Please ensure that the directory '${AMANDAHOMEDIR}' is owned by !!!
-!!! the user '${amanda_user}' and group '${amanda_group}'. !!!"
+warning_homedir_owner="WARNING: The ${amanda_user}'s home directory,'${AMANDAHOMEDIR}' ownership must be changed to '${amanda_user}:${amanda_group}'. "
 
 # --------------- End included Functions -----------------
index 85711f1d30af669dd0e0b66ca971120f31d77bb8..22c4fb6cf87351bc12d0ed0e58b42917419a29af 100755 (executable)
@@ -23,9 +23,11 @@ SHUNIT_INC="${srcdir=`pwd`}/packaging/common"; export SHUNIT_INC
 TMPDIR=`pwd`/shunit-test; export TMPDIR
 amanda_user=test_amandabackup; export amanda_user
 amanda_group=test_disk; export amanda_group
+sup_group="test_tape"; export sup_group
 AMANDAHOMEDIR=$TMPDIR/amanda; export AMANDAHOMEDIR
 AMANDATES=$AMANDAHOMEDIR/amandates; export AMANDATES
 os=`uname`; export os
+wanted_shell='/bin/false'; export wanted_shell
 dist=Fedora; export dist
 SYSCONFDIR=$TMPDIR/etc; export SYSCONFDIR
 SBINDIR=$TMPDIR/sbin; export SBINDIR
@@ -34,7 +36,7 @@ deb_uid=63000; export deb_uid
 
 
 # Append stuff to this when you make temp files if they are outside TMPDIR
-test_cleanup_files="$TMPDIR"; export sh_cleanup_files
+test_cleanup_files="$TMPDIR"; export test_cleanup_files
 
 # This can't be part of one-time setup, because TMPDIR must exist before
 # shunit2 is sourced.
@@ -63,6 +65,8 @@ oneTimeSetUp() {
         grep "${amanda_user}" ${SYSCONFDIR}/passwd &> /dev/null || { \
             echo "$msg_prefix ${amanda_user} still exists, or no ${SYSCONFDIR}/passwd.";
             exit 1; }
+        groupdel ${amanda_group} || exit 1
+        groupdel ${sup_group} || exit 1
     else
        echo "Not root, cleanup skipped"
     fi
@@ -84,7 +88,7 @@ oneTimeTearDown() {
 
 test_cleanup_files="$LOGFILE ${test_cleanup_files}"
 
-# errors before the tests are run.
+# shows syntax errors before the tests are run.
 . ${SHUNIT_INC}/common_functions.sh
 . ${SHUNIT_INC}/pre_inst_functions.sh
 . ${SHUNIT_INC}/post_inst_functions.sh
@@ -99,8 +103,6 @@ if [ "$tester_id" = "0" ]; then
 else
     IAmRoot=
 fi
-# A list of flag files that must be present to avoid spurious output.
-# Each mock util gets one whether it is used or not.
 
 # CAUTION: using real values if we are root.
 if [ "$IAmRoot" ]; then
@@ -111,6 +113,7 @@ fi
 
 # Source our mock utils.
 . ${SHUNIT_INC}/mock_utils.sh
+
 ######################################
 # Common functions
 
@@ -118,7 +121,7 @@ fi
 # to run first.
 test___logger() {
     # Write a line to the log, test that it got there.
-    TEST_MSG="Test01_logger message"
+    TEST_MSG="test___logger message"
     LOG_LINE="`date +'%b %e %Y %T'`: ${TEST_MSG}"
     # It's important for the log messages to be quoted, or funny stuff happens.
     logger "${TEST_MSG}"
@@ -136,7 +139,7 @@ test___logger() {
 
 test__log_output_of() {
     # Use log_output_of to append to the log
-    TEST_MSG="Test02_log_output_of message"
+    TEST_MSG="test__log_output_of message"
     log_output_of echo "${TEST_MSG}"
     assertEquals "log_output_of()" 0 $?
     COUNT=`grep -c "${TEST_MSG}" ${LOGFILE}`
@@ -285,11 +288,11 @@ test_reload_xinetd() {
     rm ${MOCKDIR}/success
     reload_xinetd "reload"
     assertEquals "reload_xinetd" 1 $?
-    tail -4 ${LOGFILE}|grep "\<xinetd.*Attempting restart"
+    tail -4 ${LOGFILE}|grep "\<xinetd.*Attempting restart" >/dev/null
     assertEquals "reload_xinetd should try to restart." 0 $?
     reload_xinetd "restart"
     assertEquals "restart should fail." 1 $?
-    tail -3 ${LOGFILE}|grep "Restarting xinetd"
+    tail -3 ${LOGFILE}|grep "Restarting xinetd" >/dev/null
     assertEquals "Should log attempt to restart" 0 $?
 }
 
@@ -313,11 +316,11 @@ test_reload_inetd() {
     rm ${MOCKDIR}/success
     reload_inetd "reload"
     assertEquals "reload_inetd" 1 $?
-    tail -4 ${LOGFILE}|grep "\<inetd.*Attempting restart"
+    tail -4 ${LOGFILE}|grep "\<inetd.*Attempting restart" >/dev/null
     assertEquals "reload_inetd should try to restart." 0 $?
     reload_inetd "restart"
     assertEquals "restart should fail." 1 $?
-    tail -3 ${LOGFILE}|grep "Restarting inetd"
+    tail -3 ${LOGFILE}|grep "Restarting inetd" >/dev/null
     assertEquals "Should log attempt to restart" 0 $?
 }
 
@@ -325,89 +328,118 @@ test_reload_inetd() {
 ######################################
 # pre_install_functions
 
-test_check_user_crazy_input() {
-    logger "test_check_user_crazy_input"
-    # Case 1: not enough params.
-    check_user "bar"
-    assertEquals "'check_user bar'" 2 $?
-    
-    # Case 2: bad first param.
-    check_user "bar" "bell" 
-    assertEquals "'check_user bar bell'" 2 $?
-}
-
 test_check_user_group_missing() {
-    logger "test_check_user_group_missing"
+    logger "test_check_user_group_missing no param"
+    check_user_group
+    assertNotEquals "'check_user_group' should fail" 0 $?
+    logger "test_check_user_group_missing missing group"
+    [ ! "$IAmRoot" ] && rm -f ${SYSCONFDIR}/group
     touch ${SYSCONFDIR}/group
-    check_user "group" "abracadabra"
-    assertNotEquals "'check_user group abracadabra' should not be found:" 0 $?
-}
-
-# passwd file entry for Linux systems, maybe others.  UID is correct
-# for Debian as well.
-good_passwd_entry="${amanda_user}:x:${mock_deb_uid}:6::${AMANDAHOMEDIR}:/bin/bash"
-export good_passwd_entry
-test_create_user() {
-    logger "test_create_user"
-    if [ ! "$IAmRoot" ]; then
-       startSkipping
-       echo "test_create_user: Creating mock passwd file."
-       echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd
-       echo "test_create_user: tests skipped."
-       #TODO: mock useradd.
-       return
-    fi
-    # Case 1: create_user should succeed.
-    create_user
-    assertEquals "create_user()" 0 $?
-}
-
-good_group_entry="${amanda_group}:x:100:${amanda_user}"
+    for os in linux osx solaris; do
+        echo $os > ${MOCKDIR}/id_os
+        check_user_group "abracadabra"
+        assertNotEquals "'check_user group abracadabra' should not be found:" 0 $?
+        LOG_TAIL=`tail -1 ${LOGFILE}|cut -d " " -f 5-`
+        assertEquals "check_user_group should write" \
+            "User's primary group 'abracadabra' does not exist" \
+            "${LOG_TAIL}"
+    done
+}
+
+good_group_entry="${amanda_group}:x:100:"
 export good_group_entry
-test_check_user_group() {
-    logger "test_check_user_group"
+test_check_user_group_exists() {
+    logger "test_check_user_group user and group exist"
+    touch ${MOCKDIR}/id_exists
     touch ${SYSCONFDIR}/group
     # Non-root adds and entry to the mock group file
     [ ! "$IAmRoot" ] && echo $good_group_entry > ${SYSCONFDIR}/group
+    for os in linux osx solaris; do
+        echo $os > ${MOCKDIR}/id_os
 
-    # Case 1: Amanda_user is correct.
-    touch ${MOCKDIR}/is_member
-    check_user "group" "${amanda_group}"
-    assertEquals "'check_user group ${amanda_group}': id returns member" \
-        0 $?
+        # Case 1: Amanda_user is correct.
+        echo ${amanda_group} > ${MOCKDIR}/id_group
+        check_user_group "${amanda_group}"
+        assertEquals "'check_user_group ${amanda_group}': id returns correct groupname" \
+            0 $?
 
-    # Case 2: Amanda_user is not a member of the the correct group.
-    rm ${MOCKDIR}/is_member
-    check_user "group" "${amanda_group}"
-    assertEquals "'check_user group ${amanda_group}' when not a member" 1 $?
+        # Case 2: Amanda_user is not a member of the the correct primary group.
+        rm ${MOCKDIR}/id_group
+        check_user_group "${amanda_group}"
+        assertEquals "'check_user_group ${amanda_group}' when not a member" 1 $?
+    done
 }
 
+test_check_user_supplemental_group_missing() {
+    logger "test_check_user_supplemental_group missing"
+    [ ! "$IAmRoot" ] && echo $good_group_entry > ${SYSCONFDIR}/group
+    for os in linux osx solaris; do
+        echo $os > ${MOCKDIR}/id_os
+        check_user_supplemental_group ${sup_group}
+        assertEquals "'check_user supplemental-group ${sup_group}' when group missing" \
+        1 $?
+    done
+}
+
+missing_group_member="${sup_group}:x:105:nobody"
+export missing_group_member
+good_sup_group_entry="${missing_group_member},${amanda_user}"
+export good_sup_group_entry
+
+test_check_user_supplemental_group_exists() {
+    logger "test_check_user_supplemental_group exists"
+    [ ! "$IAmRoot" ] && echo $missing_group_member > ${SYSCONFDIR}/group
+    check_user_supplemental_group ${sup_group}
+    assertEquals "'check_user_supplemental_group ${sup_group}' when amanda_user is not a member" \
+        1 $?
+
+    [ ! "$IAmRoot" ] && echo ${good_sup_group_entry} > ${SYSCONFDIR}/group
+    check_user_supplemental_group ${sup_group}
+    assertEquals "'check_user_supplemental_group ${sup_group}' with correct membership" \
+        0 $?
+}
 test_check_user_shell() {
     logger "test_check_user_shell"
     if [ ! "$IAmRoot" ]; then
-       echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd
+       echo "${good_passwd_entry}" > ${SYSCONFDIR}/passwd
     fi
     # Case 1: Provide a matching shell
-    check_user "shell" "/bin/bash"
-    assertEquals "check_user shell /bin/bash (matching)" 0 $?
-    # Case 2: Provid a non-matching shell. 
-    check_user "shell" "/bin/sh"
-    assertEquals "check_user shell /bin/ksh (not matching)" 1 $?
+    check_user_shell "/bin/bash"
+    assertEquals "check_user_shell /bin/bash (matching)" 0 $?
+    # Case 2: Provide a non-matching shell. 
+    check_user_shell "/bin/ksh"
+    assertEquals "check_user_shell /bin/ksh (not matching)" 1 $?
 }
 
 test_check_user_homedir() {
     logger 'test_check_user_homedir'
     if [ ! "$IAmRoot" ]; then
-       echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd
+       echo "${good_passwd_entry}" > ${SYSCONFDIR}/passwd
     fi
     # Case 1: Assume amanda_user is correct.
-    check_user "homedir" "${AMANDAHOMEDIR}"
-    assertEquals "check_user homedir ${AMANDAHOMEDIR}" 0 $?
+    check_user_homedir "${AMANDAHOMEDIR}"
+    assertEquals "check_user_homedir ${AMANDAHOMEDIR}" 0 $?
     # Case 2: Provide an incorrect homedir
-    check_user "homedir" "/tmp"
-    assertEquals "check_user homedir /tmp" 1 $?
-}
+    check_user_homedir "/tmp"
+    assertEquals "check_user_homedir /tmp" 1 $?
+}
+
+test_check_user_uid() {
+    echo "${amanda_group}" > ${MOCKDIR}/id_group
+    touch ${MOCKDIR}/id_exists
+    logger 'test_check_user_uid'
+    for os in linux osx solaris; do
+        echo $os > ${MOCKDIR}/id_os
+        check_user_uid
+        assertEquals "check_user_uid without a uid" 1 $?
+        logger 'test_check_user_uid wrong id'
+        check_user_uid 123
+        assertEquals "check_user_uid uids don't match" 1 $?
+        logger 'test_check_user_uid correct id'
+        check_user_uid ${deb_uid}
+    done
 
+}
 test_check_homedir_dir_missing() {
     logger "test_check_homedir_dir_missing"
     # First make sure the dir is missing
@@ -416,6 +448,61 @@ test_check_homedir_dir_missing() {
     assertNotEquals "check_homedir returned 0, but homedir did not exist" 0 $?
 }
 
+# passwd file entry for Linux systems, maybe others.  UID is correct
+# for Debian as well.
+good_passwd_entry="${amanda_user}:x:${mock_deb_uid}:6::${AMANDAHOMEDIR}:/bin/bash"
+export good_passwd_entry
+test_create_user() {
+    logger "test_create_user"
+    if [ ! "$IAmRoot" ]; then
+       startSkipping
+       echo "test_create_user: Creating mock passwd file."
+       echo "$good_passwd_entry" > ${SYSCONFDIR}/passwd
+       echo "test_create_user: tests skipped."
+       #TODO: mock useradd.
+       return
+    fi
+    # Case 1: create_user should succeed.
+    create_user
+    assertEquals "create_user()" 0 $?
+}
+
+test_add_group_check_parameters_logs() {
+    rm -f ${MOCKDIR}/groupadd_rc ${MOCKDIR}/num_groups
+    # Return codes are integers.
+    printf '%i' 0 > ${MOCKDIR}/groupadd_rc
+    # Test that first parameter is required.
+    add_group
+    assertEquals "add_group without a group should fail." 1 $?
+    LOG_TAIL=`tail -1 ${LOGFILE}|cut -d " " -f 5-`
+    assertEquals "add_group should write" \
+        "Error: first argument was not a group to add." \
+        "${LOG_TAIL}"
+}
+
+test_add_group_group_ok() {
+    # groupadd created group
+    printf '%i' 0 > ${MOCKDIR}/groupadd_rc
+    echo '${amanda_user} : prev_grp1' > ${MOCKDIR}/groups_output
+    add_group twinkle
+    assertEquals "add_group group ok" 0 $?
+    flags=`cat ${mock_usermod_flags}`
+    assertEquals "usermod_flags" \
+        "usermod args: -G prev_grp1,twinkle ${amanda_user}" \
+        "${flags}"
+
+    # Make sure supplemental groups are preserved when adding groups to an
+    # existing account
+    echo '${amanda_user} : prev_grp1 prev_grp2' > ${MOCKDIR}/groups_output
+    printf '%i' 1 > ${MOCKDIR}/num_groups
+    add_group twinkle
+    assertEquals "add_group group ok" 0 $?
+    flags=`cat ${mock_usermod_flags}`
+    assertEquals "usermod_flags should contain:" \
+        "usermod args: -G prev_grp1,prev_grp2,twinkle ${amanda_user}" \
+        "${flags}"
+}
+
 test_create_homedir() {
     logger "test_create_homedir"
     rm -rf ${AMANDAHOMEDIR}
@@ -627,12 +714,11 @@ if [ $# -gt 0 ]; then
     echo $1
     SPECIFIC_TESTS="$*"
     suite() {
-       __shunit_suite="test___logger"
-       __shunit_suite="$__shunit_suite test__log_output_of"
-       __shunit_suite="$__shunit_suite $SPECIFIC_TESTS"
-       # Set the test total including the 3 base tests.
-       __shunit_testsTotal=`expr 2 + $#`
         suite_addTest test___logger
+        suite_addTest test__log_output_of
+        for t in $SPECIFIC_TESTS; do
+            suite_addTest $t
+        done
     }
 fi
 
index c28fc4c57704a31020f9e4f2f995f88f51a3560b..5d6cb34a985b04e86e6a2df84364c41cf58f1961 100644 (file)
@@ -1,104 +1,5 @@
 #!/bin/sh
-
-SYSCONFDIR="/etc"
-LOCALSTATEDIR="/var"
-LOGDIR="${LOCALSTATEDIR}/log/amanda/"
-AMANDAHOMEDIR="${LOCALSTATEDIR}/lib/amanda"
-amanda_user=amandabackup
-amanda_group=disk
-xinetd_reload="restart"
-
-
-# Installing xinetd config and make it active.
-if [ -e /etc/xinetd.d ] && [ -d /etc/xinetd.d ] ; then
-       if [ ! -f /etc/xinetd.d/amandaclient ] ; then
-               cp ${AMANDAHOMEDIR}/example/xinetd.amandaclient /etc/xinetd.d/amandaclient || exit 1
-               echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." 
-               if [ "${xinetd_reload}" = "reload" ] ; then
-                       /usr/sbin/invoke-rc.d xinetd ${xinetd_reload} # don't exit yet...
-                       if [ $? -ne 0 ] ; then
-                               echo -n "reload failed.  Attempting restart..." 
-                               /usr/sbin/invoke-rc.d xinetd restart || exit 1
-                       fi
-               else
-                       /usr/sbin/invoke-rc.d xinetd ${xinetd_reload} || exit 1
-               fi
-       fi
-fi
-
-echo "`date +'%b %e %Y %T'`: Installing '${LOCALSTATEDIR}/amanda/amandates'." 
-if [ ! -f ${LOCALSTATEDIR}/amanda/amandates ] ; then
-       touch ${LOCALSTATEDIR}/amanda/amandates || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${LOCALSTATEDIR}/amanda/amandates'." 
-chown ${amanda_user}:${amanda_group} ${LOCALSTATEDIR}/amanda/amandates || exit 1
-chmod 0640 ${LOCALSTATEDIR}/amanda/amandates || exit 1
-if [ -x /sbin/restorecon ] ; then
-      /sbin/restorecon ${LOCALSTATEDIR}/amanda/amandates  || exit 1
-fi
-
-# Install .amandahosts to client
-echo "`date +'%b %e %Y %T'`: Checking '${AMANDAHOMEDIR}/.amandahosts' file." 
-if [ ! -f ${AMANDAHOMEDIR}/.amandahosts ] ; then
-       touch ${AMANDAHOMEDIR}/.amandahosts || exit 1
-fi
-for host in localhost localhost.localdomain ; do
-               if [ -z "`grep \"^${host}[[:blank:]]\+${amanda_user}[[:blank:]]\+amdump\" ${AMANDAHOMEDIR}/.amandahosts`" ] ; then
-                       echo "${host} ${amanda_user} amdump" >> "${AMANDAHOMEDIR}/.amandahosts" || exit 1
-               fi
-done
-chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.amandahosts || exit 1
-chmod 0600 ${AMANDAHOMEDIR}/.amandahosts || exit 1
-
-# Install amanda client configuration file
-echo "`date +'%b %e %Y %T'`: Checking '${SYSCONFDIR}/amanda/amanda-client.conf' file." 
-if [ ! -f ${SYSCONFDIR}/amanda/amanda-client.conf ] ; then
-       cp ${AMANDAHOMEDIR}/example/amanda-client.conf ${SYSCONFDIR}/amanda/amanda-client.conf || exit 1
-fi
-chown ${amanda_user}:${amanda_group} ${SYSCONFDIR}/amanda/amanda-client.conf || exit 1
-chmod 0600 ${SYSCONFDIR}/amanda/amanda-client.conf || exit 1
-
-# Install .gnupg directory
-echo "`date +'%b %e %Y %T'`: Installing '${AMANDAHOMEDIR}/.gnupg'." 
-if [ ! -d ${AMANDAHOMEDIR}/.gnupg ] ; then
-       echo "`date +'%b %e %Y %T'`: '${AMANDAHOMEDIR}/.gnupg' will be created." 
-       mkdir ${AMANDAHOMEDIR}/.gnupg || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${AMANDAHOMEDIR}/.gnupg'." 
-chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.gnupg || exit 1
-chmod 700 ${AMANDAHOMEDIR}/.gnupg || exit 1
-
-# SSH RSA key generation on client for amrecover
-KEYDIR="${AMANDAHOMEDIR}/.ssh"
-KEYFILE="id_rsa_amrecover"
-COMMENT="root@client"
-if [ ! -d ${KEYDIR} ] ; then
-       if [ -f ${KEYDIR} ] ; then
-               echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file.  Renaming to '${KEYDIR}.save'." 
-               mv ${KEYDIR} ${KEYDIR}.save || exit 1
-       fi
-       echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." 
-       mkdir ${KEYDIR} || exit 1
-fi
-if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then
-       echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" 
-       ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Setting permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" 
-chown ${amanda_user}:${amanda_group} ${KEYDIR} || exit 1
-chmod 0750 ${KEYDIR} || exit 1
-chmod 0600 ${KEYDIR}/${KEYFILE}* || exit 1
-
-# environment variables (~amandabackup/.profile)
-echo "`date +'%b %e %Y %T'`: Checking for '${AMANDAHOMEDIR}/.profile' and ensuring correct environment." 
-if [ ! -f ${AMANDAHOMEDIR}/.profile ] ; then
-       touch ${AMANDAHOMEDIR}/.profile || exit 1
-fi
-if [ -z "`grep PATH ${AMANDAHOMEDIR}/.profile | grep '/usr/sbin'`" ] ; then
-       echo "export PATH=\"\$PATH:/usr/sbin/\"" >> "${AMANDAHOMEDIR}/.profile" || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${AMANDAHOMEDIR}/.profile'" 
-chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.profile || exit 1
-chmod 0640 ${AMANDAHOMEDIR}/.profile || exit 1
-
-echo "`date +'%b %e %Y %T'`: === Amanda backup client installation complete. ===" 
+# Debian recommends this.  Script exits on simple command failure.
+# set -e
+pkg_type=client
+other_pkg_type=server
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..78a6da512b301135aa01b75221ec413495589ce1 100644 (file)
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+pkg_type=client
+other_pkg_type=server
index 2f1ee20cad6a5b62d999d46452a39c9a9b32dff3..e958104a534d79db07b42de79cfc10bb7ac045e9 100644 (file)
@@ -1,144 +1,5 @@
 #!/bin/sh
 # Debian recommends this.  Script exits on simple command failure.
 # set -e
-LOGDIR="/var/log/amanda/"
-SYSCONFDIR="/etc"
-LOCALSTATEDIR="/var"
-AMANDAHOMEDIR="${LOCALSTATEDIR}/lib/amanda"
-AMTMP="/tmp/amanda"
-amanda_user=amandabackup
-amanda_group=disk
-xinetd_reload="restart"
-
-if [ -d /etc/xinetd.d ] ; then
-       if [ ! -f /etc/xinetd.d/amandaserver ] ; then
-               cp ${AMANDAHOMEDIR}/example/xinetd.amandaserver /etc/xinetd.d/amandaserver || exit 1
-               chmod 0644 /etc/xinetd.d/amandaserver || exit 1
-               if [ -f /etc/xinetd.d/amandaclient ] ; then
-                       rm /etc/xinetd.d/amandaclient || exit 1
-               fi
-               echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." 
-               if [ "${xinetd_reload}" = "reload" ] ; then
-                       /usr/sbin/invoke-rc.d xinetd ${xinetd_reload} # don't exit yet!
-                       if [ $? -ne 0 ] ; then
-                               echo -n "reload failed.  Attempting restart..." 
-                               /usr/sbin/invoke-rc.d xinetd restart || exit 1
-                       fi
-               else
-                       /usr/sbin/invoke-rc.d xinetd ${xinetd_reload} || exit 1
-               fi
-       fi
-fi
-
-echo "`date +'%b %e %Y %T'`: Installing '${LOCALSTATEDIR}/amanda/amandates'." 
-if [ ! -f ${LOCALSTATEDIR}/amanda/amandates ] ; then
-       touch ${LOCALSTATEDIR}/amanda/amandates || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${LOCALSTATEDIR}/amanda/amandates'." 
-chown ${amanda_user}:${amanda_group} ${LOCALSTATEDIR}/amanda/amandates || exit 1
-chmod 0640 ${LOCALSTATEDIR}/amanda/amandates || exit 1
-if [ -x /sbin/restorecon ] ; then
-      /sbin/restorecon ${LOCALSTATEDIR}/amanda/amandates  || exit 1
-fi
-
-# Check for existence of and permissions on ${AMTMP}
-if [ ! -d ${AMTMP} ]; then
-       mkdir ${AMTMP} || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${AMTMP}'." 
-chown ${amanda_user}:${amanda_group} ${AMTMP} || exit 1
-chmod 0640 ${AMTMP} || exit 1
-
-# install am_passphrase file to server
-echo "`date +'%b %e %Y %T'`: Checking '${AMANDAHOMEDIR}/.am_passphrase' file." 
-if [ ! -f ${AMANDAHOMEDIR}/.am_passphrase ] ; then
-        echo "`date +'%b %e %Y %T'`: Create '${AMANDAHOMEDIR}/.am_passphrase' file." 
-        touch ${AMANDAHOMEDIR}/.am_passphrase || exit 1
-        phrase=`echo $RANDOM | md5sum | awk '{print $1}'`
-        echo ${phrase} >>${AMANDAHOMEDIR}/.am_passphrase
-
-        chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.am_passphrase
-        chmod 0600 ${AMANDAHOMEDIR}/.am_passphrase 
-fi
-
-# Install .gnupg directory
-echo "`date +'%b %e %Y %T'`: Installing '${AMANDAHOMEDIR}/.gnupg'." 
-if [ ! -d ${AMANDAHOMEDIR}/.gnupg ] ; then
-       echo "`date +'%b %e %Y %T'`: '${AMANDAHOMEDIR}/.gnupg' will be created." 
-       mkdir ${AMANDAHOMEDIR}/.gnupg || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '${AMANDAHOMEDIR}/.gnupg'." 
-chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.gnupg || exit 1
-chmod 700 ${AMANDAHOMEDIR}/.gnupg || exit 1
-
-# Install .amandahosts to server
-echo "`date +'%b %e %Y %T'`: Checking '${AMANDAHOMEDIR}/.amandahosts' file." 
-if [ ! -f ${AMANDAHOMEDIR}/.amandahosts ] ; then
-       touch ${AMANDAHOMEDIR}/.amandahosts || exit 1
-fi
-for host in localhost localhost.localdomain ; do
-       if [ -z "`grep \"^${host}[[:blank:]]\+root[[:blank:]]\+amindexd[[:blank:]]\+amidxtaped\" ${AMANDAHOMEDIR}/.amandahosts`" ] ; then
-               echo "${host}   root amindexd amidxtaped" >>${AMANDAHOMEDIR}/.amandahosts || exit 1
-       fi
-       if [ -z "`grep \"^${host}[[:blank:]]\+${amanda_user}[[:blank:]]\+amdump\" ${AMANDAHOMEDIR}/.amandahosts`" ] ; then
-                echo "${host} ${amanda_user} amdump" >>${AMANDAHOMEDIR}/.amandahosts || exit 1
-       fi
-done
-chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.amandahosts || exit 1
-chmod 0600 ${AMANDAHOMEDIR}/.amandahosts || exit 1
-
-# SSH RSA key generation for amdump
-KEYDIR="${AMANDAHOMEDIR}/.ssh"
-KEYFILE="id_rsa_amdump"
-COMMENT="${amanda_user}@server"
-if [ ! -d ${KEYDIR} ] ; then
-       if [ -f ${KEYDIR} ] ; then
-               echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file.  Renaming to '${KEYDIR}.save'." 
-               mv ${KEYDIR} ${KEYDIR}.save || exit 1
-       fi
-       echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." 
-       mkdir ${KEYDIR} || exit 1
-fi
-if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then
-       echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" 
-       ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" 
-chown ${amanda_user}:${amanda_group} ${KEYDIR} ${KEYDIR}/${KEYFILE}* || exit 1
-chmod 0750 ${KEYDIR} || exit 1
-chmod 0600 ${KEYDIR}/${KEYFILE}* || exit 1
-
-# SSH RSA key generation on client for amrecover
-KEYDIR="${AMANDAHOMEDIR}/.ssh"
-KEYFILE="id_rsa_amrecover"
-COMMENT="root@client"
-if [ ! -d ${KEYDIR} ] ; then
-       if [ -f ${KEYDIR} ] ; then
-               echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file.  Renaming to '${KEYDIR}.save'." 
-               mv ${KEYDIR} ${KEYDIR}.save || exit 1
-       fi
-       echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." 
-       mkdir ${KEYDIR} || exit 1
-fi
-if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then
-       echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" 
-       ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Setting permissions for '${KEYDIR}'" 
-chown ${amanda_user}:${amanda_group} ${KEYDIR} || exit 1
-chmod 0750 ${KEYDIR} || exit 1
-chmod 0600 ${KEYDIR}/${KEYFILE}* || exit 1
-
-# environment variables (~amandabackup/.profile)
-echo "`date +'%b %e %Y %T'`: Checking for '${AMANDAHOMEDIR}/.profile' and ensuring correct environment." 
-if [ ! -f ${AMANDAHOMEDIR}/.profile ] ; then
-       touch ${AMANDAHOMEDIR}/.profile || exit 1
-fi
-if [ -z "`grep PATH ${AMANDAHOMEDIR}/.profile | grep '/usr/sbin'`" ] ; then
-       echo "export PATH=\"\$PATH:/usr/sbin/\"" >> "${AMANDAHOMEDIR}/.profile" || exit 1
-fi
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${AMANDAHOMEDIR}/.profile'" 
-chown ${amanda_user}:${amanda_group} ${AMANDAHOMEDIR}/.profile || exit 1
-chmod 0640 ${AMANDAHOMEDIR}/.profile || exit 1
-
-echo "`date +'%b %e %Y %T'`: === Amanda backup server installation complete. ===" 
+pkg_type=server
+other_pkg_type=client
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c1f3f4116626494b5815adf2072f71b70b59b6d9 100644 (file)
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+pkg_type=server
+other_pkg_type=client
index 516d1d96bb1247557376e78a58eb67eaae72c83f..69889a9c7387aa6db6488fe333d800f7a6cb6464 100755 (executable)
@@ -51,7 +51,14 @@ do_substitute() {
     # dpkg assumes that packages will have the same name on all releases and
     # that apt will prevent users from downloading the wrong build.  We want
     # this information helpfully obvious since we can't rely on apt.
-    /usr/bin/perl packaging/common/substitute.pl packaging/deb/changelog.src packaging/deb/changelog
+    file_list="packaging/deb/changelog \
+        packaging/deb/postinst \
+        packaging/deb/postrm \
+        packaging/deb/preinst"
+    for file in ${file_list}; do
+        /usr/bin/perl packaging/common/substitute.pl \
+            ${file}.src ${file} || exit 1
+    done
 }
 
 do_resources() {
diff --git a/packaging/deb/postinst.src b/packaging/deb/postinst.src
new file mode 100644 (file)
index 0000000..2497257
--- /dev/null
@@ -0,0 +1,75 @@
+# This is appended to packaging/deb/amanda-backup-*.postinst
+# vim: ft=sh
+
+# Note: this script needs to do the same things in all maintainer
+# script cases: configure, abort-remove, abort-upgrade.
+
+LOGFILE=`mktemp /tmp/amanda-postinst.log.XXXXXXXXXXX`
+if [ $? -ne 0 ]; then
+       echo "Unable to create log file!"
+       exit 1
+fi
+amanda_user=amandabackup
+amanda_group=disk
+AMANDAHOMEDIR=%%AMANDAHOMEDIR%%
+os=Linux
+dist=%%DISTRO%%
+LOGDIR=%%LOGDIR%%
+INSTALL_LOG="${LOGDIR}/install.log"
+SYSCONFDIR=/etc
+SBINDIR=/usr/sbin
+AMTMP="/tmp/amanda"
+
+AMANDATES=${SYSCONFDIR}/amandates
+
+# ---------- Common functions ------------
+%%COMMON_FUNCTIONS%%
+%%POST_INST_FUNCTIONS%%
+
+# -------- End Common functions ----------
+
+check_xinetd "amanda${pkg_type}"
+case $? in
+       0) backup_xinetd "amanda${pkg_type}"
+          install_xinetd "amanda${pkg_type}"
+       ;;
+       1) install_xinetd "amanda${pkg_type}" ;;
+       2) logger "Xinetd config not installed: either xinetd config is not present or xinetd.d is a file." ;;
+       *) logger "bad return from check_xinetd"
+          cat ${LOGFILE} >> ${INSTALL_LOG}
+          exit 1
+       ;;
+esac
+
+# amanda${pkg_type} should not have the amanda${other_pkg_type} xinetd installed.
+check_xinetd "amanda${other_pkg_type}"
+case $? in
+       0) backup_xinetd "amanda${other_pkg_type}" ;;
+esac
+
+reload_xinetd
+create_amandates
+check_amandates
+create_gnupg
+check_gnupg
+create_amandahosts
+check_amandahosts_entry root amindexd amidxtaped
+check_amandahosts_entry ${amanda_user} amdump
+check_amandahosts_perms
+create_ssh_key ${pkg_type}
+if [ "${pkg_type}" = "server" ]; then
+    create_ssh_key ${other_pkg_type}
+fi
+create_profile
+check_profile
+install_client_conf
+create_ampassphrase
+create_amtmp
+
+logger "Amanda ${pkg_type} installation complete."
+cat $LOGFILE >> $INSTALL_LOG && {
+    rm $LOGFILE;
+    echo "Amanda installation log can be found in '${INSTALL_LOG}'.";
+} || \
+    echo "Amanda installation log can be found in '${LOGFILE}'.";
+
diff --git a/packaging/deb/postrm b/packaging/deb/postrm
deleted file mode 100755 (executable)
index e972af6..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh -e
-case "$1" in
-  purge)
-       if [ -d /etc/amanda ]; then
-               # remove /etc amanda if there are no files left
-               rmdir /etc/amanda 2> /dev/null || true
-       fi
-       if [ -d /var/log/amanda ]; then
-               rm -rf /var/log/amanda
-       fi
-       if [ -d /var/lib/amanda/gnutar-lists ]; then
-               rm -rf /var/lib/amanda/gnutar-lists
-       fi
-       if [ -d /var/lib/amanda ]; then
-               rm -rf /var/lib/amanda
-       fi
-       if which deluser >/dev/null 2>&1 ; then
-               for group in disk; do
-                       # only call deluser when amandabackup is in $group
-                       if getent group "$group" |
-                          awk -F: '{ print $4 }' |
-                          awk -F, '{ for (i=1; i <= NF; i++ ) print $i }' |
-                          grep '^amandabackup$' > /dev/null; then
-                               deluser "amandabackup $group" || true
-                       fi
-               done
-       fi
-  ;;
-  remove|upgrade|deconfigure)
-  ;;
-
-  failed-upgrade)
-  ;;
-
-  *)
-        echo "unknown argument --> $1" >&2
-        exit 0
-  ;;
-esac
diff --git a/packaging/deb/postrm.src b/packaging/deb/postrm.src
new file mode 100755 (executable)
index 0000000..20150a4
--- /dev/null
@@ -0,0 +1,86 @@
+# This get appended to amanda-backup-*-.postrm
+# vim: ft=sh
+
+LOGFILE=`mktemp /tmp/amanda-remove.log.XXXXXXXXXXX`
+if [ $? -ne 0 ]; then
+       echo "Unable to create log file!"
+       exit 1
+fi
+amanda_user=amandabackup
+amanda_group=disk
+AMANDAHOMEDIR=%%AMANDAHOMEDIR%%
+os=Linux
+dist=%%DISTRO%%
+
+LOGDIR=%%LOGDIR%%
+SYSCONFDIR=/etc
+
+# ---------- Common functions ------------
+# see packaging/common/ in the source tree
+%%COMMON_FUNCTIONS%%
+%%POST_RM_FUNCTIONS%%
+
+# -------- End Common functions ----------
+remove() {
+    if check_xinetd "amanda${pkg_type}"; then
+        rm_xinetd "amanda${pkg_type}" || { \
+        logger "Warning: Did not successfully remove amanda${pkg_type} from xinetd.";
+            exit 1; }
+        reload_xinetd
+    fi
+
+}
+
+purge() {
+    if [ -d ${SYSCONFDIR}/amanda ]; then
+        logger "Removing ${SYSCONFDIR}/amanda if empty..."
+        rmdir ${SYSCONFDIR}/amanda 2> /dev/null || true
+    fi
+    if [ -d ${LOGDIR} ]; then
+        logger "Removing ${LOGDIR}..."
+        rm -rf ${LOGDIR}
+    fi
+    if [ -d ${AMANDAHOMEDIR} ]; then
+        logger "Removing ${AMANDAHOMEDIR}..."
+        rm -rf ${AMANDAHOMEDIR}
+    fi
+    if [ -f ${SYSCONFDIR}/amandates ]; then
+        logger "Removing ${SYSCONFDIR}/amandates..."
+        rm -rf ${SYSCONFDIR}/amandates
+    fi
+    # Remove ${amanda_user} from sensitive groups.
+    if which deluser >/dev/null 2>&1 ; then
+        for group in tape; do
+            # only call deluser when amandabackup is in $group
+            if getent group "$group" |
+                awk -F: '{ print $4 }' |
+                awk -F, '{ for (i=1; i <= NF; i++ ) print $i }' |
+                grep "^${amanda_user}$" > /dev/null; then
+                    deluser ${amanda_user} $group || true
+            fi
+        done
+    fi
+}
+
+case "$1" in
+  purge|abort-install)
+    remove
+    purge
+  ;;
+  remove|upgrade|deconfigure)
+    remove
+  ;;
+
+  failed-upgrade)
+    check_xinetd "amanda${pkg_type}"
+    if [ $? -eq 1 ] ; then
+       install_xinetd
+       reload_xinetd
+    fi
+  ;;
+
+  *)
+        echo "unknown argument --> $1" >&2
+        exit 0
+  ;;
+esac
diff --git a/packaging/deb/preinst b/packaging/deb/preinst
deleted file mode 100755 (executable)
index 6180b1f..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/bin/sh 
-
-amanda_user=amandabackup
-amanda_group=disk
-
-TMPFILE=`mktemp /tmp/deb-amanda.XXXXXXXXXXX`
-if [ $? -ne 0 ]; then
-       echo "Unable to mktemp!" 1>&2
-       exit 1
-fi
-LOGDIR="/var/log/amanda"
-INSTALL_LOG="${LOGDIR}/install.log"
-INSTALL_ERR="${LOGDIR}/install.err"
-
-echo "`date +'%b %e %Y %T'`: Preparing to install Amanda" >${TMPFILE}
-
-# Check for the '${amanda_user}' user
-echo "`date +'%b %e %Y %T'`: Checking for ${amanda_user} user..." >>${TMPFILE}
-if [ "`id -u ${amanda_user} >/dev/null 2>&1 && echo 0 || echo 1`" != "0" ] ; then
-       useradd -c "Amanda" -g ${amanda_group} -d /var/lib/amanda -s /bin/bash ${amanda_user}
-       # Lock the ${amanda_user} account until admin sets password
-       passwd -l ${amanda_user} >>/dev/null
-       PASSWD_EXIT=$?
-       if [ ${PASSWD_EXIT} -eq 0 ] ; then
-               echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  The ${amanda_user} user account has been successfully created." >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  Furthermore, the account has been automatically locked for you" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  for security purposes.  Once a password for the  '${amanda_user}'" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  account has been set, the user can be unlocked by issuing" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  the following command as root.:" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  # passwd -u ${amanda_user}" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  If this is not a new installation of Amanda and you have" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  pre-existing Amanda configurations in /etc/amanda" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  you should ensure that 'dumpuser' is set to '${amanda_user}'" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  in those configurations.  Additionally, you should ensure" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  that /var/lib/amanda/.amandahosts on your client systems" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  is properly configured to allow connections for the user" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  '${amanda_user}'." >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-               PASSWD_OK=0
-       else
-               echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!  The '${amanda_user}' user account for this system has been   !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!  created, however the user has no password set. For   !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!  security purposes this account  is normally locked   !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!  after creation.  Unfortunately,  when locking this   !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!  account an error occurred.  To ensure the security   !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!  of your system  you should set a password  for the   !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!  user account '${amanda_user}' immediately!  To set  such a   !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!  password, please issue the following command.:       !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!   # passwd ${amanda_user}" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-               PASSWD_OK=1
-       fi
-else
-       # log information about '${amanda_user}' user parameters
-       echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  The Amanda backup software is configured to operate as the" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  user '${amanda_user}'.  This user exists on your system and has not" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  been modified.  To ensure that Amanda functions properly," >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  please see that the following parameters are set for that" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  user.:" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  SHELL:          /bin/bash" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  HOME:           /var/lib/amanda" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  Default group:  ${amanda_group}" >>${TMPFILE}
-       echo "`date +'%b %e %Y %T'`:  Verifying ${amanda_user} user parameters :" >>${TMPFILE}
-       
-
-        if [ "`id -gn ${amanda_user}`" != "${amanda_group}" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user '${amanda_user}' is not part of the ${amanda_group} group, !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! please make sure it is corrected before start using amanda  !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified group name of user '${amanda_user}'" >>${TMPFILE}
-        fi
-
-       echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-       PASSWD_OK=0
-fi
-if [ -d /var/lib/amanda ] ; then
-       echo -n "`date +'%b %e %Y %T'`:  Checking ownership of '/var/lib/amanda'... " >>${TMPFILE}
-       if [ "`ls -dl /var/lib/amanda | awk '//{split($_,x); print x[3]}'`" = "${amanda_user}" ] && \
-          [ "`ls -dl /var/lib/amanda | awk '//{split($_,x); print x[4]}'`" = "${amanda_group}" ] ; then
-               echo "correct." >>${TMPFILE}
-               VARLIB_OK=0
-       else
-               echo "incorrect!" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  Please ensure that the directory '/var/lib/amanda' is owned by" >>${TMPFILE}
-               echo "`date +'%b %e %Y %T'`:  the user '${amanda_user}' and group '${amanda_group}'." >>${TMPFILE}
-               VARLIB_OK=1
-       fi
-else
-       VARLIB_OK=0
-fi
-echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-if [ ! -e ${LOGDIR} ] ; then
-       # create log directory
-       mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1
-       chown ${amanda_user}:${amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1
-fi
-
-if [ ${PASSWD_OK} -eq 1 ] || [ ${VARLIB_OK} -eq 1 ] ; then
-       cat ${TMPFILE}
-       cat ${TMPFILE} >>${INSTALL_ERR}
-       echo "Please review '${INSTALL_ERR}' to correct errors which have prevented the Amanda installation." >&2
-       echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'."
-       exit 1
-else
-       cat ${TMPFILE}
-       cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-
-echo "`date +'%b %e %Y %T'`: === Amanda installation started. ===" >${TMPFILE}
-
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-if [ -f "${TMPFILE}" ]; then
-       rm -f "${TMPFILE}"
-fi
-
diff --git a/packaging/deb/preinst.src b/packaging/deb/preinst.src
new file mode 100755 (executable)
index 0000000..2e67461
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh
+# This is appended to packaging/deb/amanda-backup-*.preinst
+# vim: ft=sh
+
+LOGFILE=`mktemp /tmp/amanda-preinst.log.XXXXXXXXXXX`
+if [ $? -ne 0 ]; then
+    echo "Unable to mktemp!" 1>&2
+    exit 1
+fi
+amanda_user=amandabackup
+amanda_group=disk
+AMANDAHOMEDIR=%%AMANDAHOMEDIR%%
+os=`uname`
+wanted_shell=/bin/bash
+dist=%%DISTRO%%
+LOGDIR=%%LOGDIR%%
+INSTALL_LOG=${LOGDIR}/install.log
+SYSCONFDIR=/etc
+# We require amandabackup to have a specific uid because buildtime uid is
+# recorded in deb packages.  This number should avoid conflict
+deb_uid=63998
+
+# See packaging/common/ for shell function libraries.
+# ---------- Common functions ------------
+%%COMMON_FUNCTIONS%%
+%%PRE_INST_FUNCTIONS%%
+
+# -------- End Common functions ----------
+logger "Preparing to install: Amanda Server %%VERSION%%"
+create_user
+check_user_group "${amanda_group}" || add_group "${amanda_group}"
+check_user_supplemental_group "tape" || add_group "tape"
+check_user_shell "${wanted_shell}"
+check_user_homedir "${AMANDAHOMEDIR}"
+check_homedir || create_homedir
+create_logdir
+
+logger "Preinstall done."
+cat $LOGFILE >> $INSTALL_LOG && rm $LOGFILE || \
+    echo "Amanda preinstall logs can be found in '$LOGFILE'."
index 1d75bbed5ea1022b5c5f9aed109538a1b8f628f5..acf900c713255b50bbf1c6e0267261b708deb4f0 100755 (executable)
@@ -1,13 +1,13 @@
 #!/usr/bin/make -f
-# debian/rules for amanda using debhelper. GNU copyright 2008 by Dan Locks, 
+# debian/rules for amanda using debhelper. GNU copyright 2008 by Dan Locks,
 # based on work by Bdale Garbee.
 
 #      Warning - do *not* use -j on an SMP machine, or the build gets
-#              confused... some sort of race condition in the makefiles?
+#      confused... some sort of race condition in the makefiles?
 
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
-AMVER=3.2alpha
+AMVER=`cat FULL_VERSION`
 
 # These are variables that the user can override.  They get used in various
 # places during configure, build, and install.
@@ -45,8 +45,8 @@ DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
 
 WD=$(shell pwd)
 
-build: build-stamp 
-build-stamp: /sbin/dump /usr/bin/smbclient 
+build: build-stamp
+build-stamp: /sbin/dump /usr/bin/smbclient
        dh_testdir
        ./configure \
                MAKEFLAGS="-j1 " \
@@ -81,11 +81,14 @@ build-stamp: /sbin/dump /usr/bin/smbclient
                --enable-s3-device \
                --disable-installperms
        touch missing
-       # There's probably a better way to do this.  Preinst and postrm are the
-       # same for client and server, but we leave room for differences by just
-       # appending here.
+       # Preinst is the same for client and server, but we leave room for
+       # differences by just appending here.
        cat $(WD)/debian/preinst >> $(WD)/debian/amanda-backup-client.preinst
        cat $(WD)/debian/preinst >> $(WD)/debian/amanda-backup-server.preinst
+       # Postinst and postrm keep client/server differences to just variables;
+       # the postinst/postrm logic is otherwise the same.
+       cat $(WD)/debian/postinst >> $(WD)/debian/amanda-backup-client.postinst
+       cat $(WD)/debian/postinst >> $(WD)/debian/amanda-backup-server.postinst
        cat $(WD)/debian/postrm >> $(WD)/debian/amanda-backup-client.postrm
        cat $(WD)/debian/postrm >> $(WD)/debian/amanda-backup-server.postrm
        make -s LIBTOOLFLAGS=--silent
@@ -177,8 +180,8 @@ binary-arch: build
                $(server)$(AMLIBEXECDIR)/planner \
                $(server)/usr/sbin/amcheck \
                $(server)/usr/sbin/amservice
-       echo "Amanda version $(AMVER)" >  $(server)/$(AMANDAHOMEDIR)/amanda-release 
-       echo "Amanda version $(AMVER)" >  $(client)/$(AMANDAHOMEDIR)/amanda-release 
+       echo "Amanda version $(AMVER)" >  $(server)/$(AMANDAHOMEDIR)/amanda-release
+       echo "Amanda version $(AMVER)" >  $(client)/$(AMANDAHOMEDIR)/amanda-release
        install -o root -g root -m 0644 debian/amanda-backup-client.lintian \
                $(client)/usr/share/lintian/overrides/amanda-backup-client
        install -o root -g root -m 0644 debian/amanda-backup-server.lintian \
@@ -191,7 +194,7 @@ binary-arch: build
        dh_md5sums  >> $(log) 2>&1
        dh_builddeb  >> $(log) 2>&1
 
-source diff:                                                                  
+source diff:
        @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
 
 binary: binary-arch
index ec55de84d383481920f7f43830f4ac4577eb44eb..4e59570c45c09c27c76cb1206bdc6da7f93c1b86 100644 (file)
@@ -1,5 +1,5 @@
 #
-#                  Copyright (C) 2005 Zmanda Incorporated.
+#                  Copyright (C) 2005-2012 Zmanda Incorporated.
 #                            All Rights Reserved.
 #
 #  This program is free software; you can redistribute it and/or modify it
 
 # --- Pre/post (un)installation scripts ---
 
-%pre
-TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX`
-if [ $? -ne 0 ]; then
-        echo "Unable to mktemp!" 1>&2
-        exit 1
-fi
-LOGDIR="%{LOGDIR}"
-INSTALL_LOG="${LOGDIR}/install.log"
-INSTALL_ERR="${LOGDIR}/install.err"
-
-echo "`date +'%b %e %Y %T'`: Preparing to install: %{amanda_version_info}" >${TMPFILE}
-
-# Check for the 'amanda' user
-echo "`date +'%b %e %Y %T'`: Checking for '%{amanda_user}' user..." >>${TMPFILE}
-if [ "`id -u %{amanda_user} > /dev/null 2>&1 && echo 0 || echo 1`" != "0" ] ; then
-        useradd -c "Amanda" -M -g %{amanda_group} -d %{AMANDAHOMEDIR} -s /bin/bash %{amanda_user}
-        if [ %{dist} = "SuSE" ]; then
-                PASSWD_EXIT=$?
-        else
-                # Lock the amanda account until admin sets password
-                passwd -l %{amanda_user} >>/dev/null
-                PASSWD_EXIT=$?
-        fi
-        if [ ${PASSWD_EXIT} -eq 0 ] ; then
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  The '%{amanda_user}; user account has been successfully created." >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  Furthermore, the account has been automatically locked for you" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  for security purposes.  Once a password for the  '%{amanda_user}'" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  account has been set, the user can be unlocked by issuing" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  the following command as root.:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  # passwd -u %{amanda_user}" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  If this is not a new installation of Amanda and you have" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  pre-existing Amanda configurations in %{SYSCONFDIR}/amanda" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  you should ensure that 'dumpuser' is set to '%{amanda_user}'" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  in those configurations.  Additionally, you should ensure" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  that %{AMANDAHOMEDIR}/.amandahosts on your client systems" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  is properly configured to allow connections for the user" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  '%{amanda_user}'." >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                PASSWD_OK=0
-        else
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  The '%{amanda_user}' user account for this system has been   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  created, however the user has no password set. For   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  security purposes this account  is normally locked   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  after creation.  Unfortunately,  when locking this   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  account an error occurred.  To ensure the security   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  of your system  you should set a password  for the   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  user account '%{amanda_user}' immediately!  To set  such a   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  password, please issue the following command.:       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!   # passwd %{amanda_user}                                   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                PASSWD_OK=1
-        fi
-else
-        # log information about 'amanda' user parameters
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  The Amanda backup software is configured to operate as the" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  user '%{amanda_user}'.  This user exists on your system and has not" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  been modified.  To ensure that Amanda functions properly," >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  please see that the following parameters are set for that" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  user.:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  SHELL:          /bin/bash" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  HOME:           %{AMANDAHOMEDIR}" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  Default group:  %{amanda_group}" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  Verifying %{amanda_user} parameters :" >>${TMPFILE}
-
-        if [ "`id -gn %{amanda_user}`" != "disk" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  user 'amandabackup' is not part of the disk group,Pl !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  make sure it is corrected before start using amanda  !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified group name of user 'amandabackup'" >>${TMPFILE}
-        fi
-
-        if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f7`" != "/bin/bash" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user 'amandabackup' default shell should be set to    !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! /bin/bash, pl correct before start using Amanda         !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified Default shell for user 'amandabackup'" >>${TMPFILE}
-        fi
-
-        if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f6`" != "%{AMANDAHOMEDIR}" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user 'amandabackup' home directory should be set to   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! %{AMANDAHOMEDIR} Pl correct before using Amanda       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified Default home directory for user amandabackup" >>${TMPFILE}
-        fi
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        PASSWD_OK=0
-fi
-if [ -d %{AMANDAHOMEDIR} ] ; then
-        echo -n "`date +'%b %e %Y %T'`:  Checking ownership of '%{AMANDAHOMEDIR}'... " >>${TMPFILE}
-        if [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[3]}'`" = "%{amanda_user}" ] && \
-           [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[4]}'`" = "%{amanda_group}" ] ; then
-                echo "correct." >>${TMPFILE}
-                VARLIB_OK=0
-        else
-                echo "incorrect!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  Please ensure that the directory '%{AMANDAHOMEDIR}' is owned by" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  the user '%{amanda_user}' and group '%{amanda_group}'." >>${TMPFILE}
-                VARLIB_OK=1
-        fi
-else
-        VARLIB_OK=0
-fi
-echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-if [ ! -e ${LOGDIR} ] ; then
-        # create log directory
-        mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1
-        chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1
-elif [ ! -d ${LOGDIR} ] ; then
-        mv ${LOGDIR} ${LOGDIR}.rpmsave >>${TMPFILE} 2>&1
-        mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1
-        chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1
-        mv ${LOGDIR}.rpmsave ${LOGDIR}/ >>${TMPFILE} 2>&1
-fi
-
-if [ ${PASSWD_OK} -eq 1 ] || [ ${VARLIB_OK} -eq 1 ] ; then
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-        echo "Please review '${INSTALL_ERR}' to correct errors which have prevented the Amanda installaton." >&2
-        echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'."
-        exit 1
-else
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-
-echo "`date +'%b %e %Y %T'`: === Amanda installation started. ===" >${TMPFILE}
-
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-if [ -f "${TMPFILE}" ]; then
-        rm -f "${TMPFILE}"
-fi
-
-%post
-TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX
-if [ $? -ne 0 ]; then
-        echo "Unable to mktemp!" 1>&2
-        exit 1
-fi
-LOGDIR="%{LOGDIR}"
-INSTALL_LOG="${LOGDIR}/install.log"
-INSTALL_ERR="${LOGDIR}/install.err"
-
-echo -n "`date +'%b %e %Y %T'`: Updating library cache..." >${TMPFILE}
-/sbin/ldconfig >>${TMPFILE} 2>&1
-echo "done." >>${TMPFILE}
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-if [ -e /etc/xinetd.d ] && [ -d /etc/xinetd.d ] ; then
-        if [ ! -f /etc/xinetd.d/amandaserver ] ; then
-                cp %{AMANDAHOMEDIR}/example/xinetd.amandaserver /etc/xinetd.d/amandaserver
-                chmod 0644 /etc/xinetd.d/amandaserver >>${TMPFILE} 2>&1
-                if [ -f /etc/xinetd.d/amandaclient ] ; then
-                        rm /etc/xinetd.d/amandaclient
-                fi
-                echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." >${TMPFILE}
-                if [ "%{xinetd_reload}" == "reload" ] ; then
-                        /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1
-                        ret_val=$?
-                        if [ ${ret_val} -ne 0 ] ; then
-                                echo -n "reload failed.  Attempting restart..." >>${TMPFILE}
-                                /etc/init.d/xinetd restart >>${TMPFILE} 2>&1
-                                ret_val=$?
-                        fi
-                else
-                        /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1
-                        ret_val=$?
-                fi
-                if [ ${ret_val} -eq 0 ] ; then
-                        echo "success." >>${TMPFILE}
-                        cat ${TMPFILE}
-                        cat ${TMPFILE} >>${INSTALL_LOG}
-                else
-                        echo "failed.  Please check your system logs." >>${TMPFILE}
-                        cat ${TMPFILE} 1>&2
-                        cat ${TMPFILE} >>${INSTALL_ERR}
-                fi
-        fi
-fi
-
-echo "`date +'%b %e %Y %T'`: Installing '%{AMANDATES}'." >${TMPFILE}
-ret_val=0
-if [ ! -f %{AMANDATES} ] ; then
-        touch %{AMANDATES} >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                echo "`date +'%b %e %Y %T'`: The file '%{AMANDATES}' has been created." >>${TMPFILE}
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDATES}'." >>${TMPFILE}
-        chown %{amanda_user}:%{amanda_group} %{AMANDATES} >>${TMPFILE} 2>&1
-        chmod 0640 %{AMANDATES} >>${TMPFILE} 2>&1
-        if [ -x /sbin/restorecon ] ; then
-              /sbin/restorecon %{AMANDATES}  >>${TMPFILE} 2>&1
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation successful." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-else
-        echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation failed." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-fi
-
-
-# Install .gnupg directory
-echo "`date +'%b %e %Y %T'`: Installing '%{AMANDAHOMEDIR}/.gnupg'." >${TMPFILE}
-ret_val=0
-if [ ! -d %{AMANDAHOMEDIR}/.gnupg ] ; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' will be created." >>${TMPFILE}
-        mkdir %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' created successfully." >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' creation failed." >>${TMPFILE}
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDAHOMEDIR}/.gnupg'." >>${TMPFILE}
-        chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                chmod 700 %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-                ret_val=$?
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation successful." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-else
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation failed." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-fi
-
-# Install .amandahosts
-echo "`date +'%b %e %Y %T'`: Checking '%{AMANDAHOMEDIR}/.amandahosts' file." >${TMPFILE}
-if [ ! -f %{AMANDAHOMEDIR}/.amandahosts ] ; then
-        touch %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-fi
-for host in localhost localhost.localdomain ; do
-        if [ -z "`grep \"^${host}[[:blank:]]\+root[[:blank:]]\+amindexd[[:blank:]]\+amidxtaped\" %{AMANDAHOMEDIR}/.amandahosts`" ] ; then
-                echo "${host}   root amindexd amidxtaped" >>%{AMANDAHOMEDIR}/.amandahosts
-        fi
-        if [ -z "`grep \"^${host}[[:blank:]]\+%{amanda_user}[[:blank:]]\+amdump\" %{AMANDAHOMEDIR}/.amandahosts`" ] ; then
-                echo "${host}   %{amanda_user} amdump" >>%{AMANDAHOMEDIR}/.amandahosts
-        fi
-done
-chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-chmod 0600 %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# SSH RSA key generation for amdump
-KEYDIR="%{AMANDAHOMEDIR}/.ssh"
-KEYFILE="id_rsa_amdump"
-COMMENT="%{amanda_user}@server"
-if [ ! -d ${KEYDIR} ] ; then
-        if [ -f ${KEYDIR} ] ; then
-                echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file.  Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE}
-                mv ${KEYDIR} ${KEYDIR}.rpmsave
-                cat ${TMPFILE}
-                cat ${TMPFILE} >>${INSTALL_LOG}
-        fi
-        echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE}
-        mkdir ${KEYDIR} >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then
-        echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-        ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" >${TMPFILE}
-chown %{amanda_user}:%{amanda_group} ${KEYDIR} ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1
-chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1
-chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# SSH RSA key generation on client for amrecover
-KEYDIR="%{AMANDAHOMEDIR}/.ssh"
-KEYFILE="id_rsa_amrecover"
-COMMENT="root@client"
-if [ ! -d ${KEYDIR} ] ; then
-        if [ -f ${KEYDIR} ] ; then
-                echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file.  Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE}
-                mv ${KEYDIR} ${KEYDIR}.rpmsave >>${TMPFILE} 2>&1
-                cat ${TMPFILE}
-                cat ${TMPFILE} >>${INSTALL_LOG}
-        fi
-        echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE}
-        mkdir ${KEYDIR} >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then
-        echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE}
-        ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-echo "`date +'%b %e %Y %T'`: Setting permissions for '${KEYDIR}'" >${TMPFILE}
-chown %{amanda_user}:%{amanda_group} ${KEYDIR} >>${TMPFILE} 2>&1
-chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1
-chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# environment variables (~amandabackup/.profile)
-echo "`date +'%b %e %Y %T'`: Checking for '%{AMANDAHOMEDIR}/.profile' and ensuring correct environment." >${TMPFILE}
-if [ ! -f %{AMANDAHOMEDIR}/.profile ] ; then
-        touch %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-fi
-if [ -z "`grep PATH %{AMANDAHOMEDIR}/.profile | grep '%{SBINDIR}'`" ] ; then
-        echo "export PATH=\"\$PATH:%{SBINDIR}\"" >>%{AMANDAHOMEDIR}/.profile 2>>${TMPFILE}
-fi
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '%{AMANDAHOMEDIR}/.profile'" >>${TMPFILE}
-chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-chmod 0640 %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-echo "`date +'%b %e %Y %T'`: Sending anonymous distribution and version information to Zmanda" >> ${INSTALL_LOG}
-if [ -x /usr/bin/wget ]; then 
-        /usr/bin/wget -q -o /dev/null -O - --timeout=5 http://www.zmanda.com/amanda-tips.php\?version=%{amanda_version}\&os=%{disttag}%{distver}\&type=server 
-fi
-
-echo "`date +'%b %e %Y %T'`: === Amanda installation complete. ===" >${TMPFILE}
-
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-if [ -f "${TMPFILE}" ]; then
-        rm -f "${TMPFILE}"
-fi
+# Define script variables
+# Some versions of rpmbuild do not like multi-line macros in spec files. ugly.
+%define script_vars amanda_user=%{amanda_user}; amanda_group=%{amanda_group}; AMANDAHOMEDIR=%{AMANDAHOMEDIR}; os=Linux; wanted_shell=/bin/bash; dist=%{dist}; LOGDIR=%{LOGDIR}; INSTALL_LOG=$LOGDIR/install.log; SYSCONFDIR=%{SYSCONFDIR}; SBINDIR=%{SBINDIR};
+# --- Pre/post (un)installation scripts ---
 
-echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'."
-%postun
-/sbin/ldconfig
 %pre backup_server
-TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX`
+##########################################
+LOGFILE=`mktemp /tmp/amanda_server-preinst.log.XXXXXXXXXXX`
 if [ $? -ne 0 ]; then
-        echo "Unable to mktemp!" 1>&2
+        echo "Unable to create log file!"
         exit 1
 fi
+%{script_vars}
 
-LOGDIR="%{LOGDIR}"
-INSTALL_LOG="${LOGDIR}/install.log"
-INSTALL_ERR="${LOGDIR}/install.err"
-
-echo "`date +'%b %e %Y %T'`: Preparing to install: %{amanda_version_info}" >${TMPFILE}
-
-# Check for the 'amanda' user
-echo "`date +'%b %e %Y %T'`: Checking for '%{amanda_user}' user..." >>${TMPFILE}
-if [ "`id -u %{amanda_user} > /dev/null 2>&1 && echo 0 || echo 1`" != "0" ] ; then
-        useradd -c "Amanda" -M -g %{amanda_group} -d %{AMANDAHOMEDIR} -s /bin/bash %{amanda_user}
-        if [ %{dist} = "SuSE" ]; then
-                PASSWD_EXIT=$?
-        else
-                # Lock the amanda account until admin sets password
-                passwd -l %{amanda_user} >>/dev/null
-                PASSWD_EXIT=$?
-        fi
-        if [ ${PASSWD_EXIT} -eq 0 ] ; then
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  The '%{amanda_user}; user account has been successfully created." >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  Furthermore, the account has been automatically locked for you" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  for security purposes.  Once a password for the  '%{amanda_user}'" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  account has been set, the user can be unlocked by issuing" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  the following command as root.:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  # passwd -u %{amanda_user}" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  If this is not a new installation of Amanda and you have" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  pre-existing Amanda configurations in %{SYSCONFDIR}/amanda" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  you should ensure that 'dumpuser' is set to '%{amanda_user}'" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  in those configurations.  Additionally, you should ensure" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  that %{AMANDAHOMEDIR}/.amandahosts on your client systems" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  is properly configured to allow connections for the user" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  '%{amanda_user}'." >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                PASSWD_OK=0
-        else
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  The '%{amanda_user}' user account for this system has been   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  created, however the user has no password set. For   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  security purposes this account  is normally locked   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  after creation.  Unfortunately,  when locking this   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  account an error occurred.  To ensure the security   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  of your system  you should set a password  for the   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  user account '%{amanda_user}' immediately!  To set  such a   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  password, please issue the following command.:       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!   # passwd %{amanda_user}                                     !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                PASSWD_OK=1
-        fi
-else
-        # log information about 'amanda' user parameters
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  The Amanda backup software is configured to operate as the" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  user '%{amanda_user}'.  This user exists on your system and has not" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  been modified.  To ensure that Amanda functions properly," >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  please see that the following parameters are set for that" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  user.:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  SHELL:          /bin/bash" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  HOME:           %{AMANDAHOMEDIR}" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  Default group:  %{amanda_group}" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  Verifying %{amanda_user} parameters :" >>${TMPFILE}
-
-        if [ "`id -gn %{amanda_user}`" != "disk" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user 'amandabackup' is not part of the disk group,Pl  !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! make sure it is corrected before start using Amanda   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified group name of user 'amandabackup'" >>${TMPFILE}
-        fi
 
-        if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f7`" != "/bin/bash" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user 'amandabackup' default shell should be set to    !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! /bin/bash, pl correct before start using Amanda         !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified Default shell for user 'amandabackup'" >>${TMPFILE}
-        fi
+# See packaging/common/ for shell function libraries.
+# ---------- Common functions ------------
+%%COMMON_FUNCTIONS%%
+%%PRE_INST_FUNCTIONS%%
 
-        if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f6`" != "%{AMANDAHOMEDIR}" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user 'amandabackup' home directory should be set to   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! %{AMANDAHOMEDIR} Pl correct before using Amanda       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified Default home directory for user amandabackup" >>${TMPFILE}
-        fi
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        PASSWD_OK=0
-fi
-if [ -d %{AMANDAHOMEDIR} ] ; then
-        echo -n "`date +'%b %e %Y %T'`:  Checking ownership of '%{AMANDAHOMEDIR}'... " >>${TMPFILE}
-        if [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[3]}'`" = "%{amanda_user}" ] && \
-           [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[4]}'`" = "%{amanda_group}" ] ; then
-                echo "correct." >>${TMPFILE}
-                VARLIB_OK=0
-        else
-                echo "incorrect!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  Please ensure that the directory '%{AMANDAHOMEDIR}' is owned by" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  the user '%{amanda_user}' and group '%{amanda_group}'." >>${TMPFILE}
-                VARLIB_OK=1
-        fi
-else
-        VARLIB_OK=0
-fi
-echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-
-if [ ! -e ${LOGDIR} ] ; then
-        # create log directory
-        mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1
-        chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1
-elif [ ! -d ${LOGDIR} ] ; then
-        mv ${LOGDIR} ${LOGDIR}.rpmsave >>${TMPFILE} 2>&1
-        mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1
-        chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1
-        mv ${LOGDIR}.rpmsave ${LOGDIR}/ >>${TMPFILE} 2>&1
-fi
-if [ ${PASSWD_OK} -eq 1 ] || [ ${VARLIB_OK} -eq 1 ] ; then
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-        echo "Please review '${INSTALL_ERR}' to correct errors which have prevented the Amanda installaton." >&2
-        echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'."
-        exit 1
-else
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
+# -------- End Common functions ----------
+logger "Preparing to install: Amanda Server %%VERSION%%"
+create_user
+check_user_group "${amanda_group}" || add_group "${amanda_group}"
+check_user_supplemental_group "tape" || add_group "tape"
+check_user_shell "${wanted_shell}"
+check_user_homedir "${AMANDAHOMEDIR}"
+check_homedir || create_homedir
+create_logdir
 
-echo "`date +'%b %e %Y %T'`: === Amanda backup server installation started. ===" >${TMPFILE}
+logger "Preinstall done."
+cat $LOGFILE > $INSTALL_LOG && rm $LOGFILE || \
+    echo "Amanda preinstall logs can be found in '$LOGFILE'."
 
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-if [ -f "${TMPFILE}" ]; then
-        rm -f "${TMPFILE}"
-fi
 %post backup_server
-TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX`
+##########################################
+LOGFILE=`mktemp /tmp/amanda_server-postinst.log.XXXXXXXXXXX`
 if [ $? -ne 0 ]; then
-        echo "Unable to mktemp!" 1>&2
+        echo "Unable to create log file!"
         exit 1
 fi
-LOGDIR="%{LOGDIR}"
-INSTALL_LOG="${LOGDIR}/install.log"
-INSTALL_ERR="${LOGDIR}/install.err"
+%{script_vars}
+AMANDATES=%{AMANDATES}
 
-echo -n "`date +'%b %e %Y %T'`: Updating system library cache..." >${TMPFILE}
-/sbin/ldconfig
-echo "done." >>${TMPFILE}
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-if [ -e /etc/xinetd.d ] && [ -d /etc/xinetd.d ] ; then
-        if [ ! -f /etc/xinetd.d/amandaserver ] ; then
-                cp %{AMANDAHOMEDIR}/example/xinetd.amandaserver /etc/xinetd.d/amandaserver
-                chmod 0644 /etc/xinetd.d/amandaserver >>${TMPFILE} 2>&1
-                if [ -f /etc/xinetd.d/amandaclient ] ; then
-                        rm /etc/xinetd.d/amandaclient
-                fi
-
-                echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." >${TMPFILE}
-                if [ "%{xinetd_reload}" == "reload" ] ; then
-                        /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1
-                        ret_val=$?
-                        if [ ${ret_val} -ne 0 ] ; then
-                                echo -n "reload failed.  Attempting restart..." >>${TMPFILE}
-                                /etc/init.d/xinetd restart >>${TMPFILE} 2>&1
-                                ret_val=$?
-                        fi
-                else
-                        /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1
-                        ret_val=$?
-                fi
-                if [ ${ret_val} -eq 0 ] ; then
-                        echo "success." >>${TMPFILE}
-                        cat ${TMPFILE}
-                        cat ${TMPFILE} >>${INSTALL_LOG}
-                else
-                        echo "failed.  Please check your system logs." >>${TMPFILE}
-                        cat ${TMPFILE} 1>&2
-                        cat ${TMPFILE} >>${INSTALL_ERR}
-                fi
-        fi
-fi
+# ---------- Common functions ------------
+%%COMMON_FUNCTIONS%%
+%%POST_INST_FUNCTIONS%%
 
-echo "`date +'%b %e %Y %T'`: Installing '%{AMANDATES}'." >${TMPFILE}
-ret_val=0
-if [ ! -f %{AMANDATES} ] ; then
-        touch %{AMANDATES} >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                echo "`date +'%b %e %Y %T'`: The file '%{AMANDATES}' has been created." >>${TMPFILE}
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDATES}'." >>${TMPFILE}
-        chown %{amanda_user}:%{amanda_group} %{AMANDATES} >>${TMPFILE} 2>&1
-        chmod 0640 %{AMANDATES} >>${TMPFILE} 2>&1
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation successful." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-else
-        echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation failed." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-fi
-
-# Install .amandahosts to server
-echo "`date +'%b %e %Y %T'`: Checking '%{AMANDAHOMEDIR}/.amandahosts' file." >${TMPFILE}
-if [ ! -f %{AMANDAHOMEDIR}/.amandahosts ] ; then
-        touch %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-fi
-for host in localhost localhost.localdomain ; do
-        if [ -z "`grep \"^${host}[[:blank:]]\+root[[:blank:]]\+amindexd[[:blank:]]\+amidxtaped\" %{AMANDAHOMEDIR}/.amandahosts`" ] ; then
-                echo "${host}   root amindexd amidxtaped" >>%{AMANDAHOMEDIR}/.amandahosts
-        fi
-        if [ -z "`grep \"^${host}[[:blank:]]\+%{amanda_user}[[:blank:]]\+amdump\" %{AMANDAHOMEDIR}/.amandahosts`" ] ; then
-                echo "${host}   %{amanda_user} amdump" >>%{AMANDAHOMEDIR}/.amandahosts
-        fi
-done
-chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-chmod 0600 %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# Install amanda client configuration file
-echo "`date +'%b %e %Y %T'`: Checking '%{SYSCONFDIR}/amanda/amanda-client.conf' file." >${TMPFILE}
-if [ ! -f %{SYSCONFDIR}/amanda/amanda-client.conf ] ; then
-        cp %{AMANDAHOMEDIR}/example/amanda-client.conf %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1
-fi
-chown %{amanda_user}:%{amanda_group} %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1
-chmod 0600 %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# install am_passphrase file to server
-echo "`date +'%b %e %Y %T'`: Checking '%{AMANDAHOMEDIR}/.am_passphrase' file." >${TMPFILE}
-if [ ! -f %{AMANDAHOMEDIR}/.am_passphrase ] ; then
-        echo "`date +'%b %e %Y %T'`: Create '%{AMANDAHOMEDIR}/.am_passphrase' file." >${TMPFILE}
-        touch %{AMANDAHOMEDIR}/.am_passphrase >>${TMPFILE} 2>&1
-        phrase=`echo $RANDOM | md5sum | awk '{print $1}'`
-        echo ${phrase} >>%{AMANDAHOMEDIR}/.am_passphrase
-
-        chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.am_passphrase >>${TMPFILE} 2>&1
-        chmod 0700 %{AMANDAHOMEDIR}/.am_passphrase >>${TMPFILE} 2>&1
-fi
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# Install .gnupg directory
-echo "`date +'%b %e %Y %T'`: Installing '%{AMANDAHOMEDIR}/.gnupg'." >${TMPFILE}
-ret_val=0
-if [ ! -d %{AMANDAHOMEDIR}/.gnupg ] ; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' will be created." >>${TMPFILE}
-        mkdir %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' created successfully." >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' creation failed." >>${TMPFILE}
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDAHOMEDIR}/.gnupg'." >>${TMPFILE}
-        chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                chmod 700 %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-                ret_val=$?
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation successful." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-else
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation failed." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-fi
-
-# SSH RSA key generation on server for amdump
-KEYDIR="%{AMANDAHOMEDIR}/.ssh"
-KEYFILE="id_rsa_amdump"
-COMMENT="%{amanda_user}@server"
-if [ ! -d ${KEYDIR} ] ; then
-        if [ -f ${KEYDIR} ] ; then
-                echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file.  Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE}
-                mv ${KEYDIR} ${KEYDIR}.rpmsave >>${TMPFILE} 2>&1
-                cat ${TMPFILE}
-                cat ${TMPFILE} >>${INSTALL_LOG}
-        fi
-        echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE}
-        mkdir ${KEYDIR} >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then
-        echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE}
-        ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" >${TMPFILE}
-chown %{amanda_user}:%{amanda_group} ${KEYDIR} ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1
-chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1
-chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# SSH RSA key generation on client for amrecover
-KEYDIR="%{AMANDAHOMEDIR}/.ssh"
-KEYFILE="id_rsa_amrecover"
-COMMENT="root@client"
-if [ ! -d ${KEYDIR} ] ; then
-        if [ -f ${KEYDIR} ] ; then
-                echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file.  Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE}
-                mv ${KEYDIR} ${KEYDIR}.rpmsave >>${TMPFILE} 2>&1
-                cat ${TMPFILE}
-                cat ${TMPFILE} >>${INSTALL_LOG}
-        fi
-        echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE}
-        mkdir ${KEYDIR} >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then
-        echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE}
-        ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '${KEYDIR}'" >${TMPFILE}
-chown %{amanda_user}:%{amanda_group} ${KEYDIR} >>${TMPFILE} 2>&1
-chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1
-chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# environment variables (~amandabackup/.profile)
-echo "`date +'%b %e %Y %T'`: Checking for '%{AMANDAHOMEDIR}/.profile' and ensuring correct environment." >${TMPFILE}
-if [ ! -f %{AMANDAHOMEDIR}/.profile ] ; then
-        touch %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-fi
-if [ -z "`grep PATH %{AMANDAHOMEDIR}/.profile | grep '%{SBINDIR}'`" ] ; then
-        echo "export PATH=\"\$PATH:%{SBINDIR}\"" >>%{AMANDAHOMEDIR}/.profile 2>>${TMPFILE}
-fi
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '%{AMANDAHOMEDIR}/.profile'" >${TMPFILE}
-chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-chmod 0640 %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-echo "`date +'%b %e %Y %T'`: Sending anonymous distribution and version information to Zmanda" >> ${INSTALL_LOG}
-if [ -x /usr/bin/wget ]; then 
-        /usr/bin/wget -q -o /dev/null -O - --timeout=5 http://www.zmanda.com/amanda-tips.php\?version=%{amanda_version}\&os=%{disttag}%{distver}\&type=server 
-fi
-
-echo "`date +'%b %e %Y %T'`: === Amanda backup server installation complete. ===" >${TMPFILE}
+# -------- End Common functions ----------
+/sbin/ldconfig
 
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
+check_xinetd "amandaserver"
+case $? in
+       0) backup_xinetd "amandaserver"
+          install_xinetd "amandaserver"
+       ;;
+       1) install_xinetd "amandaserver" ;;
+       2) logger "Xinetd config not installed: either xinetd config is not present or xinetd.d is a file." ;;
+       *) logger "bad return from check_xinetd"; exit 1 ;;
+esac
+
+# Amanda servers should not have the client xinetd installed.
+check_xinetd "amandaclient"
+case $? in
+       0) backup_xinetd "amandaclient" ;;
+esac
+
+reload_xinetd
+create_amandates
+check_amandates
+create_gnupg
+check_gnupg
+create_amandahosts
+check_amandahosts_entry root amindexd amidxtaped
+check_amandahosts_entry ${amanda_user} amdump
+check_amandahosts_perms
+create_ssh_key server
+create_ssh_key client
+create_profile
+check_profile
+install_client_conf
+create_ampassphrase
+
+logger "Amanda installation complete."
+cat $LOGFILE >> $INSTALL_LOG && {
+    rm $LOGFILE;
+    echo "Amanda installation log can be found in '${INSTALL_LOG}'.";
+} || \
+    echo "Amanda postinstall logs can be found in '$LOGFILE'."
 
-if [ -f "${TMPFILE}" ]; then
-        rm -f "${TMPFILE}" >>${TMPFILE} 2>&1
-fi
-
-echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'."
 %postun backup_server
-/sbin/ldconfig
-%pre backup_client
-TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX`
+##########################################
+LOGFILE=`mktemp /tmp/amanda_server-remove.log.XXXXXXXXXXX`
 if [ $? -ne 0 ]; then
-        echo "Unable to mktemp!" 1>&2
+        echo "Unable to create log file!"
         exit 1
 fi
-LOGDIR="%{LOGDIR}"
-INSTALL_LOG="${LOGDIR}/install.log"
-INSTALL_ERR="${LOGDIR}/install.err"
-
-echo "`date +'%b %e %Y %T'`: Preparing to install: %{amanda_version_info}" >${TMPFILE}
-
-# Check for the 'amanda' user
-echo "`date +'%b %e %Y %T'`: Checking for '%{amanda_user}' user..." >>${TMPFILE}
-if [ "`id -u %{amanda_user} > /dev/null 2>&1 && echo 0 || echo 1`" != "0" ] ; then
-        useradd -c "Amanda" -M -g %{amanda_group} -d %{AMANDAHOMEDIR} -s /bin/bash %{amanda_user} >>${TMPFILE} 2>&1
-        if [ %{dist} = "SuSE" ]; then
-                PASSWD_EXIT=$?
-        else
-                # Lock the amanda account until admin sets password
-                passwd -l %{amanda_user} >>/dev/null
-                PASSWD_EXIT=$?
-        fi
-        if [ ${PASSWD_EXIT} -eq 0 ] ; then
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  The '%{amanda_user}; user account has been successfully created." >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  Furthermore, the account has been automatically locked for you" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  for security purposes.  Once a password for the  '%{amanda_user}'" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  account has been set, the user can be unlocked by issuing" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  the following command as root.:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  # passwd -u %{amanda_user}" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  If this is not a new installation of Amanda and you have" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  pre-existing Amanda configurations in %{SYSCONFDIR}/amanda" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  you should ensure that 'dumpuser' is set to '%{amanda_user}'" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  in those configurations.  Additionally, you should ensure" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  that %{AMANDAHOMEDIR}/.amandahosts on your client systems" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  is properly configured to allow connections for the user" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  '%{amanda_user}'." >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-                PASSWD_OK=0
-        else
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  The '%{amanda_user}' user account for this system has been   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  created, however the user has no password set. For   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  security purposes this account  is normally locked   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  after creation.  Unfortunately,  when locking this   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  account an error occurred.  To ensure the security   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  of your system  you should set a password  for the   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  user account '%{amanda_user}' immediately!  To set  such a   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!  password, please issue the following command.:       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!   # passwd %{amanda_user}                                     !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!!                                                       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                PASSWD_OK=1
-        fi
-else
-        # log information about 'amanda' user parameters
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  The Amanda backup software is configured to operate as the" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  user '%{amanda_user}'.  This user exists on your system and has not" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  been modified.  To ensure that Amanda functions properly," >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  please see that the following parameters are set for that" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  user.:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  SHELL:          /bin/bash" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  HOME:           %{AMANDAHOMEDIR}" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  Default group:  %{amanda_group}" >>${TMPFILE}
-        echo "`date +'%b %e %Y %T'`:  Verifying %{amanda_user} parameters :" >>${TMPFILE}
-
-        if [ "`id -gn %{amanda_user}`" != "disk" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user 'amandabackup' is not part of the disk group,Pl  !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! make sure it is corrected before start using Amanda   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified group name of user 'amandabackup'" >>${TMPFILE}
-        fi
+%{script_vars}
 
-        if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f7`" != "/bin/bash" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user 'amandabackup' default shell should be set to    !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! /bin/bash, pl correct before start using Amanda         !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified Default shell for user 'amandabackup'" >>${TMPFILE}
-        fi
+# ---------- Common functions ------------
+%%COMMON_FUNCTIONS%%
+%%POST_RM_FUNCTIONS%%
 
-        if [ "`grep ^%{amanda_user} /etc/passwd|cut -d: -f6`" != "%{AMANDAHOMEDIR}" ] ; then
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! user 'amandabackup' home directory should be set to   !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! %{AMANDAHOMEDIR} Pl correct before using Amanda       !!!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  !!! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! !!!" >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`:  Verified Default home directory for user amandabackup" >>${TMPFILE}
-        fi
-        echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-        PASSWD_OK=0
-fi
-if [ -d %{AMANDAHOMEDIR} ] ; then
-        echo -n "`date +'%b %e %Y %T'`:  Checking ownership of '%{AMANDAHOMEDIR}'... " >>${TMPFILE}
-        if [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[3]}'`" = "%{amanda_user}" ] && \
-           [ "`ls -dl %{AMANDAHOMEDIR} | awk '//{split($_,x); print x[4]}'`" = "%{amanda_group}" ] ; then
-                echo "correct." >>${TMPFILE}
-                VARLIB_OK=0
-        else
-                echo "incorrect!" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  Please ensure that the directory '%{AMANDAHOMEDIR}' is owned by" >>${TMPFILE}
-                echo "`date +'%b %e %Y %T'`:  the user '%{amanda_user}' and group '%{amanda_group}'." >>${TMPFILE}
-                VARLIB_OK=1
-        fi
+# -------- End Common functions ----------
+/sbin/ldconfig
+# Check for parameter to script (are we upgrading?)
+if [ $1 -gt 0 ]; then
+    # We're upgrading
+    action="upgrade"
 else
-        VARLIB_OK=0
-fi
-echo "`date +'%b %e %Y %T'`:" >>${TMPFILE}
-
-if [ ! -e ${LOGDIR} ] ; then
-        # create log directory
-        mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1
-        chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1
-elif [ ! -d ${LOGDIR} ] ; then
-        mv ${LOGDIR} ${LOGDIR}.rpmsave >>${TMPFILE} 2>&1
-        mkdir -m 0750 ${LOGDIR} >>${TMPFILE} 2>&1
-        chown %{amanda_user}:%{amanda_group} ${LOGDIR} >>${TMPFILE} 2>&1
-        mv ${LOGDIR}.rpmsave ${LOGDIR}/ >>${TMPFILE} 2>&1
-fi
-if [ ${PASSWD_OK} -eq 1 ] || [ ${VARLIB_OK} -eq 1 ] ; then
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-        echo "Please review '${INSTALL_ERR}' to correct errors which have prevented the Amanda installaton." >&2
-        echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'."
+    # We're uninstalling
+    action="uninstall"
+fi
+
+# See http://fedoraproject.org/wiki/Packaging/ScriptletSnippets for the reason
+# we only remove xinetd on uninstall.
+if [ "$action" = "uninstall" ]; then
+    # Check for and remove existing xinetd configs
+    check_xinetd "amandaserver"
+    if [ $? -eq 0 ] ; then
+       rm_xinetd "amandaserver"
+       reload_xinetd
+    fi
+    check_inetd "amandaserver"
+    if [ $? -eq 0 ] ; then
+       rm_inetd "amandaserver"
+       reload_inetd
+    fi
+    if [ -d ${SYSCONFDIR}/amanda ]; then
+        logger "Removing ${SYSCONFDIR}/amanda if empty..."
+        rmdir ${SYSCONFDIR}/amanda 2> /dev/null || true
+    fi
+    if [ -d ${AMANDAHOMEDIR} ]; then
+        logger "Removing ${AMANDAHOMEDIR}..."
+        rm -rf ${AMANDAHOMEDIR}
+    fi
+    if [ -f ${SYSCONFDIR}/amandates ]; then
+        logger "Removing ${SYSCONFDIR}/amandates..."
+        rm -rf ${SYSCONFDIR}/amandates
+    fi
+    # Remove ${amanda_user} from sensitive groups.
+    if which deluser >/dev/null 2>&1 ; then
+        for group in tape; do
+            # only call deluser when amandabackup is in $group
+            if getent group "$group" |
+                awk -F: '{ print $4 }' |
+                awk -F, '{ for (i=1; i <= NF; i++ ) print $i }' |
+                grep "^${amanda_user}$" > /dev/null; then
+                    deluser ${amanda_user} $group || true
+            fi
+        done
+    fi
+
+fi
+
+echo "Amanda removal log can be found in '$LOGFILE'."
+
+%pre backup_client
+##########################################
+LOGFILE=`mktemp /tmp/amanda_client-preinst.log.XXXXXXXXXXX`
+if [ $? -ne 0 ]; then
+        echo "Unable to create log file!"
         exit 1
-else
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
 fi
+%{script_vars}
 
-echo "`date +'%b %e %Y %T'`: === Amanda backup client installation started. ===" >${TMPFILE}
+# ---------- Common functions ------------
+%%COMMON_FUNCTIONS%%
+%%PRE_INST_FUNCTIONS%%
 
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
+# -------- End Common functions ----------
+logger "Preparing to install: %{amanda_version_info}" 
+create_user
+check_user_group "${amanda_group}" || add_group "${amanda_group}"
+check_user_shell "${wanted_shell}"
+check_user_homedir "${AMANDAHOMEDIR}"
+check_homedir || create_homedir
+create_logdir
 
-if [ -f "${TMPFILE}" ]; then
-        rm -f "${TMPFILE}"
-fi
+logger "Preinstall done."
+cat $LOGFILE >> $INSTALL_LOG && rm $LOGFILE || \
+    echo "Amanda preinstall logs can be found in '$LOGFILE'."
 
 %post backup_client
-TMPFILE=`mktemp /tmp/rpm-amanda.XXXXXXXXXXX`
+##########################################
+LOGFILE=`mktemp /tmp/amanda_client-postinst.log.XXXXXXXXXXX`
 if [ $? -ne 0 ]; then
-        echo "Unable to mktemp!" 1>&2
+        echo "Unable to create log file!"
         exit 1
 fi
-LOGDIR="%{LOGDIR}"
-INSTALL_LOG="${LOGDIR}/install.log"
-INSTALL_ERR="${LOGDIR}/install.err"
+%{script_vars}
+AMANDATES=%{AMANDATES}
 
-echo -n "`date +'%b %e %Y %T'`: Updating system library cache..." >${TMPFILE}
-/sbin/ldconfig
-echo "done." >>${TMPFILE}
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-if [ -e /etc/xinetd.d ] && [ -d /etc/xinetd.d ] ; then
-        if [ ! -f /etc/xinetd.d/amandaclient ] ; then
-                cp %{AMANDAHOMEDIR}/example/xinetd.amandaclient /etc/xinetd.d/amandaclient
-
-                echo -n "`date +'%b %e %Y %T'`: Reloading xinetd configuration..." >${TMPFILE}
-                if [ "%{xinetd_reload}" == "reload" ] ; then
-                        /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1
-                        ret_val=$?
-                        if [ ${ret_val} -ne 0 ] ; then
-                                echo -n "reload failed.  Attempting restart..." >>${TMPFILE}
-                                /etc/init.d/xinetd restart >>${TMPFILE} 2>&1
-                                ret_val=$?
-                        fi
-                else
-                        /etc/init.d/xinetd %{xinetd_reload} >>${TMPFILE} 2>&1
-                        ret_val=$?
-                fi
-                if [ ${ret_val} -eq 0 ] ; then
-                        echo "success." >>${TMPFILE}
-                        cat ${TMPFILE}
-                        cat ${TMPFILE} >>${INSTALL_LOG}
-                else
-                        echo "failed.  Please check your system logs." >>${TMPFILE}
-                        cat ${TMPFILE}
-                        cat ${TMPFILE} >>${INSTALL_LOG}
-                fi
-        fi
-fi
-
-echo "`date +'%b %e %Y %T'`: Installing '%{AMANDATES}'." >${TMPFILE}
-ret_val=0
-if [ ! -f %{AMANDATES} ] ; then
-        touch %{AMANDATES} >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                echo "`date +'%b %e %Y %T'`: The file '%{AMANDATES}' has been created." >>${TMPFILE}
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDATES}'." >>${TMPFILE}
-        chown %{amanda_user}:%{amanda_group} %{AMANDATES} >>${TMPFILE} 2>&1
-        chmod 0640 %{AMANDATES} >>${TMPFILE} 2>&1
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation successful." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-else
-        echo "`date +'%b %e %Y %T'`: '%{AMANDATES}' Installation failed." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-fi
+# ---------- Common functions ------------
+%%COMMON_FUNCTIONS%%
+%%POST_INST_FUNCTIONS%%
 
-# Install .amandahosts to client
-echo "`date +'%b %e %Y %T'`: Checking '%{AMANDAHOMEDIR}/.amandahosts' file." >${TMPFILE}
-if [ ! -f %{AMANDAHOMEDIR}/.amandahosts ] ; then
-        touch %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-fi
-for host in localhost localhost.localdomain ; do
-                if [ -z "`grep \"^${host}[[:blank:]]\+\" %{AMANDAHOMEDIR}/.amandahosts | grep \"[[:blank:]]\+%{amanda_user}[[:blank:]]\+amdump\"`" ] ; then
-                        echo "${host}   %{amanda_user} amdump" >>%{AMANDAHOMEDIR}/.amandahosts
-                fi
-done
-chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-chmod 0600 %{AMANDAHOMEDIR}/.amandahosts >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# Install amanda client configuration file
-echo "`date +'%b %e %Y %T'`: Checking '%{SYSCONFDIR}/amanda/amanda-client.conf' file." >${TMPFILE}
-if [ ! -f %{SYSCONFDIR}/amanda/amanda-client.conf ] ; then
-        cp %{AMANDAHOMEDIR}/example/amanda-client.conf %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1
-fi
-chown %{amanda_user}:%{amanda_group} %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1
-chmod 0600 %{SYSCONFDIR}/amanda/amanda-client.conf >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# Install .gnupg directory
-echo "`date +'%b %e %Y %T'`: Installing '%{AMANDAHOMEDIR}/.gnupg'." >${TMPFILE}
-ret_val=0
-if [ ! -d %{AMANDAHOMEDIR}/.gnupg ] ; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' will be created." >>${TMPFILE}
-        mkdir %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' created successfully." >>${TMPFILE}
-        else
-                echo "`date +'%b %e %Y %T'`: The directory '%{AMANDAHOMEDIR}/.gnupg' creation failed." >>${TMPFILE}
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: Ensuring correct permissions for '%{AMANDAHOMEDIR}/.gnupg'." >>${TMPFILE}
-        chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-        ret_val=$?
-        if [ ${ret_val} -eq 0 ]; then
-                chmod 700 %{AMANDAHOMEDIR}/.gnupg >>${TMPFILE} 2>&1
-                ret_val=$?
-        fi
-fi
-if [ ${ret_val} -eq 0 ]; then
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation successful." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-else
-        echo "`date +'%b %e %Y %T'`: '%{AMANDAHOMEDIR}/.gnupg' Installation failed." >>${TMPFILE}
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_ERR}
-fi
+# -------- End Common functions ----------
+/sbin/ldconfig
 
-# SSH RSA key generation on client for amrecover
-KEYDIR="%{AMANDAHOMEDIR}/.ssh"
-KEYFILE="id_rsa_amrecover"
-COMMENT="root@client"
-if [ ! -d ${KEYDIR} ] ; then
-        if [ -f ${KEYDIR} ] ; then
-                echo "`date +'%b %e %Y %T'`: Directory '${KEYDIR}' exists as a file.  Renaming to '${KEYDIR}.rpmsave'." >${TMPFILE}
-                mv ${KEYDIR} ${KEYDIR}.rpmsave >>${TMPFILE} 2>&1
-                cat ${TMPFILE}
-                cat ${TMPFILE} >>${INSTALL_LOG}
-        fi
-        echo "`date +'%b %e %Y %T'`: Creating directory '${KEYDIR}'." >${TMPFILE}
-        mkdir ${KEYDIR} >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-if [ ! -f ${KEYDIR}/${KEYFILE} ] ; then
-        echo "`date +'%b %e %Y %T'`: Creating ssh RSA key in '${KEYDIR}/${KEYFILE}'" >${TMPFILE}
-        ssh-keygen -q -C $COMMENT -t rsa -f ${KEYDIR}/${KEYFILE} -N '' >>${TMPFILE} 2>&1
-        cat ${TMPFILE}
-        cat ${TMPFILE} >>${INSTALL_LOG}
-fi
-echo "`date +'%b %e %Y %T'`: Setting permissions for '${KEYDIR}' and '${KEYDIR}/${KEYFILE}*'" >${TMPFILE}
-chown %{amanda_user}:%{amanda_group} ${KEYDIR} >>${TMPFILE} 2>&1
-chmod 0750 ${KEYDIR} >>${TMPFILE} 2>&1
-chmod 0600 ${KEYDIR}/${KEYFILE}* >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-# environment variables (~amandabackup/.profile)
-echo "`date +'%b %e %Y %T'`: Checking for '%{AMANDAHOMEDIR}/.profile' and ensuring correct environment." >${TMPFILE}
-if [ ! -f %{AMANDAHOMEDIR}/.profile ] ; then
-        touch %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-fi
-if [ -z "`grep PATH %{AMANDAHOMEDIR}/.profile | grep '%{SBINDIR}'`" ] ; then
-        echo "export PATH=\"\$PATH:%{SBINDIR}\"" >>%{AMANDAHOMEDIR}/.profile 2>>${TMPFILE}
-fi
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-echo "`date +'%b %e %Y %T'`: Setting ownership and permissions for '%{AMANDAHOMEDIR}/.profile'" >${TMPFILE}
-chown %{amanda_user}:%{amanda_group} %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-chmod 0640 %{AMANDAHOMEDIR}/.profile >>${TMPFILE} 2>&1
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
+check_xinetd "amandaclient"
+case $? in
+       0) backup_xinetd "amandaclient"
+          install_xinetd "amandaclient"
+       ;;
+       1) install_xinetd "amandaclient" ;;
+       2) logger "Xinetd config not installed: either xinetd config is not present or xinetd.d is a file." ;;
+       *) logger "bad return from check_xinetd"; exit 1 ;;
+esac
+
+# Amanda clients should not have the server xinetd installed.
+check_xinetd "amandaserver"
+case $? in
+       0) backup_xinetd "amandaserver" ;;
+esac
+
+reload_xinetd
+create_amandates
+check_amandates
+create_gnupg
+check_gnupg
+create_amandahosts
+check_amandahosts_entry ${amanda_user} amdump
+check_amandahosts_perms
+create_ssh_key server
+create_ssh_key client
+create_profile
+check_profile
+install_client_conf
+
+logger "Amanda installation complete."
+cat $LOGFILE >> $INSTALL_LOG && {
+    rm $LOGFILE;
+    echo "Amanda installation log can be found in '${INSTALL_LOG}'.";
+} || \
+    echo "Amanda postinstall logs can be found in '$LOGFILE'."
 
 echo "`date +'%b %e %Y %T'`: Sending anonymous distribution and version information to Zmanda" >> ${INSTALL_LOG}
 if [ -x /usr/bin/wget ]; then 
         /usr/bin/wget -q -o /dev/null -O - --timeout=5 http://www.zmanda.com/amanda-tips.php\?version=%{amanda_version}\&os=%{disttag}%{distver}\&type=client 
 fi
 
-echo "`date +'%b %e %Y %T'`: === Amanda backup client installation complete. ===" >>${TMPFILE}
-cat ${TMPFILE}
-cat ${TMPFILE} >>${INSTALL_LOG}
-
-if [ -f "${TMPFILE}" ]; then
-        rm -f "${TMPFILE}"
+%postun backup_client
+##########################################
+LOGFILE=`mktemp /tmp/amanda_client-remove.log.XXXXXXXXXXX`
+if [ $? -ne 0 ]; then
+        echo "Unable to create log file!"
+        exit 1
 fi
+%{script_vars}
 
-echo "Amanda installation log can be found in '${INSTALL_LOG}' and errors (if any) in '${INSTALL_ERR}'."
-%postun backup_client
+# ---------- Common functions ------------
+%%COMMON_FUNCTIONS%%
+%%POST_RM_FUNCTIONS%%
+
+# -------- End Common functions ----------
 /sbin/ldconfig
 
+# Check for parameter to script (are we upgrading?)
+if [ $1 -gt 0 ]; then
+    # We're upgrading
+    action="upgrade"
+else
+    # We're uninstalling
+    action="uninstall"
+fi
+
+# See http://fedoraproject.org/wiki/Packaging/ScriptletSnippets for the reason
+# we only remove xinetd on uninstall.
+if [ "$action" = "uninstall" ]; then
+    # Check for and remove existing xinetd configs
+    check_xinetd "amandaclient"
+    if [ $? -eq 0 ] ; then
+       rm_xinetd "amandaclient"
+       reload_xinetd
+    fi
+    check_inetd "amandaclient"
+    if [ $? -eq 0 ] ; then
+       rm_inetd "amandaclient"
+       reload_inetd
+    fi
+    if [ -d ${SYSCONFDIR}/amanda ]; then
+        logger "Removing ${SYSCONFDIR}/amanda if empty..."
+        rmdir ${SYSCONFDIR}/amanda 2> /dev/null || true
+    fi
+    if [ -d ${AMANDAHOMEDIR} ]; then
+        logger "Removing ${AMANDAHOMEDIR}..."
+        rm -rf ${AMANDAHOMEDIR}
+    fi
+    if [ -f ${SYSCONFDIR}/amandates ]; then
+        logger "Removing ${SYSCONFDIR}/amandates..."
+        rm -rf ${SYSCONFDIR}/amandates
+    fi
+    # Remove ${amanda_user} from sensitive groups.
+    if which deluser >/dev/null 2>&1 ; then
+        for group in tape; do
+            # only call deluser when amandabackup is in $group
+            if getent group "$group" |
+                awk -F: '{ print $4 }' |
+                awk -F, '{ for (i=1; i <= NF; i++ ) print $i }' |
+                grep "^${amanda_user}$" > /dev/null; then
+                    deluser ${amanda_user} $group || true
+            fi
+        done
+    fi
+fi
+
+echo "Amanda removal log can be found in '$LOGFILE'."
+
+%files backup_client
 # --- Files to install ---
 # Notes:  Do not use wildcards on directories not wholly owned by amanda.  An
 # uninstall of the software will attempt to delete whatever matches here.
-%files backup_client
 %defattr(0755,%{amanda_user},%{amanda_group},0755)
 %{AMLIBEXECDIR}
 %{AMLIBDIR}
index ef6974cb85a295c37432dfdd13244358f6adf9a1..eaaa0d543f868dc6de619dc5f1dceaeacd8f4453 100755 (executable)
@@ -30,9 +30,12 @@ fi
 # Until we get package revisioning in community.
 [ -f "PKG_REV" ] || echo "1" > PKG_REV
 
+[ -f "./configure" ] || \
+    { echo "./configure does not exist, please run ./autogen"; exit 1; }
+
 # Substitute amanda.spec.src
 /usr/bin/perl packaging/common/substitute.pl \
-    packaging/rpm/amanda.spec.src packaging/rpm/amanda.spec
+    packaging/rpm/amanda.spec.src packaging/rpm/amanda.spec || exit 1
 
 PKG_TARBALL=${AMVER}.tar.gz
 if [ ! -f "${PKG_TARBALL}" ]; then
index af5d0a3b886cc986e123698a8847f6761a51e067..32ad7b28d1dc5629786041da4b682b4fd2dcd4f8 100755 (executable)
@@ -2,6 +2,12 @@
 # This is useful for debugging
 #set -x
 
+if [ "$1" = "-v" ]; then
+    silent_make_flags=""
+    shift
+else
+    silent_make_flags="-s LIBTOOLFLAGS=--silent"
+fi
 #### CHECKS
 if [ ! -f common-src/amanda.h ]; then
     echo "Error: 'buildpkg' must be run from the root of an otherwise unused amanda source"
@@ -52,7 +58,7 @@ do_build() {
        { echo "client or server not given" && exit 1; }
     rm -rf ${INSTALL_DEST} ${PKG_DEST}
     mkdir ${INSTALL_DEST} ${PKG_DEST} || exit 1
-    make distclean
+    make ${silent_make_flags} distclean
     echo "Running configure.."
     CONF="$CONF \
        STAR=/opt/csw/bin/star \
@@ -99,7 +105,7 @@ do_build() {
         GLIB_MKENUMS=glib-mkenums \
        ${CONF} || exit 1
 
-    echo "Building.."
+    echo "Building $1.."
 
     # rpcgen should be run natively on solaris, linux generated XDR stubs
     # are not compatible. Specially when being compiled in 64 bit mode.
@@ -107,8 +113,8 @@ do_build() {
 
     (cd ndmp-src;rpcgen ndmp0.x;rpcgen ndmp2.x;rpcgen ndmp3.x;rpcgen ndmp4.x; rpcgen ndmp9.x)
 
-    make || exit 1
-    make DESTDIR=${INSTALL_DEST} install || exit 1
+    make ${silent_make_flags}|| exit 1
+    make ${silent_make_flags} DESTDIR=${INSTALL_DEST} install || exit 1
 
     # the gnulib makefiles create $amlibdir/charset.alias in hopes of "merging"
     # it with a similar file from other applications.  This doesn't work with
@@ -136,7 +142,7 @@ do_package() {
     cp ${src_dir}/${pkg_root}/${subpkg}/* ${PKG_DEST} || exit 1
     cd ${INSTALL_DEST} || exit 1
     
-    # amanda does not create /etc/amanda 
+    # amanda does not create /etc/amanda
     mkdir -p ${AMSTATEDIR} || exit 1
     mkdir -p ${ETCDIR}/amanda || exit 1
 
@@ -147,7 +153,7 @@ do_package() {
     # permissions and ownership per pkg settings if included.
     cat "${PKG_DEST}/pkgproto" \
        >> ${PKG_DEST}/prototype || exit 1
-    pkgproto $PREFIX >> ${PKG_DEST}/prototype || exit 1
+    pkgproto $PREFIX ${AMSTATEDIR} ${ETCDIR}/amanda >> ${PKG_DEST}/prototype || exit 1
 
     # Using --disable-installperms creates installperms.sh, which this bit of
     # perl will merge into the prototype.  Note that this perl script is
@@ -210,12 +216,11 @@ PKG_DEST=${PKG_TMP}/pkg; export PKG_DEST
 
 # Explanation of solaris paths:
 # /opt/SUNWspro/*: Sun compiler, NOT USED FOR PACKAGING.
-# /opt/csw/*: blastwave.
+# /opt/csw/*: OpenCSW.
 # /usr/ccs/*: sun compilation tools (ld, lex, yacc)
 # /usr/sfw/*: SunFreeware, sometimes. (solaris 10)
 # /usr/local/*: SunFreeware, othertimes. (solaris 8)
 
-# Not Absolute!  Remember to prefix a "/" except in pkgproto.
 # sparc or intel
 arch=`uname -p`
 # 5.8 or 5.10
@@ -228,14 +233,15 @@ PATH=/opt/csw/bin:/usr/bin:/usr/sbin:/usr/ccs/bin;export PATH
 # Compile 32bit because csw perl is 32bit and native is too old.
 CFLAGS="-O2 -pipe -m32"; export CFLAGS
 CPPFLAGS="-I/opt/csw/include"; export CPPFLAGS
-PREFIX=opt/amanda; export PREFIX # Not absolute.  Pkgprot needs this.
+# Not Absolute!  Remember to prefix a "/" except in pkgproto.
+PREFIX=opt/amanda; export PREFIX # Not absolute.
 amlibdir=${PREFIX}/lib     # Not absolute
 LOCALSTATEDIR=var; export LOCALSTATEDIR
 AMSTATEDIR=${LOCALSTATEDIR}/lib/amanda; export AMSTATEDIR
 ETCDIR=etc; export ETCDIR
 DBGDIR=${LOCALSTATEDIR}/log; export DBGDIR
 # Each client and server and platform combination gets different compile options
-if [ "x${1}" = "xclient" -o "x${1}" = "x" ]; then
+if [ "x${1}" = "xclient" ] || [ "x${1}" = "x" ]; then
     CC=/usr/sfw/bin/gcc
     # Variables with spaces must be entered on the configure line separate from
     # CONF to maintain quoting.
@@ -250,6 +256,7 @@ if [ "x${1}" = "xclient" -o "x${1}" = "x" ]; then
         GLIB_LIBS="-lglib-2.0 -lgobject-2.0 -lgthread-2.0"; export GLIB_LIBS
     elif [ "x$arch" = "xi386" -a "x$os_rel" = "x5.10" ]; then
         GLIB_CFLAGS="-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include"; export GLIB_CFLAGS
+        GLIB_LIBS="-lglib-2.0 -lgobject-2.0 -lgthread-2.0"; export GLIB_LIBS
     elif [ "x$arch" = "xsparc" -a "x$os_rel" = "x5.8" ]; then
         # CSW glib2.0 flags for gcc.  CSW compiles with Sunstudio, so some
         # flags may not work
@@ -267,7 +274,7 @@ if [ "x${1}" = "xclient" -o "x${1}" = "x" ]; then
     do_package "client"
 fi
 
-if [ "x${1}" = "xserver"  -o "x${1}" = "x" ]; then
+if [ "x${1}" = "xserver" ] || [ "x${1}" = "x" ]; then
     LDFLAGS="-L/usr/lib -R/usr/lib \
         -L/opt/csw/lib -R/opt/csw/lib \
         -L/usr/sfw/lib \
@@ -294,6 +301,7 @@ if [ "x${1}" = "xserver"  -o "x${1}" = "x" ]; then
     fi
     CONF="--with-amlibdir=/${amlibdir} \
        --enable-s3-device \
+        --with-libcurl=/opt/csw \
        CC=/usr/sfw/bin/gcc \
        PERL=/opt/csw/bin/perl \
        MTX=/opt/csw/sbin/mtx" ; export CONF
index 5cb9cc94566ba595882fe4aa6d0e695a10399d88..e6ef6eb9eac91e3908cdf6dae4f792a8b6eb6459 100755 (executable)
@@ -1,19 +1,22 @@
 #!/bin/sh
 
-LOGFILE=`mktemp /tmp/deb-log-amanda_enterprise-client.XXXXXXXXXXX`
+LOGFILE=`mktemp /tmp/amanda-client-postinstall.log.XXXXXXXXXXX`
 if [ $? -ne 0 ]; then
     echo "Unable to mktemp!" 1>&2
     exit 1
 fi
 amanda_user=amandabackup; export amanda_user
 amanda_group=disk; export amanda_group
-AMANDAHOMEDIR="${BASEDIR}/%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR
+# BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime.
+# Unfortunately, it messes things up to have basedir="/".
+[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR}
+AMANDAHOMEDIR="${basedir}%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR
 os=SunOS; export os
 arch=%%ARCH%%; export arch
-LOGDIR="${BASEDIR}/%%LOGDIR%%"; export LOGDIR
+LOGDIR="${basedir}%%LOGDIR%%"; export LOGDIR
 INSTALL_LOG="${LOGDIR}/install.log"; export INSTALL_LOG
-SYSCONFDIR="${BASEDIR}/etc"; export SYSCONFDIR
-SBINDIR="${BASEDIR}/usr/sbin"; export SBINDIR
+SYSCONFDIR="${basedir}/etc"; export SYSCONFDIR
+SBINDIR="${basedir}/usr/sbin"; export SBINDIR
 AMTMP="/tmp/amanda"
 
 AMANDATES=${SYSCONFDIR}/amandates; export AMANDATES
@@ -46,7 +49,8 @@ if [ "$rel" = "5.8" ]; then
 else
     # Solaris 10+ uses smf, but we can't differentiate server from client, all
     # entries end up named "amanda"
-    case check_smf "amanda"
+    check_smf "amanda"
+    case $? in
       0) backup_smf || logger "Warning: Backup of existing service failed. continuing..."
          install_smf "amandaclient" || \
             logger "Warning: Amanda service not installed."
index 287d9398293c0c4a0cd53ed759666f9dc97ab44f..c4479ec5c79d893fa01c2db1e001c818f2dd6812 100755 (executable)
@@ -7,13 +7,15 @@ if [ $? -ne 0 ]; then
 fi
 amanda_user=amandabackup
 amanda_group=disk
-AMANDAHOMEDIR=%%AMANDAHOMEDIR%%
+# BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime.
+# Unfortunately, it messes things up to have basedir="/".
+[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR}
+AMANDAHOMEDIR=${basedir}%%AMANDAHOMEDIR%%
 os=SunOS
 dist=%%DISTRO%%
 
-LOGDIR=%%LOGDIR%%
-REMOVE_LOG="/tmp/amanda-remove.log"
-SYSCONFDIR=/etc
+LOGDIR=${basedir}%%LOGDIR%%
+SYSCONFDIR=${basedir}/etc
 
 # ---------- Common functions ------------
 # see packaging/common/ in the source tree
@@ -28,7 +30,7 @@ case $rel in
     5.8|5.9)
        if check_inetd "amanda"; then
            rm_inetd "amanda" || { \
-            logger "Warning: Did not successfully remove $net_svc_name from SMF.";
+            logger "Warning: Did not successfully remove amanda from SMF.";
                 exit 1; }
            reload_inetd
         fi
@@ -36,13 +38,10 @@ case $rel in
     5.10)
         if check_smf "amanda"; then
             rm_smf "amanda" || { \
-                logger "Warning: Did not successfully remove $net_svc_name from SMF.";
+                logger "Warning: Did not successfully remove amanda from SMF.";
                 exit 1; }
         fi
     ;;
 esac
 
 logger "Amanda Client removed."
-
-cat $LOGFILE >> $REMOVE_LOG
-rm $LOGFILE
index 28228b0d0cb63cf203943e39d28be5ba7ed33b62..035cb9f4ae801dd7c593ae6ced326544e4995493 100755 (executable)
@@ -11,11 +11,14 @@ export LOGFILE
 amanda_user=amandabackup; export amanda_user
 amanda_group=disk; export amanda_group
 # BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime.
-AMANDAHOMEDIR="${BASEDIR}/%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR
+# Unfortunately, it messes things up to have basedir="/".
+[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR}
+AMANDAHOMEDIR="${basedir}%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR
 os=`uname`; export os
-dist=%%DISTRO%%; export dist
-LOGDIR="/var/log/amanda"; export LOGDIR
-SYSCONFDIR=/etc; export SYSCONFDIR
+wanted_shell=/usr/bin/bash; export wanted_shell
+LOGDIR="${basedir}%%LOGDIR%%"; export LOGDIR
+INSTALL_LOG=${LOGDIR}/install.log; export INSTALL_LOG
+SYSCONFDIR="${basedir}/etc"; export SYSCONFDIR
 
 # See packaging/common/ for shell function libraries.
 # ---------- Common functions ------------
@@ -25,17 +28,13 @@ SYSCONFDIR=/etc; export SYSCONFDIR
 # -------- End Common functions ----------
 logger "Preparing to install: Amanda Client %%VERSION%%"
 create_user
-if ! check_user "group" "${amanda_group}" ; then
-    add_group "${amanda_group}"
-fi
-if ! check_user "group" "tape" ; then
-    add_group "tape"
-fi
-check_user "shell" "/usr/bin/bash"
-check_user "homedir" "${AMANDAHOMEDIR}"
-if ! check_homedir ; then
-    create_homedir
-fi
+check_user_group "${amanda_group}" || add_group "${amanda_group}"
+check_user_shell "${wanted_shell}"
+check_user_homedir "${AMANDAHOMEDIR}"
+check_homedir || create_homedir
 create_logdir
 
 logger "Preinstall done."
+
+cat $LOGFILE > $INSTALL_LOG && rm $LOGFILE || \
+    echo "Amanda preinstall logs can be found in '$LOGFILE'."
index c4ab56ea825a4905ccbc2a245b35f67afebd094e..5860799b9be444abd0bea343d4fe95142ca78e58 100755 (executable)
@@ -1,25 +1,26 @@
 #!/bin/sh
 
-LOGFILE=`mktemp /tmp/deb-log-amanda_enterprise-client.XXXXXXXXXXX`
+LOGFILE=`mktemp /tmp/amanda-server-postinstall.log.XXXXXXXXXXX`
 if [ $? -ne 0 ]; then
     echo "Unable to mktemp!" 1>&2
     exit 1
 fi
 amanda_user=amandabackup; export amanda_user
 amanda_group=disk; export amanda_group
-AMANDAHOMEDIR="${BASEDIR}/%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR
+# BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime.
+# Unfortunately, it messes things up to have basedir="/".
+[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR}
+AMANDAHOMEDIR="${basedir}%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR
 os=SunOS; export os
 arch=%%ARCH%%; export arch
-LOGDIR="${BASEDIR}/%%LOGDIR%%"; export LOGDIR
+LOGDIR="${basedir}%%LOGDIR%%"; export LOGDIR
 INSTALL_LOG="${LOGDIR}/install.log"; export INSTALL_LOG
-SYSCONFDIR="${BASEDIR}/etc"; export SYSCONFDIR
-SBINDIR="${BASEDIR}/usr/sbin"; export SBINDIR
+SYSCONFDIR="${basedir}/etc"; export SYSCONFDIR
+SBINDIR="${basedir}/usr/sbin"; export SBINDIR
 AMTMP="/tmp/amanda"
 
 AMANDATES=${SYSCONFDIR}/amandates; export AMANDATES
 
-exit_msg="Amanda installation log can be found in '${INSTALL_LOG}'."
-
 # ---------- Common functions ------------
 %%COMMON_FUNCTIONS%%
 %%POST_INST_FUNCTIONS%%
@@ -46,7 +47,8 @@ if [ "$rel" = "5.8" ]; then
 else
     # Solaris 10+ uses smf, but we can't differentiate server from client, all
     # entries end up named "amanda"
-    case check_smf "amanda"
+    check_smf "amanda"
+    case $? in
       0) backup_smf || logger "Warning: Backup of existing service failed. continuing..."
          install_smf "amandaserver" || \
             logger "Warning: Amanda service not installed."
@@ -69,7 +71,8 @@ install_client_conf
 create_amtmp
 
 logger "Amanda installation complete."
-cat $LOGFILE >> $INSTALL_LOG
-rm $LOGFILE
-
-echo "${exit_msg}"
+cat $LOGFILE >> $INSTALL_LOG && {
+    rm $LOGFILE
+    echo "Amanda installation log can be found in '${INSTALL_LOG}'."
+} || \
+    echo "Amanda postinstall log can be found in $LOGFILE"
index e0184ac2188379c40821af955e1d81e8fe4986dd..e307ee89c7ee7dc112e8a3e3f6adb16c23310db2 100755 (executable)
@@ -7,13 +7,15 @@ if [ $? -ne 0 ]; then
 fi
 amanda_user=amandabackup
 amanda_group=disk
-AMANDAHOMEDIR=%%AMANDAHOMEDIR%%
+# BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime.
+# Unfortunately, it messes things up to have basedir="/".
+[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR}
+AMANDAHOMEDIR=${basedir}%%AMANDAHOMEDIR%%
 os=SunOS
 dist=%%DISTRO%%
 
-LOGDIR=%%LOGDIR%%
-REMOVE_LOG="/tmp/amanda-remove.log"
-SYSCONFDIR=/etc
+LOGDIR=${basedir}%%LOGDIR%%
+SYSCONFDIR=${basedir}/etc
 
 # ---------- Common functions ------------
 # see packaging/common/ in the source tree
@@ -28,7 +30,7 @@ case $rel in
     5.8|5.9)
        if check_inetd "amanda"; then
            rm_inetd "amanda" || { \
-            logger "Warning: Did not successfully remove $net_svc_name from SMF.";
+            logger "Warning: Did not successfully remove amanda from SMF.";
                 exit 1; }
            reload_inetd
         fi
@@ -36,13 +38,10 @@ case $rel in
     5.10)
         if check_smf "amanda"; then
             rm_smf "amanda" || { \
-                logger "Warning: Did not successfully remove $net_svc_name from SMF.";
+                logger "Warning: Did not successfully remove amanda from SMF.";
                 exit 1; }
         fi
     ;;
 esac
 
 logger "Amanda Server removed."
-
-cat $LOGFILE >> $REMOVE_LOG
-rm $LOGFILE
index b986e4ef9e2f7fe3a0b60023a3ce8f7abe701ed6..4451b9dfe9a57d60b0c5d469ae7fd1d4fe4af2f3 100755 (executable)
@@ -11,11 +11,14 @@ export LOGFILE
 amanda_user=amandabackup; export amanda_user
 amanda_group=disk; export amanda_group
 # BASEDIR is set by either in pkginfo, or if not set, by pkgadd at installtime.
-AMANDAHOMEDIR="${BASEDIR}/%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR
+# Unfortunately, it messes things up to have basedir="/".
+[ "x${BASEDIR}" = "x/" ] && basedir="" || basedir=${BASEDIR}
+AMANDAHOMEDIR="${basedir}%%AMANDAHOMEDIR%%"; export AMANDAHOMEDIR
 os=`uname`; export os
-dist=%%DISTRO%%; export dist
-LOGDIR="${BASEDIR}/%%LOGDIR%%"; export LOGDIR
-SYSCONFDIR="${BASEDIR}/%%SYSCONFDIR%%"; export SYSCONFDIR
+wanted_shell=/usr/bin/bash; export wanted_shell
+LOGDIR="${basedir}%%LOGDIR%%"; export LOGDIR
+INSTALL_LOG=${LOGDIR}/install.log; export INSTALL_LOG
+SYSCONFDIR="${basedir}/etc"; export SYSCONFDIR
 
 # See packaging/common/ for shell function libraries.
 # ---------- Common functions ------------
@@ -25,17 +28,14 @@ SYSCONFDIR="${BASEDIR}/%%SYSCONFDIR%%"; export SYSCONFDIR
 # -------- End Common functions ----------
 logger "Preparing to install: Amanda Server %%VERSION%%"
 create_user
-if ! check_user "group" "${amanda_group}" ; then
-    add_group "${amanda_group}"
-fi
-if ! check_user "group" "tape" ; then
-    add_group "tape"
-fi
-check_user "shell" "/usr/bin/bash"
-check_user "homedir" "${AMANDAHOMEDIR}"
-if ! check_homedir ; then
-    create_homedir
-fi
+check_user_group "${amanda_group}" || add_group "${amanda_group}"
+check_user_supplemental_group "tape" || add_group "tape"
+check_user_shell "${wanted_shell}"
+check_user_homedir "${AMANDAHOMEDIR}"
+check_homedir || create_homedir
 create_logdir
 
 logger "Preinstall done."
+
+cat $LOGFILE > $INSTALL_LOG && rm $LOGFILE || \
+    echo "Amanda preinstall logs can be found in '$LOGFILE'."
index a0b22bed617cffef3c01f33e5ecc3d86b5cf78e6..e2dc296b3084f1f5533c38bb25c674a766b067d0 100644 (file)
@@ -114,6 +114,7 @@ require Amanda::Script_App;
 
 use strict;
 use warnings;
+use IO::Handle;
 use Amanda::Config qw( :init :getconf  config_dir_relative );
 
 
@@ -173,9 +174,10 @@ sub read_magic_block {
 sub _set_mesgout {
     my $self = shift;
 
-    my $mesgout_fd;
-    open ($mesgout_fd, '>&=3') || die("Can't open mesgout_fd: $!");
-    $self->{mesgout} = $mesgout_fd;
+    my $mesgout = IO::Handle->new();
+    $mesgout->fdopen(3,"a") || die("Can't open mesgout_fd: $!");
+    $mesgout->autoflush(1);
+    $self->{mesgout} = $mesgout;
 }
 
 1;
index 57c3045b4fc980b1925d2c3a6784ab4c429798f0..5af1d3c2dc3c72f68338710d40058ece47524055 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index c58cfd0f54a920549a175cd325091abcaa69d3e1..a73a77da0697a9a46a9b9e4830056774c8299e74 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -31,6 +31,7 @@ require Amanda::Script_App;
 
 use strict;
 use warnings;
+use IO::Handle;
 use Amanda::Config qw( :init :getconf  config_dir_relative );
 
 
@@ -90,9 +91,10 @@ sub read_magic_block {
 sub _set_mesgout {
     my $self = shift;
 
-    my $mesgout_fd;
-    open ($mesgout_fd, '>&=3') || die("Can't open mesgout_fd: $!");
-    $self->{mesgout} = $mesgout_fd;
+    my $mesgout = IO::Handle->new();
+    $mesgout->fdopen(3,"a") || die("Can't open mesgout_fd: $!");
+    $mesgout->autoflush(1);
+    $self->{mesgout} = $mesgout;
 }
 
 %}
index 6fd92b20d5c8f9c87a49787bbed866b9fd6a7a51..26bd6bf8d71b5d944bd52a17bc105fd6a8d59b69 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 728b1c8f20e23e65a76094f19c04220d519e0ba7..e7b2b26e6d024fc4fe45397dc3aa114f2b6d7bb8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index dc8057cdb4be0502267833516be4e04f63e22b58..a3fd2e0377dc02b4cffb505df137a7956bea44e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index ae4d77f80a8b662a31b3a70b8b4e5cb51b6beae9..18e6b881a5f1a493ea1dbdd35b9b8000454f21f2 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index ddb7f660a5ef559a2b459892587d57752cdfa508..419c1a0d510755522595522c3e48d288f68d3b1c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2007,2008,2009,2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -1253,15 +1253,19 @@ sub make_new_tape_label {
 
     my $tl = $self->{'tapelist'};
     die ("make_new_tape_label: no tapelist") if !$tl;
-    return undef if !defined $self->{'autolabel'}->{'template'};
-    return undef if !defined $self->{'labelstr'};
+    if (!defined $self->{'autolabel'}) {
+       return (undef, "autolabel not set");
+    }
+    if (!defined $self->{'autolabel'}->{'template'}) {
+       return (undef, "template is not set, you must set autolabel");
+    }
+    if (!defined $self->{'labelstr'}) {
+       return (undef, "labelstr not set");
+    }
     my $template = $self->{'autolabel'}->{'template'};
     my $labelstr = $self->{'labelstr'};
     my $slot_digit = 1;
 
-    if (!$template) {
-       return (undef, "template is not set, you must set autolabel");
-    }
     $template =~ s/\$\$/SUBSTITUTE_DOLLAR/g;
     $template =~ s/\$b/SUBSTITUTE_BARCODE/g;
     $template =~ s/\$m/SUBSTITUTE_META/g;
index a7c333d9bb98437024e4d6552fc6a011d274aae2..4f59be32df866c38be550cacd00f6d4cbe9264d2 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009,2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -20,6 +20,7 @@ package Amanda::Changer::aggregate;
 
 use strict;
 use warnings;
+use Carp;
 use vars qw( @ISA );
 @ISA = qw( Amanda::Changer );
 
@@ -655,7 +656,7 @@ sub _for_each_child {
        ($params{'oksub'}, $params{'errsub'}, $params{'parent_cb'}, $params{'args'});
 
     if (defined($args)) {
-       die "number of args did not match number of children"
+       confess "number of args did not match number of children"
            unless (@$args == $self->{'num_children'});
     } else {
        $args = [ ( undef ) x $self->{'num_children'} ];
index fccc22602bff588c2c8b8592ecd7d4bb193d9a74..4f57d5c9c227de367f768d60f3f27c9c8db1bcf0 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 8172791db08fbe14824dd13cd39c613c01151f36..8c18e65ce91d6a32e78c8153d274390c9c4c4397 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008,2009,2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -20,6 +20,7 @@ package Amanda::Changer::disk;
 
 use strict;
 use warnings;
+use Carp;
 use vars qw( @ISA );
 @ISA = qw( Amanda::Changer );
 
@@ -497,7 +498,7 @@ sub _get_slot_label {
 sub _load_drive {
     my ($self, $drive, $slot) = @_;
 
-    die "'$drive' does not exist" unless (-d $drive);
+    confess "'$drive' does not exist" unless (-d $drive);
     if (-e "$drive/data") {
        unlink("$drive/data");
     }
index 9324a54124fbf4eaade3855945a836c1eaaaa7c7..85de8fd3654b23baa95404d0c0afa65e950dd45b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008,2009,2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -410,7 +410,8 @@ sub inventory {
            my $s = { slot => $slot,
                      state => $state->{slots}->{$unaliased}->{state} || Amanda::Changer::SLOT_UNKNOWN,
                      reserved => $self->_is_slot_in_use($state, $slot) };
-           if (defined $state->{slots}->{$unaliased}) {
+           if (defined $state->{slots}->{$unaliased} and
+               exists $state->{slots}->{$unaliased}->{device_status}) {
                $s->{'device_status'} =
                              $state->{slots}->{$unaliased}->{device_status};
                if ($s->{'device_status'} != $DEVICE_STATUS_SUCCESS) {
index 016db8f8af08f8f4ee46819e7457480aca00d8b3..0314d326423698f7cfdd5b62f7f959fb657dbaeb 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009,2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This library is free software; you can redistribute it and/or modify it
 # under the terms of the GNU Lesser General Public License version 2.1 as
@@ -110,6 +110,7 @@ sub get_device {
 
 package Amanda::Changer::ndmp::Interface;
 
+use Carp;
 use Amanda::NDMP qw( :constants );
 use Amanda::Debug qw( debug warning );
 use Amanda::MainLoop;
@@ -422,9 +423,9 @@ sub _parse_read_element_status {
        my $all_descrips_len = ($all_descrips_len_msb << 16) + $all_descrips_len_lsw;
        my $have_pvoltag = $flags & 0x80;
        my $have_avoltag = $flags & 0x40;
-       die unless $all_descrips_len % $descrip_len == 0;
-       die unless $all_descrips_len >= $descrip_len;
-       die length($data) unless $all_descrips_len <= length($data);
+       confess unless $all_descrips_len % $descrip_len == 0;
+       confess unless $all_descrips_len >= $descrip_len;
+       confess (length($data)) unless $all_descrips_len <= length($data);
        $data = substr($data, 8);
 
        while ($all_descrips_len > 0) { # for each element status descriptor
index 86628b7bd09c67541e2a31969c7ef2a0fc689156..7fb2eaf6e4fab4219888ef40acf5780d7ff0a472 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 26486bc495ce99d5e9c0a92feccb55cf8e2b8e75..d387c841246d8c4e3a763c909594a21746a6d302 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009,2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -20,6 +20,7 @@ package Amanda::Changer::rait;
 
 use strict;
 use warnings;
+use Carp;
 use vars qw( @ISA );
 @ISA = qw( Amanda::Changer );
 
@@ -525,7 +526,7 @@ sub _for_each_child {
        ($params{'oksub'}, $params{'errsub'}, $params{'parent_cb'}, $params{'args'});
 
     if (defined($args)) {
-       die "number of args did not match number of children"
+       confess "number of args did not match number of children"
            unless (@$args == $self->{'num_children'});
     } else {
        $args = [ ( undef ) x $self->{'num_children'} ];
index d13e342fd76df26710591a383dd4feea89fc0670..dae6af016477daa0bf36643be5388c065a4d4eb4 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009,2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This library is free software; you can redistribute it and/or modify it
 # under the terms of the GNU Lesser General Public License version 2.1 as
@@ -471,7 +471,7 @@ sub load_unlocked {
            @check_order = (@{$self->{'driveorder'}});
        } else {
            # the constructor should detect this circumstance
-           die "invalid drive_choice";
+           confess "invalid drive_choice";
        }
 
        my %checked;
@@ -587,7 +587,7 @@ sub load_unlocked {
 
     step check_device => sub {
        my $device_name = $self->{'drive2device'}->{$drive};
-       die "drive $drive not found in drive2device" unless $device_name; # shouldn't happen
+       confess "drive $drive not found in drive2device" unless $device_name; # shouldn't happen
 
        $self->_debug("polling '$device_name' to see if it's ready");
 
@@ -644,7 +644,13 @@ sub load_unlocked {
            }
            $state->{'slots'}->{$slot}->{'label'} = $label;
            if ($state->{'slots'}->{$slot}->{'barcode'}) {
-               $state->{'bc2lb'}->{$state->{'slots'}->{$slot}->{'barcode'}} = $label;
+               my $barcode = $state->{'slots'}->{$slot}->{'barcode'};
+               my $old_label = $state->{'bc2lb'}->{$barcode};
+               if ($label ne $old_label) {
+                   $self->_debug("make_res: slot $slot");
+                   $self->_debug("update label '$label' for barcode '$barcode', old label was '$old_label'");
+               }
+               $state->{'bc2lb'}->{$barcode} = $label;
            }
 
            return $self->make_error("failed", $params{'res_cb'},
@@ -689,11 +695,17 @@ sub load_unlocked {
        $state->{'drives'}->{$drive}->{'state'} = Amanda::Changer::SLOT_FULL;
        $state->{'drives'}->{$drive}->{'barcode'} = $state->{'slots'}->{$slot}->{'barcode'};
        $state->{'slots'}->{$slot}->{'device_status'} = $device->status;
-       if ($label and $state->{'slots'}->{$slot}->{'barcode'}) {
-           $state->{'bc2lb'}->{$state->{'slots'}->{$slot}->{'barcode'}} = $label;
+       my $barcode = $state->{'slots'}->{$slot}->{'barcode'};
+       if ($label and $barcode) {
+           my $old_label = $state->{'bc2lb'}->{$barcode};
+           if (defined $old_label and $old_label ne $label) {
+               $self->_debug("load drive $drive slot $slot");
+               $self->_debug("update label '$label' for barcode '$barcode', old label was '$old_label'");
+           }
+           $state->{'bc2lb'}->{$barcode} = $label;
        }
        if ($params{'set_current'}) {
-               $self->_debug("setting current slot to $slot");
+           $self->_debug("setting current slot to $slot");
            $state->{'current_slot'} = $slot;
        }
 
@@ -845,6 +857,11 @@ sub _set_label_unlocked {
        $state->{'slots'}->{$slot}->{'label'} = $label;
     }
     if (defined $barcode) {
+       if (defined $state->{'bc2lb'}->{$barcode} and
+           $state->{'bc2lb'}->{$barcode} ne $label) {
+           my $old_label = $state->{'bc2lb'}->{$barcode};
+           $self->_debug("update barcode '$barcode' to label '$label', old label was '$old_label'");
+       }
        $state->{'bc2lb'}->{$barcode} = $label;
     }
 
@@ -1914,6 +1931,7 @@ sub status {
            } else {
                my %status;
                for my $line (split '\n', $output) {
+                   debug("mtx: $line");
                    my ($slot, $ie, $slinfo);
 
                    # drives (data transfer elements)
@@ -2025,12 +2043,12 @@ sub _run_system_command {
 
     my ($readfd, $writefd) = POSIX::pipe();
     if (!defined($writefd)) {
-       die("Error creating pipe: $!");
+       confess("Error creating pipe: $!");
     }
 
     my $pid = fork();
     if (!defined($pid) or $pid < 0) {
-        die("Can't fork to run changer script: $!");
+        confess("Can't fork to run changer script: $!");
     }
 
     if (!$pid) {
index 75e0469f8d88491d358db2db8315c06562ebec48..06a15e2dd89573ce47e415a354d867eca25733cc 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008,2009,2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -20,6 +20,7 @@ package Amanda::Changer::single;
 
 use strict;
 use warnings;
+use Carp;
 use vars qw( @ISA );
 @ISA = qw( Amanda::Changer );
 
@@ -77,7 +78,7 @@ sub load {
 
     return if $self->check_error($params{'res_cb'});
 
-    die "no res_cb supplied" unless (exists $params{'res_cb'});
+    confess "no res_cb supplied" unless (exists $params{'res_cb'});
 
     if ($self->{'reserved'}) {
        return $self->make_error("failed", $params{'res_cb'},
index 07989aa6be8081a88c87baf277cf2ca897ad0530..8d593829053756d7b276b7d78a1b9a61c51ad50d 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 9746795e71183eb0e9325ff25e2d0472de752536..1051b239e3d076c8303433c3a4fdde08dc1d8299 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index b908c9575c4066076721a06bced96f8a27939e2d..e31d7662722f415f62e973fd7524867c99b4e68b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index cacd064a4fe4500769135e8b4f2e54a4a3fc7d34..6a585e62c12f898091e7d014c36aa5e6216dd7c6 100644 (file)
@@ -1968,7 +1968,7 @@ typedef char **val_t_strs;
 val_t_strs getconf_byname_strs(char *key, int str_needs_quotes) {
     val_t *val = getconf_byname(key);
     if (!val) return NULL;
-    return val_t_display_strs(val, str_needs_quotes);
+    return val_t_display_strs(val, str_needs_quotes, FALSE, FALSE);
 }
 
 
@@ -4808,16 +4808,28 @@ XS(_wrap_set_config_overrides) {
 
 XS(_wrap_dump_configuration) {
   {
+    gboolean arg1 ;
+    gboolean arg2 ;
     int argvi = 0;
     dXSARGS;
     
-    if ((items < 0) || (items > 0)) {
-      SWIG_croak("Usage: dump_configuration();");
+    if ((items < 2) || (items > 2)) {
+      SWIG_croak("Usage: dump_configuration(print_default,print_source);");
     }
-    dump_configuration();
+    {
+      arg1 = SvTRUE(ST(0));
+    }
+    {
+      arg2 = SvTRUE(ST(1));
+    }
+    dump_configuration(arg1,arg2);
     ST(argvi) = sv_newmortal();
+    
+    
     XSRETURN(argvi);
   fail:
+    
+    
     SWIG_croak_null();
   }
 }
@@ -4980,6 +4992,7 @@ XS(_wrap_amandaify_property_name) {
     result = (gchar *)amandaify_property_name((char const *)arg1);
     ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ;
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+    free((char*)result);
     XSRETURN(argvi);
   fail:
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
@@ -5934,6 +5947,11 @@ XS(SWIG_init) {
     sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1((int)(CNF_EJECT_VOLUME)));
     SvREADONLY_on(sv);
   } while(0) /*@SWIG@*/;
+  /*@SWIG:/usr/share/swig/2.0.4/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+    SV *sv = get_sv((char*) SWIG_prefix "CNF_TMPDIR", TRUE | 0x2 | GV_ADDMULTI);
+    sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1((int)(CNF_TMPDIR)));
+    SvREADONLY_on(sv);
+  } while(0) /*@SWIG@*/;
   /*@SWIG:/usr/share/swig/2.0.4/perl5/perltypemaps.swg,65,%set_constant@*/ do {
     SV *sv = get_sv((char*) SWIG_prefix "TAPETYPE_COMMENT", TRUE | 0x2 | GV_ADDMULTI);
     sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1((int)(TAPETYPE_COMMENT)));
@@ -6209,6 +6227,11 @@ XS(SWIG_init) {
     sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1((int)(DUMPTYPE_ALLOW_SPLIT)));
     SvREADONLY_on(sv);
   } while(0) /*@SWIG@*/;
+  /*@SWIG:/usr/share/swig/2.0.4/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+    SV *sv = get_sv((char*) SWIG_prefix "DUMPTYPE_MAX_WARNINGS", TRUE | 0x2 | GV_ADDMULTI);
+    sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1((int)(DUMPTYPE_MAX_WARNINGS)));
+    SvREADONLY_on(sv);
+  } while(0) /*@SWIG@*/;
   /*@SWIG:/usr/share/swig/2.0.4/perl5/perltypemaps.swg,65,%set_constant@*/ do {
     SV *sv = get_sv((char*) SWIG_prefix "DUMPTYPE_RECOVERY_LIMIT", TRUE | 0x2 | GV_ADDMULTI);
     sv_setsv(sv, SWIG_From_int  SWIG_PERL_CALL_ARGS_1((int)(DUMPTYPE_RECOVERY_LIMIT)));
index 79b2e5baa167c62ef84f6f835b7d53690419b782..bcd636ca262a318ee1e57e8623f6abb86dfcf198 100644 (file)
@@ -217,6 +217,7 @@ package Amanda::Config;
 *CNF_INTERACTIVITY = *Amanda::Configc::CNF_INTERACTIVITY;
 *CNF_TAPERSCAN = *Amanda::Configc::CNF_TAPERSCAN;
 *CNF_EJECT_VOLUME = *Amanda::Configc::CNF_EJECT_VOLUME;
+*CNF_TMPDIR = *Amanda::Configc::CNF_TMPDIR;
 *TAPETYPE_COMMENT = *Amanda::Configc::TAPETYPE_COMMENT;
 *TAPETYPE_LBL_TEMPL = *Amanda::Configc::TAPETYPE_LBL_TEMPL;
 *TAPETYPE_BLOCKSIZE = *Amanda::Configc::TAPETYPE_BLOCKSIZE;
@@ -272,6 +273,7 @@ package Amanda::Config;
 *DUMPTYPE_PROPERTY = *Amanda::Configc::DUMPTYPE_PROPERTY;
 *DUMPTYPE_DATA_PATH = *Amanda::Configc::DUMPTYPE_DATA_PATH;
 *DUMPTYPE_ALLOW_SPLIT = *Amanda::Configc::DUMPTYPE_ALLOW_SPLIT;
+*DUMPTYPE_MAX_WARNINGS = *Amanda::Configc::DUMPTYPE_MAX_WARNINGS;
 *DUMPTYPE_RECOVERY_LIMIT = *Amanda::Configc::DUMPTYPE_RECOVERY_LIMIT;
 *DUMPTYPE_DUMP_LIMIT = *Amanda::Configc::DUMPTYPE_DUMP_LIMIT;
 *INTER_COMMENT = *Amanda::Configc::INTER_COMMENT;
@@ -738,9 +740,9 @@ sub confparm_key_to_string {
     return $enumval;
 }
 
-push @EXPORT_OK, qw( $CNF_ORG $CNF_CONF $CNF_AMDUMP_SERVER $CNF_INDEX_SERVER $CNF_TAPE_SERVER $CNF_AUTH $CNF_SSH_KEYS $CNF_AMANDAD_PATH $CNF_CLIENT_USERNAME $CNF_CLIENT_PORT $CNF_GNUTAR_LIST_DIR $CNF_AMANDATES $CNF_MAILER $CNF_MAILTO $CNF_DUMPUSER $CNF_TAPEDEV $CNF_DEVICE_PROPERTY $CNF_PROPERTY $CNF_CHANGERDEV $CNF_CHANGERFILE $CNF_LABELSTR $CNF_AUTOLABEL $CNF_META_AUTOLABEL $CNF_TAPELIST $CNF_DISKFILE $CNF_INFOFILE $CNF_LOGDIR $CNF_INDEXDIR $CNF_TAPETYPE $CNF_DUMPCYCLE $CNF_RUNSPERCYCLE $CNF_TAPECYCLE $CNF_NETUSAGE $CNF_INPARALLEL $CNF_DUMPORDER $CNF_BUMPPERCENT $CNF_BUMPSIZE $CNF_BUMPMULT $CNF_BUMPDAYS $CNF_TPCHANGER $CNF_RUNTAPES $CNF_MAX_DLE_BY_VOLUME $CNF_MAXDUMPS $CNF_ETIMEOUT $CNF_DTIMEOUT $CNF_CTIMEOUT $CNF_DEVICE_OUTPUT_BUFFER_SIZE $CNF_PRINTER $CNF_AUTOFLUSH $CNF_RESERVE $CNF_MAXDUMPSIZE $CNF_COLUMNSPEC $CNF_AMRECOVER_DO_FSF $CNF_AMRECOVER_CHECK_LABEL $CNF_AMRECOVER_CHANGER $CNF_TAPERALGO $CNF_FLUSH_THRESHOLD_DUMPED $CNF_FLUSH_THRESHOLD_SCHEDULED $CNF_TAPERFLUSH $CNF_DISPLAYUNIT $CNF_KRB5KEYTAB $CNF_KRB5PRINCIPAL $CNF_LABEL_NEW_TAPES $CNF_USETIMESTAMPS $CNF_REP_TRIES $CNF_CONNECT_TRIES $CNF_REQ_TRIES $CNF_DEBUG_AMANDAD $CNF_DEBUG_RECOVERY $CNF_DEBUG_AMIDXTAPED $CNF_DEBUG_AMINDEXD $CNF_DEBUG_AMRECOVER $CNF_DEBUG_AUTH $CNF_DEBUG_EVENT $CNF_DEBUG_HOLDING $CNF_DEBUG_PROTOCOL $CNF_DEBUG_PLANNER $CNF_DEBUG_DRIVER $CNF_DEBUG_DUMPER $CNF_DEBUG_CHUNKER $CNF_DEBUG_TAPER $CNF_DEBUG_SELFCHECK $CNF_DEBUG_SENDSIZE $CNF_DEBUG_SENDBACKUP $CNF_RESERVED_UDP_PORT $CNF_RESERVED_TCP_PORT $CNF_UNRESERVED_TCP_PORT $CNF_HOLDINGDISK $CNF_SEND_AMREPORT_ON $CNF_TAPER_PARALLEL_WRITE $CNF_RECOVERY_LIMIT  $CNF_INTERACTIVITY  $CNF_TAPERSCAN  $CNF_EJECT_VOLUME);
-push @{$EXPORT_TAGS{"confparm_key"}}, qw( $CNF_ORG $CNF_CONF $CNF_AMDUMP_SERVER $CNF_INDEX_SERVER $CNF_TAPE_SERVER $CNF_AUTH $CNF_SSH_KEYS $CNF_AMANDAD_PATH $CNF_CLIENT_USERNAME $CNF_CLIENT_PORT $CNF_GNUTAR_LIST_DIR $CNF_AMANDATES $CNF_MAILER $CNF_MAILTO $CNF_DUMPUSER $CNF_TAPEDEV $CNF_DEVICE_PROPERTY $CNF_PROPERTY $CNF_CHANGERDEV $CNF_CHANGERFILE $CNF_LABELSTR $CNF_AUTOLABEL $CNF_META_AUTOLABEL $CNF_TAPELIST $CNF_DISKFILE $CNF_INFOFILE $CNF_LOGDIR $CNF_INDEXDIR $CNF_TAPETYPE $CNF_DUMPCYCLE $CNF_RUNSPERCYCLE $CNF_TAPECYCLE $CNF_NETUSAGE $CNF_INPARALLEL $CNF_DUMPORDER $CNF_BUMPPERCENT $CNF_BUMPSIZE $CNF_BUMPMULT $CNF_BUMPDAYS $CNF_TPCHANGER $CNF_RUNTAPES $CNF_MAX_DLE_BY_VOLUME $CNF_MAXDUMPS $CNF_ETIMEOUT $CNF_DTIMEOUT $CNF_CTIMEOUT $CNF_DEVICE_OUTPUT_BUFFER_SIZE $CNF_PRINTER $CNF_AUTOFLUSH $CNF_RESERVE $CNF_MAXDUMPSIZE $CNF_COLUMNSPEC $CNF_AMRECOVER_DO_FSF $CNF_AMRECOVER_CHECK_LABEL $CNF_AMRECOVER_CHANGER $CNF_TAPERALGO $CNF_FLUSH_THRESHOLD_DUMPED $CNF_FLUSH_THRESHOLD_SCHEDULED $CNF_TAPERFLUSH $CNF_DISPLAYUNIT $CNF_KRB5KEYTAB $CNF_KRB5PRINCIPAL $CNF_LABEL_NEW_TAPES $CNF_USETIMESTAMPS $CNF_REP_TRIES $CNF_CONNECT_TRIES $CNF_REQ_TRIES $CNF_DEBUG_AMANDAD $CNF_DEBUG_RECOVERY $CNF_DEBUG_AMIDXTAPED $CNF_DEBUG_AMINDEXD $CNF_DEBUG_AMRECOVER $CNF_DEBUG_AUTH $CNF_DEBUG_EVENT $CNF_DEBUG_HOLDING $CNF_DEBUG_PROTOCOL $CNF_DEBUG_PLANNER $CNF_DEBUG_DRIVER $CNF_DEBUG_DUMPER $CNF_DEBUG_CHUNKER $CNF_DEBUG_TAPER $CNF_DEBUG_SELFCHECK $CNF_DEBUG_SENDSIZE $CNF_DEBUG_SENDBACKUP $CNF_RESERVED_UDP_PORT $CNF_RESERVED_TCP_PORT $CNF_UNRESERVED_TCP_PORT $CNF_HOLDINGDISK $CNF_SEND_AMREPORT_ON $CNF_TAPER_PARALLEL_WRITE $CNF_RECOVERY_LIMIT  $CNF_INTERACTIVITY  $CNF_TAPERSCAN  $CNF_EJECT_VOLUME);
-      foreach (qw(  CNF_ORG CNF_CONF CNF_AMDUMP_SERVER CNF_INDEX_SERVER CNF_TAPE_SERVER CNF_AUTH CNF_SSH_KEYS CNF_AMANDAD_PATH CNF_CLIENT_USERNAME CNF_CLIENT_PORT CNF_GNUTAR_LIST_DIR CNF_AMANDATES CNF_MAILER CNF_MAILTO CNF_DUMPUSER CNF_TAPEDEV CNF_DEVICE_PROPERTY CNF_PROPERTY CNF_CHANGERDEV CNF_CHANGERFILE CNF_LABELSTR CNF_AUTOLABEL CNF_META_AUTOLABEL CNF_TAPELIST CNF_DISKFILE CNF_INFOFILE CNF_LOGDIR CNF_INDEXDIR CNF_TAPETYPE CNF_DUMPCYCLE CNF_RUNSPERCYCLE CNF_TAPECYCLE CNF_NETUSAGE CNF_INPARALLEL CNF_DUMPORDER CNF_BUMPPERCENT CNF_BUMPSIZE CNF_BUMPMULT CNF_BUMPDAYS CNF_TPCHANGER CNF_RUNTAPES CNF_MAX_DLE_BY_VOLUME CNF_MAXDUMPS CNF_ETIMEOUT CNF_DTIMEOUT CNF_CTIMEOUT CNF_DEVICE_OUTPUT_BUFFER_SIZE CNF_PRINTER CNF_AUTOFLUSH CNF_RESERVE CNF_MAXDUMPSIZE CNF_COLUMNSPEC CNF_AMRECOVER_DO_FSF CNF_AMRECOVER_CHECK_LABEL CNF_AMRECOVER_CHANGER CNF_TAPERALGO CNF_FLUSH_THRESHOLD_DUMPED CNF_FLUSH_THRESHOLD_SCHEDULED CNF_TAPERFLUSH CNF_DISPLAYUNIT CNF_KRB5KEYTAB CNF_KRB5PRINCIPAL CNF_LABEL_NEW_TAPES CNF_USETIMESTAMPS CNF_REP_TRIES CNF_CONNECT_TRIES CNF_REQ_TRIES CNF_DEBUG_AMANDAD CNF_DEBUG_RECOVERY CNF_DEBUG_AMIDXTAPED CNF_DEBUG_AMINDEXD CNF_DEBUG_AMRECOVER CNF_DEBUG_AUTH CNF_DEBUG_EVENT CNF_DEBUG_HOLDING CNF_DEBUG_PROTOCOL CNF_DEBUG_PLANNER CNF_DEBUG_DRIVER CNF_DEBUG_DUMPER CNF_DEBUG_CHUNKER CNF_DEBUG_TAPER CNF_DEBUG_SELFCHECK CNF_DEBUG_SENDSIZE CNF_DEBUG_SENDBACKUP CNF_RESERVED_UDP_PORT CNF_RESERVED_TCP_PORT CNF_UNRESERVED_TCP_PORT CNF_HOLDINGDISK CNF_SEND_AMREPORT_ON CNF_TAPER_PARALLEL_WRITE CNF_RECOVERY_LIMIT  CNF_INTERACTIVITY  CNF_TAPERSCAN  CNF_EJECT_VOLUME)) {        $_confparm_key_VALUES{$_} = $$_;      }  
+push @EXPORT_OK, qw( $CNF_ORG $CNF_CONF $CNF_AMDUMP_SERVER $CNF_INDEX_SERVER $CNF_TAPE_SERVER $CNF_AUTH $CNF_SSH_KEYS $CNF_AMANDAD_PATH $CNF_CLIENT_USERNAME $CNF_CLIENT_PORT $CNF_GNUTAR_LIST_DIR $CNF_AMANDATES $CNF_MAILER $CNF_MAILTO $CNF_DUMPUSER $CNF_TAPEDEV $CNF_DEVICE_PROPERTY $CNF_PROPERTY $CNF_CHANGERDEV $CNF_CHANGERFILE $CNF_LABELSTR $CNF_AUTOLABEL $CNF_META_AUTOLABEL $CNF_TAPELIST $CNF_DISKFILE $CNF_INFOFILE $CNF_LOGDIR $CNF_INDEXDIR $CNF_TAPETYPE $CNF_DUMPCYCLE $CNF_RUNSPERCYCLE $CNF_TAPECYCLE $CNF_NETUSAGE $CNF_INPARALLEL $CNF_DUMPORDER $CNF_BUMPPERCENT $CNF_BUMPSIZE $CNF_BUMPMULT $CNF_BUMPDAYS $CNF_TPCHANGER $CNF_RUNTAPES $CNF_MAX_DLE_BY_VOLUME $CNF_MAXDUMPS $CNF_ETIMEOUT $CNF_DTIMEOUT $CNF_CTIMEOUT $CNF_DEVICE_OUTPUT_BUFFER_SIZE $CNF_PRINTER $CNF_AUTOFLUSH $CNF_RESERVE $CNF_MAXDUMPSIZE $CNF_COLUMNSPEC $CNF_AMRECOVER_DO_FSF $CNF_AMRECOVER_CHECK_LABEL $CNF_AMRECOVER_CHANGER $CNF_TAPERALGO $CNF_FLUSH_THRESHOLD_DUMPED $CNF_FLUSH_THRESHOLD_SCHEDULED $CNF_TAPERFLUSH $CNF_DISPLAYUNIT $CNF_KRB5KEYTAB $CNF_KRB5PRINCIPAL $CNF_LABEL_NEW_TAPES $CNF_USETIMESTAMPS $CNF_REP_TRIES $CNF_CONNECT_TRIES $CNF_REQ_TRIES $CNF_DEBUG_AMANDAD $CNF_DEBUG_RECOVERY $CNF_DEBUG_AMIDXTAPED $CNF_DEBUG_AMINDEXD $CNF_DEBUG_AMRECOVER $CNF_DEBUG_AUTH $CNF_DEBUG_EVENT $CNF_DEBUG_HOLDING $CNF_DEBUG_PROTOCOL $CNF_DEBUG_PLANNER $CNF_DEBUG_DRIVER $CNF_DEBUG_DUMPER $CNF_DEBUG_CHUNKER $CNF_DEBUG_TAPER $CNF_DEBUG_SELFCHECK $CNF_DEBUG_SENDSIZE $CNF_DEBUG_SENDBACKUP $CNF_RESERVED_UDP_PORT $CNF_RESERVED_TCP_PORT $CNF_UNRESERVED_TCP_PORT $CNF_HOLDINGDISK $CNF_SEND_AMREPORT_ON $CNF_TAPER_PARALLEL_WRITE $CNF_RECOVERY_LIMIT  $CNF_INTERACTIVITY  $CNF_TAPERSCAN  $CNF_EJECT_VOLUME  $CNF_TMPDIR);
+push @{$EXPORT_TAGS{"confparm_key"}}, qw( $CNF_ORG $CNF_CONF $CNF_AMDUMP_SERVER $CNF_INDEX_SERVER $CNF_TAPE_SERVER $CNF_AUTH $CNF_SSH_KEYS $CNF_AMANDAD_PATH $CNF_CLIENT_USERNAME $CNF_CLIENT_PORT $CNF_GNUTAR_LIST_DIR $CNF_AMANDATES $CNF_MAILER $CNF_MAILTO $CNF_DUMPUSER $CNF_TAPEDEV $CNF_DEVICE_PROPERTY $CNF_PROPERTY $CNF_CHANGERDEV $CNF_CHANGERFILE $CNF_LABELSTR $CNF_AUTOLABEL $CNF_META_AUTOLABEL $CNF_TAPELIST $CNF_DISKFILE $CNF_INFOFILE $CNF_LOGDIR $CNF_INDEXDIR $CNF_TAPETYPE $CNF_DUMPCYCLE $CNF_RUNSPERCYCLE $CNF_TAPECYCLE $CNF_NETUSAGE $CNF_INPARALLEL $CNF_DUMPORDER $CNF_BUMPPERCENT $CNF_BUMPSIZE $CNF_BUMPMULT $CNF_BUMPDAYS $CNF_TPCHANGER $CNF_RUNTAPES $CNF_MAX_DLE_BY_VOLUME $CNF_MAXDUMPS $CNF_ETIMEOUT $CNF_DTIMEOUT $CNF_CTIMEOUT $CNF_DEVICE_OUTPUT_BUFFER_SIZE $CNF_PRINTER $CNF_AUTOFLUSH $CNF_RESERVE $CNF_MAXDUMPSIZE $CNF_COLUMNSPEC $CNF_AMRECOVER_DO_FSF $CNF_AMRECOVER_CHECK_LABEL $CNF_AMRECOVER_CHANGER $CNF_TAPERALGO $CNF_FLUSH_THRESHOLD_DUMPED $CNF_FLUSH_THRESHOLD_SCHEDULED $CNF_TAPERFLUSH $CNF_DISPLAYUNIT $CNF_KRB5KEYTAB $CNF_KRB5PRINCIPAL $CNF_LABEL_NEW_TAPES $CNF_USETIMESTAMPS $CNF_REP_TRIES $CNF_CONNECT_TRIES $CNF_REQ_TRIES $CNF_DEBUG_AMANDAD $CNF_DEBUG_RECOVERY $CNF_DEBUG_AMIDXTAPED $CNF_DEBUG_AMINDEXD $CNF_DEBUG_AMRECOVER $CNF_DEBUG_AUTH $CNF_DEBUG_EVENT $CNF_DEBUG_HOLDING $CNF_DEBUG_PROTOCOL $CNF_DEBUG_PLANNER $CNF_DEBUG_DRIVER $CNF_DEBUG_DUMPER $CNF_DEBUG_CHUNKER $CNF_DEBUG_TAPER $CNF_DEBUG_SELFCHECK $CNF_DEBUG_SENDSIZE $CNF_DEBUG_SENDBACKUP $CNF_RESERVED_UDP_PORT $CNF_RESERVED_TCP_PORT $CNF_UNRESERVED_TCP_PORT $CNF_HOLDINGDISK $CNF_SEND_AMREPORT_ON $CNF_TAPER_PARALLEL_WRITE $CNF_RECOVERY_LIMIT  $CNF_INTERACTIVITY  $CNF_TAPERSCAN  $CNF_EJECT_VOLUME  $CNF_TMPDIR);
+      foreach (qw(  CNF_ORG CNF_CONF CNF_AMDUMP_SERVER CNF_INDEX_SERVER CNF_TAPE_SERVER CNF_AUTH CNF_SSH_KEYS CNF_AMANDAD_PATH CNF_CLIENT_USERNAME CNF_CLIENT_PORT CNF_GNUTAR_LIST_DIR CNF_AMANDATES CNF_MAILER CNF_MAILTO CNF_DUMPUSER CNF_TAPEDEV CNF_DEVICE_PROPERTY CNF_PROPERTY CNF_CHANGERDEV CNF_CHANGERFILE CNF_LABELSTR CNF_AUTOLABEL CNF_META_AUTOLABEL CNF_TAPELIST CNF_DISKFILE CNF_INFOFILE CNF_LOGDIR CNF_INDEXDIR CNF_TAPETYPE CNF_DUMPCYCLE CNF_RUNSPERCYCLE CNF_TAPECYCLE CNF_NETUSAGE CNF_INPARALLEL CNF_DUMPORDER CNF_BUMPPERCENT CNF_BUMPSIZE CNF_BUMPMULT CNF_BUMPDAYS CNF_TPCHANGER CNF_RUNTAPES CNF_MAX_DLE_BY_VOLUME CNF_MAXDUMPS CNF_ETIMEOUT CNF_DTIMEOUT CNF_CTIMEOUT CNF_DEVICE_OUTPUT_BUFFER_SIZE CNF_PRINTER CNF_AUTOFLUSH CNF_RESERVE CNF_MAXDUMPSIZE CNF_COLUMNSPEC CNF_AMRECOVER_DO_FSF CNF_AMRECOVER_CHECK_LABEL CNF_AMRECOVER_CHANGER CNF_TAPERALGO CNF_FLUSH_THRESHOLD_DUMPED CNF_FLUSH_THRESHOLD_SCHEDULED CNF_TAPERFLUSH CNF_DISPLAYUNIT CNF_KRB5KEYTAB CNF_KRB5PRINCIPAL CNF_LABEL_NEW_TAPES CNF_USETIMESTAMPS CNF_REP_TRIES CNF_CONNECT_TRIES CNF_REQ_TRIES CNF_DEBUG_AMANDAD CNF_DEBUG_RECOVERY CNF_DEBUG_AMIDXTAPED CNF_DEBUG_AMINDEXD CNF_DEBUG_AMRECOVER CNF_DEBUG_AUTH CNF_DEBUG_EVENT CNF_DEBUG_HOLDING CNF_DEBUG_PROTOCOL CNF_DEBUG_PLANNER CNF_DEBUG_DRIVER CNF_DEBUG_DUMPER CNF_DEBUG_CHUNKER CNF_DEBUG_TAPER CNF_DEBUG_SELFCHECK CNF_DEBUG_SENDSIZE CNF_DEBUG_SENDBACKUP CNF_RESERVED_UDP_PORT CNF_RESERVED_TCP_PORT CNF_UNRESERVED_TCP_PORT CNF_HOLDINGDISK CNF_SEND_AMREPORT_ON CNF_TAPER_PARALLEL_WRITE CNF_RECOVERY_LIMIT  CNF_INTERACTIVITY  CNF_TAPERSCAN  CNF_EJECT_VOLUME  CNF_TMPDIR)) {    $_confparm_key_VALUES{$_} = $$_;      }  
 #copy symbols in confparm_key to getconf
 push @{$EXPORT_TAGS{"getconf"}},  @{$EXPORT_TAGS{"confparm_key"}};
 
@@ -749,7 +751,7 @@ use Amanda::Config::FoldingHash;
 
 =pod
 
-Global Parameters:       C<$CNF_ORG> C<$CNF_CONF> C<$CNF_AMDUMP_SERVER> C<$CNF_INDEX_SERVER> C<$CNF_TAPE_SERVER> C<$CNF_AUTH> C<$CNF_SSH_KEYS> C<$CNF_AMANDAD_PATH> C<$CNF_CLIENT_USERNAME> C<$CNF_CLIENT_PORT> C<$CNF_GNUTAR_LIST_DIR> C<$CNF_AMANDATES> C<$CNF_MAILER> C<$CNF_MAILTO> C<$CNF_DUMPUSER> C<$CNF_TAPEDEV> C<$CNF_DEVICE_PROPERTY> C<$CNF_PROPERTY> C<$CNF_CHANGERDEV> C<$CNF_CHANGERFILE> C<$CNF_LABELSTR> C<$CNF_AUTOLABEL> C<$CNF_META_AUTOLABEL> C<$CNF_TAPELIST> C<$CNF_DISKFILE> C<$CNF_INFOFILE> C<$CNF_LOGDIR> C<$CNF_INDEXDIR> C<$CNF_TAPETYPE> C<$CNF_DUMPCYCLE> C<$CNF_RUNSPERCYCLE> C<$CNF_TAPECYCLE> C<$CNF_NETUSAGE> C<$CNF_INPARALLEL> C<$CNF_DUMPORDER> C<$CNF_BUMPPERCENT> C<$CNF_BUMPSIZE> C<$CNF_BUMPMULT> C<$CNF_BUMPDAYS> C<$CNF_TPCHANGER> C<$CNF_RUNTAPES> C<$CNF_MAX_DLE_BY_VOLUME> C<$CNF_MAXDUMPS> C<$CNF_ETIMEOUT> C<$CNF_DTIMEOUT> C<$CNF_CTIMEOUT> C<$CNF_DEVICE_OUTPUT_BUFFER_SIZE> C<$CNF_PRINTER> C<$CNF_AUTOFLUSH> C<$CNF_RESERVE> C<$CNF_MAXDUMPSIZE> C<$CNF_COLUMNSPEC> C<$CNF_AMRECOVER_DO_FSF> C<$CNF_AMRECOVER_CHECK_LABEL> C<$CNF_AMRECOVER_CHANGER> C<$CNF_TAPERALGO> C<$CNF_FLUSH_THRESHOLD_DUMPED> C<$CNF_FLUSH_THRESHOLD_SCHEDULED> C<$CNF_TAPERFLUSH> C<$CNF_DISPLAYUNIT> C<$CNF_KRB5KEYTAB> C<$CNF_KRB5PRINCIPAL> C<$CNF_LABEL_NEW_TAPES> C<$CNF_USETIMESTAMPS> C<$CNF_REP_TRIES> C<$CNF_CONNECT_TRIES> C<$CNF_REQ_TRIES> C<$CNF_DEBUG_AMANDAD> C<$CNF_DEBUG_RECOVERY> C<$CNF_DEBUG_AMIDXTAPED> C<$CNF_DEBUG_AMINDEXD> C<$CNF_DEBUG_AMRECOVER> C<$CNF_DEBUG_AUTH> C<$CNF_DEBUG_EVENT> C<$CNF_DEBUG_HOLDING> C<$CNF_DEBUG_PROTOCOL> C<$CNF_DEBUG_PLANNER> C<$CNF_DEBUG_DRIVER> C<$CNF_DEBUG_DUMPER> C<$CNF_DEBUG_CHUNKER> C<$CNF_DEBUG_TAPER> C<$CNF_DEBUG_SELFCHECK> C<$CNF_DEBUG_SENDSIZE> C<$CNF_DEBUG_SENDBACKUP> C<$CNF_RESERVED_UDP_PORT> C<$CNF_RESERVED_TCP_PORT> C<$CNF_UNRESERVED_TCP_PORT> C<$CNF_HOLDINGDISK> C<$CNF_SEND_AMREPORT_ON> C<$CNF_TAPER_PARALLEL_WRITE> C<$CNF_RECOVERY_LIMIT>  C<$CNF_INTERACTIVITY>  C<$CNF_TAPERSCAN>  C<$CNF_EJECT_VOLUME>
+Global Parameters:       C<$CNF_ORG> C<$CNF_CONF> C<$CNF_AMDUMP_SERVER> C<$CNF_INDEX_SERVER> C<$CNF_TAPE_SERVER> C<$CNF_AUTH> C<$CNF_SSH_KEYS> C<$CNF_AMANDAD_PATH> C<$CNF_CLIENT_USERNAME> C<$CNF_CLIENT_PORT> C<$CNF_GNUTAR_LIST_DIR> C<$CNF_AMANDATES> C<$CNF_MAILER> C<$CNF_MAILTO> C<$CNF_DUMPUSER> C<$CNF_TAPEDEV> C<$CNF_DEVICE_PROPERTY> C<$CNF_PROPERTY> C<$CNF_CHANGERDEV> C<$CNF_CHANGERFILE> C<$CNF_LABELSTR> C<$CNF_AUTOLABEL> C<$CNF_META_AUTOLABEL> C<$CNF_TAPELIST> C<$CNF_DISKFILE> C<$CNF_INFOFILE> C<$CNF_LOGDIR> C<$CNF_INDEXDIR> C<$CNF_TAPETYPE> C<$CNF_DUMPCYCLE> C<$CNF_RUNSPERCYCLE> C<$CNF_TAPECYCLE> C<$CNF_NETUSAGE> C<$CNF_INPARALLEL> C<$CNF_DUMPORDER> C<$CNF_BUMPPERCENT> C<$CNF_BUMPSIZE> C<$CNF_BUMPMULT> C<$CNF_BUMPDAYS> C<$CNF_TPCHANGER> C<$CNF_RUNTAPES> C<$CNF_MAX_DLE_BY_VOLUME> C<$CNF_MAXDUMPS> C<$CNF_ETIMEOUT> C<$CNF_DTIMEOUT> C<$CNF_CTIMEOUT> C<$CNF_DEVICE_OUTPUT_BUFFER_SIZE> C<$CNF_PRINTER> C<$CNF_AUTOFLUSH> C<$CNF_RESERVE> C<$CNF_MAXDUMPSIZE> C<$CNF_COLUMNSPEC> C<$CNF_AMRECOVER_DO_FSF> C<$CNF_AMRECOVER_CHECK_LABEL> C<$CNF_AMRECOVER_CHANGER> C<$CNF_TAPERALGO> C<$CNF_FLUSH_THRESHOLD_DUMPED> C<$CNF_FLUSH_THRESHOLD_SCHEDULED> C<$CNF_TAPERFLUSH> C<$CNF_DISPLAYUNIT> C<$CNF_KRB5KEYTAB> C<$CNF_KRB5PRINCIPAL> C<$CNF_LABEL_NEW_TAPES> C<$CNF_USETIMESTAMPS> C<$CNF_REP_TRIES> C<$CNF_CONNECT_TRIES> C<$CNF_REQ_TRIES> C<$CNF_DEBUG_AMANDAD> C<$CNF_DEBUG_RECOVERY> C<$CNF_DEBUG_AMIDXTAPED> C<$CNF_DEBUG_AMINDEXD> C<$CNF_DEBUG_AMRECOVER> C<$CNF_DEBUG_AUTH> C<$CNF_DEBUG_EVENT> C<$CNF_DEBUG_HOLDING> C<$CNF_DEBUG_PROTOCOL> C<$CNF_DEBUG_PLANNER> C<$CNF_DEBUG_DRIVER> C<$CNF_DEBUG_DUMPER> C<$CNF_DEBUG_CHUNKER> C<$CNF_DEBUG_TAPER> C<$CNF_DEBUG_SELFCHECK> C<$CNF_DEBUG_SENDSIZE> C<$CNF_DEBUG_SENDBACKUP> C<$CNF_RESERVED_UDP_PORT> C<$CNF_RESERVED_TCP_PORT> C<$CNF_UNRESERVED_TCP_PORT> C<$CNF_HOLDINGDISK> C<$CNF_SEND_AMREPORT_ON> C<$CNF_TAPER_PARALLEL_WRITE> C<$CNF_RECOVERY_LIMIT>  C<$CNF_INTERACTIVITY>  C<$CNF_TAPERSCAN>  C<$CNF_EJECT_VOLUME>  C<$CNF_TMPDIR>
 
 =cut
 
@@ -810,9 +812,9 @@ sub dumptype_key_to_string {
     return $enumval;
 }
 
-push @EXPORT_OK, qw( $DUMPTYPE_COMMENT $DUMPTYPE_PROGRAM $DUMPTYPE_SRVCOMPPROG $DUMPTYPE_CLNTCOMPPROG $DUMPTYPE_SRV_ENCRYPT $DUMPTYPE_CLNT_ENCRYPT $DUMPTYPE_AMANDAD_PATH $DUMPTYPE_CLIENT_USERNAME $DUMPTYPE_CLIENT_PORT $DUMPTYPE_SSH_KEYS $DUMPTYPE_AUTH $DUMPTYPE_EXCLUDE $DUMPTYPE_INCLUDE $DUMPTYPE_PRIORITY $DUMPTYPE_DUMPCYCLE $DUMPTYPE_MAXDUMPS $DUMPTYPE_MAXPROMOTEDAY $DUMPTYPE_BUMPPERCENT $DUMPTYPE_BUMPSIZE $DUMPTYPE_BUMPDAYS $DUMPTYPE_BUMPMULT $DUMPTYPE_STARTTIME $DUMPTYPE_STRATEGY $DUMPTYPE_ESTIMATELIST $DUMPTYPE_COMPRESS $DUMPTYPE_ENCRYPT $DUMPTYPE_SRV_DECRYPT_OPT $DUMPTYPE_CLNT_DECRYPT_OPT $DUMPTYPE_COMPRATE $DUMPTYPE_TAPE_SPLITSIZE $DUMPTYPE_FALLBACK_SPLITSIZE $DUMPTYPE_SPLIT_DISKBUFFER $DUMPTYPE_RECORD $DUMPTYPE_SKIP_INCR $DUMPTYPE_SKIP_FULL $DUMPTYPE_HOLDINGDISK $DUMPTYPE_KENCRYPT $DUMPTYPE_IGNORE $DUMPTYPE_INDEX $DUMPTYPE_APPLICATION $DUMPTYPE_SCRIPTLIST $DUMPTYPE_PROPERTY $DUMPTYPE_DATA_PATH $DUMPTYPE_ALLOW_SPLIT $DUMPTYPE_RECOVERY_LIMIT  $DUMPTYPE_DUMP_LIMIT);
-push @{$EXPORT_TAGS{"dumptype_key"}}, qw( $DUMPTYPE_COMMENT $DUMPTYPE_PROGRAM $DUMPTYPE_SRVCOMPPROG $DUMPTYPE_CLNTCOMPPROG $DUMPTYPE_SRV_ENCRYPT $DUMPTYPE_CLNT_ENCRYPT $DUMPTYPE_AMANDAD_PATH $DUMPTYPE_CLIENT_USERNAME $DUMPTYPE_CLIENT_PORT $DUMPTYPE_SSH_KEYS $DUMPTYPE_AUTH $DUMPTYPE_EXCLUDE $DUMPTYPE_INCLUDE $DUMPTYPE_PRIORITY $DUMPTYPE_DUMPCYCLE $DUMPTYPE_MAXDUMPS $DUMPTYPE_MAXPROMOTEDAY $DUMPTYPE_BUMPPERCENT $DUMPTYPE_BUMPSIZE $DUMPTYPE_BUMPDAYS $DUMPTYPE_BUMPMULT $DUMPTYPE_STARTTIME $DUMPTYPE_STRATEGY $DUMPTYPE_ESTIMATELIST $DUMPTYPE_COMPRESS $DUMPTYPE_ENCRYPT $DUMPTYPE_SRV_DECRYPT_OPT $DUMPTYPE_CLNT_DECRYPT_OPT $DUMPTYPE_COMPRATE $DUMPTYPE_TAPE_SPLITSIZE $DUMPTYPE_FALLBACK_SPLITSIZE $DUMPTYPE_SPLIT_DISKBUFFER $DUMPTYPE_RECORD $DUMPTYPE_SKIP_INCR $DUMPTYPE_SKIP_FULL $DUMPTYPE_HOLDINGDISK $DUMPTYPE_KENCRYPT $DUMPTYPE_IGNORE $DUMPTYPE_INDEX $DUMPTYPE_APPLICATION $DUMPTYPE_SCRIPTLIST $DUMPTYPE_PROPERTY $DUMPTYPE_DATA_PATH $DUMPTYPE_ALLOW_SPLIT $DUMPTYPE_RECOVERY_LIMIT  $DUMPTYPE_DUMP_LIMIT);
-      foreach (qw(  DUMPTYPE_COMMENT DUMPTYPE_PROGRAM DUMPTYPE_SRVCOMPPROG DUMPTYPE_CLNTCOMPPROG DUMPTYPE_SRV_ENCRYPT DUMPTYPE_CLNT_ENCRYPT DUMPTYPE_AMANDAD_PATH DUMPTYPE_CLIENT_USERNAME DUMPTYPE_CLIENT_PORT DUMPTYPE_SSH_KEYS DUMPTYPE_AUTH DUMPTYPE_EXCLUDE DUMPTYPE_INCLUDE DUMPTYPE_PRIORITY DUMPTYPE_DUMPCYCLE DUMPTYPE_MAXDUMPS DUMPTYPE_MAXPROMOTEDAY DUMPTYPE_BUMPPERCENT DUMPTYPE_BUMPSIZE DUMPTYPE_BUMPDAYS DUMPTYPE_BUMPMULT DUMPTYPE_STARTTIME DUMPTYPE_STRATEGY DUMPTYPE_ESTIMATELIST DUMPTYPE_COMPRESS DUMPTYPE_ENCRYPT DUMPTYPE_SRV_DECRYPT_OPT DUMPTYPE_CLNT_DECRYPT_OPT DUMPTYPE_COMPRATE DUMPTYPE_TAPE_SPLITSIZE DUMPTYPE_FALLBACK_SPLITSIZE DUMPTYPE_SPLIT_DISKBUFFER DUMPTYPE_RECORD DUMPTYPE_SKIP_INCR DUMPTYPE_SKIP_FULL DUMPTYPE_HOLDINGDISK DUMPTYPE_KENCRYPT DUMPTYPE_IGNORE DUMPTYPE_INDEX DUMPTYPE_APPLICATION DUMPTYPE_SCRIPTLIST DUMPTYPE_PROPERTY DUMPTYPE_DATA_PATH DUMPTYPE_ALLOW_SPLIT DUMPTYPE_RECOVERY_LIMIT  DUMPTYPE_DUMP_LIMIT)) {    $_dumptype_key_VALUES{$_} = $$_;      }  
+push @EXPORT_OK, qw( $DUMPTYPE_COMMENT $DUMPTYPE_PROGRAM $DUMPTYPE_SRVCOMPPROG $DUMPTYPE_CLNTCOMPPROG $DUMPTYPE_SRV_ENCRYPT $DUMPTYPE_CLNT_ENCRYPT $DUMPTYPE_AMANDAD_PATH $DUMPTYPE_CLIENT_USERNAME $DUMPTYPE_CLIENT_PORT $DUMPTYPE_SSH_KEYS $DUMPTYPE_AUTH $DUMPTYPE_EXCLUDE $DUMPTYPE_INCLUDE $DUMPTYPE_PRIORITY $DUMPTYPE_DUMPCYCLE $DUMPTYPE_MAXDUMPS $DUMPTYPE_MAXPROMOTEDAY $DUMPTYPE_BUMPPERCENT $DUMPTYPE_BUMPSIZE $DUMPTYPE_BUMPDAYS $DUMPTYPE_BUMPMULT $DUMPTYPE_STARTTIME $DUMPTYPE_STRATEGY $DUMPTYPE_ESTIMATELIST $DUMPTYPE_COMPRESS $DUMPTYPE_ENCRYPT $DUMPTYPE_SRV_DECRYPT_OPT $DUMPTYPE_CLNT_DECRYPT_OPT $DUMPTYPE_COMPRATE $DUMPTYPE_TAPE_SPLITSIZE $DUMPTYPE_FALLBACK_SPLITSIZE $DUMPTYPE_SPLIT_DISKBUFFER $DUMPTYPE_RECORD $DUMPTYPE_SKIP_INCR $DUMPTYPE_SKIP_FULL $DUMPTYPE_HOLDINGDISK $DUMPTYPE_KENCRYPT $DUMPTYPE_IGNORE $DUMPTYPE_INDEX $DUMPTYPE_APPLICATION $DUMPTYPE_SCRIPTLIST $DUMPTYPE_PROPERTY $DUMPTYPE_DATA_PATH $DUMPTYPE_ALLOW_SPLIT $DUMPTYPE_MAX_WARNINGS $DUMPTYPE_RECOVERY_LIMIT  $DUMPTYPE_DUMP_LIMIT);
+push @{$EXPORT_TAGS{"dumptype_key"}}, qw( $DUMPTYPE_COMMENT $DUMPTYPE_PROGRAM $DUMPTYPE_SRVCOMPPROG $DUMPTYPE_CLNTCOMPPROG $DUMPTYPE_SRV_ENCRYPT $DUMPTYPE_CLNT_ENCRYPT $DUMPTYPE_AMANDAD_PATH $DUMPTYPE_CLIENT_USERNAME $DUMPTYPE_CLIENT_PORT $DUMPTYPE_SSH_KEYS $DUMPTYPE_AUTH $DUMPTYPE_EXCLUDE $DUMPTYPE_INCLUDE $DUMPTYPE_PRIORITY $DUMPTYPE_DUMPCYCLE $DUMPTYPE_MAXDUMPS $DUMPTYPE_MAXPROMOTEDAY $DUMPTYPE_BUMPPERCENT $DUMPTYPE_BUMPSIZE $DUMPTYPE_BUMPDAYS $DUMPTYPE_BUMPMULT $DUMPTYPE_STARTTIME $DUMPTYPE_STRATEGY $DUMPTYPE_ESTIMATELIST $DUMPTYPE_COMPRESS $DUMPTYPE_ENCRYPT $DUMPTYPE_SRV_DECRYPT_OPT $DUMPTYPE_CLNT_DECRYPT_OPT $DUMPTYPE_COMPRATE $DUMPTYPE_TAPE_SPLITSIZE $DUMPTYPE_FALLBACK_SPLITSIZE $DUMPTYPE_SPLIT_DISKBUFFER $DUMPTYPE_RECORD $DUMPTYPE_SKIP_INCR $DUMPTYPE_SKIP_FULL $DUMPTYPE_HOLDINGDISK $DUMPTYPE_KENCRYPT $DUMPTYPE_IGNORE $DUMPTYPE_INDEX $DUMPTYPE_APPLICATION $DUMPTYPE_SCRIPTLIST $DUMPTYPE_PROPERTY $DUMPTYPE_DATA_PATH $DUMPTYPE_ALLOW_SPLIT $DUMPTYPE_MAX_WARNINGS $DUMPTYPE_RECOVERY_LIMIT  $DUMPTYPE_DUMP_LIMIT);
+      foreach (qw(  DUMPTYPE_COMMENT DUMPTYPE_PROGRAM DUMPTYPE_SRVCOMPPROG DUMPTYPE_CLNTCOMPPROG DUMPTYPE_SRV_ENCRYPT DUMPTYPE_CLNT_ENCRYPT DUMPTYPE_AMANDAD_PATH DUMPTYPE_CLIENT_USERNAME DUMPTYPE_CLIENT_PORT DUMPTYPE_SSH_KEYS DUMPTYPE_AUTH DUMPTYPE_EXCLUDE DUMPTYPE_INCLUDE DUMPTYPE_PRIORITY DUMPTYPE_DUMPCYCLE DUMPTYPE_MAXDUMPS DUMPTYPE_MAXPROMOTEDAY DUMPTYPE_BUMPPERCENT DUMPTYPE_BUMPSIZE DUMPTYPE_BUMPDAYS DUMPTYPE_BUMPMULT DUMPTYPE_STARTTIME DUMPTYPE_STRATEGY DUMPTYPE_ESTIMATELIST DUMPTYPE_COMPRESS DUMPTYPE_ENCRYPT DUMPTYPE_SRV_DECRYPT_OPT DUMPTYPE_CLNT_DECRYPT_OPT DUMPTYPE_COMPRATE DUMPTYPE_TAPE_SPLITSIZE DUMPTYPE_FALLBACK_SPLITSIZE DUMPTYPE_SPLIT_DISKBUFFER DUMPTYPE_RECORD DUMPTYPE_SKIP_INCR DUMPTYPE_SKIP_FULL DUMPTYPE_HOLDINGDISK DUMPTYPE_KENCRYPT DUMPTYPE_IGNORE DUMPTYPE_INDEX DUMPTYPE_APPLICATION DUMPTYPE_SCRIPTLIST DUMPTYPE_PROPERTY DUMPTYPE_DATA_PATH DUMPTYPE_ALLOW_SPLIT DUMPTYPE_MAX_WARNINGS DUMPTYPE_RECOVERY_LIMIT  DUMPTYPE_DUMP_LIMIT)) {      $_dumptype_key_VALUES{$_} = $$_;      }  
 #copy symbols in dumptype_key to getconf
 push @{$EXPORT_TAGS{"getconf"}},  @{$EXPORT_TAGS{"dumptype_key"}};
 
@@ -821,7 +823,7 @@ use Amanda::Config::FoldingHash;
 
 =pod
 
-Dumptype Parameters:       C<$DUMPTYPE_COMMENT> C<$DUMPTYPE_PROGRAM> C<$DUMPTYPE_SRVCOMPPROG> C<$DUMPTYPE_CLNTCOMPPROG> C<$DUMPTYPE_SRV_ENCRYPT> C<$DUMPTYPE_CLNT_ENCRYPT> C<$DUMPTYPE_AMANDAD_PATH> C<$DUMPTYPE_CLIENT_USERNAME> C<$DUMPTYPE_CLIENT_PORT> C<$DUMPTYPE_SSH_KEYS> C<$DUMPTYPE_AUTH> C<$DUMPTYPE_EXCLUDE> C<$DUMPTYPE_INCLUDE> C<$DUMPTYPE_PRIORITY> C<$DUMPTYPE_DUMPCYCLE> C<$DUMPTYPE_MAXDUMPS> C<$DUMPTYPE_MAXPROMOTEDAY> C<$DUMPTYPE_BUMPPERCENT> C<$DUMPTYPE_BUMPSIZE> C<$DUMPTYPE_BUMPDAYS> C<$DUMPTYPE_BUMPMULT> C<$DUMPTYPE_STARTTIME> C<$DUMPTYPE_STRATEGY> C<$DUMPTYPE_ESTIMATELIST> C<$DUMPTYPE_COMPRESS> C<$DUMPTYPE_ENCRYPT> C<$DUMPTYPE_SRV_DECRYPT_OPT> C<$DUMPTYPE_CLNT_DECRYPT_OPT> C<$DUMPTYPE_COMPRATE> C<$DUMPTYPE_TAPE_SPLITSIZE> C<$DUMPTYPE_FALLBACK_SPLITSIZE> C<$DUMPTYPE_SPLIT_DISKBUFFER> C<$DUMPTYPE_RECORD> C<$DUMPTYPE_SKIP_INCR> C<$DUMPTYPE_SKIP_FULL> C<$DUMPTYPE_HOLDINGDISK> C<$DUMPTYPE_KENCRYPT> C<$DUMPTYPE_IGNORE> C<$DUMPTYPE_INDEX> C<$DUMPTYPE_APPLICATION> C<$DUMPTYPE_SCRIPTLIST> C<$DUMPTYPE_PROPERTY> C<$DUMPTYPE_DATA_PATH> C<$DUMPTYPE_ALLOW_SPLIT> C<$DUMPTYPE_RECOVERY_LIMIT>  C<$DUMPTYPE_DUMP_LIMIT>
+Dumptype Parameters:       C<$DUMPTYPE_COMMENT> C<$DUMPTYPE_PROGRAM> C<$DUMPTYPE_SRVCOMPPROG> C<$DUMPTYPE_CLNTCOMPPROG> C<$DUMPTYPE_SRV_ENCRYPT> C<$DUMPTYPE_CLNT_ENCRYPT> C<$DUMPTYPE_AMANDAD_PATH> C<$DUMPTYPE_CLIENT_USERNAME> C<$DUMPTYPE_CLIENT_PORT> C<$DUMPTYPE_SSH_KEYS> C<$DUMPTYPE_AUTH> C<$DUMPTYPE_EXCLUDE> C<$DUMPTYPE_INCLUDE> C<$DUMPTYPE_PRIORITY> C<$DUMPTYPE_DUMPCYCLE> C<$DUMPTYPE_MAXDUMPS> C<$DUMPTYPE_MAXPROMOTEDAY> C<$DUMPTYPE_BUMPPERCENT> C<$DUMPTYPE_BUMPSIZE> C<$DUMPTYPE_BUMPDAYS> C<$DUMPTYPE_BUMPMULT> C<$DUMPTYPE_STARTTIME> C<$DUMPTYPE_STRATEGY> C<$DUMPTYPE_ESTIMATELIST> C<$DUMPTYPE_COMPRESS> C<$DUMPTYPE_ENCRYPT> C<$DUMPTYPE_SRV_DECRYPT_OPT> C<$DUMPTYPE_CLNT_DECRYPT_OPT> C<$DUMPTYPE_COMPRATE> C<$DUMPTYPE_TAPE_SPLITSIZE> C<$DUMPTYPE_FALLBACK_SPLITSIZE> C<$DUMPTYPE_SPLIT_DISKBUFFER> C<$DUMPTYPE_RECORD> C<$DUMPTYPE_SKIP_INCR> C<$DUMPTYPE_SKIP_FULL> C<$DUMPTYPE_HOLDINGDISK> C<$DUMPTYPE_KENCRYPT> C<$DUMPTYPE_IGNORE> C<$DUMPTYPE_INDEX> C<$DUMPTYPE_APPLICATION> C<$DUMPTYPE_SCRIPTLIST> C<$DUMPTYPE_PROPERTY> C<$DUMPTYPE_DATA_PATH> C<$DUMPTYPE_ALLOW_SPLIT> C<$DUMPTYPE_MAX_WARNINGS> C<$DUMPTYPE_RECOVERY_LIMIT>  C<$DUMPTYPE_DUMP_LIMIT>
 
 =cut
 
index 535869e4a9a2388638dc88b256061977ebb32fa0..e101eff2a0bfd0cef529143d21f8ddf73febae2c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 4780ce934d412c8a99aea00d5806acfdea923718..f3481a808c63cc11b35b361c9f9a1924d447140a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -145,7 +145,8 @@ APPLY(CNF_TAPER_PARALLEL_WRITE)\
 APPLY(CNF_RECOVERY_LIMIT) \
 APPLY(CNF_INTERACTIVITY) \
 APPLY(CNF_TAPERSCAN) \
-APPLY(CNF_EJECT_VOLUME)
+APPLY(CNF_EJECT_VOLUME) \
+APPLY(CNF_TMPDIR)
 
 amglue_add_enum_tag_fns(confparm_key);
 amglue_add_constants(FOR_ALL_CONFPARM_KEY, confparm_key);
@@ -215,6 +216,7 @@ APPLY(DUMPTYPE_SCRIPTLIST)\
 APPLY(DUMPTYPE_PROPERTY)\
 APPLY(DUMPTYPE_DATA_PATH)\
 APPLY(DUMPTYPE_ALLOW_SPLIT)\
+APPLY(DUMPTYPE_MAX_WARNINGS)\
 APPLY(DUMPTYPE_RECOVERY_LIMIT) \
 APPLY(DUMPTYPE_DUMP_LIMIT)
 
@@ -693,7 +695,7 @@ typedef char **val_t_strs;
 val_t_strs getconf_byname_strs(char *key, int str_needs_quotes) {
     val_t *val = getconf_byname(key);
     if (!val) return NULL;
-    return val_t_display_strs(val, str_needs_quotes);
+    return val_t_display_strs(val, str_needs_quotes, FALSE, FALSE);
 }
 %}
 
@@ -909,7 +911,7 @@ amglue_export_tag(init,
  * Miscellaneous
  */
 
-void dump_configuration(void);
+void dump_configuration(gboolean print_default, gboolean print_source);
 %newobject config_dir_relative;
 char *config_dir_relative(char *filename);
 char *taperalgo2str(taperalgo_t taperalgo);
@@ -934,5 +936,6 @@ sub string_to_boolean {
 
 amglue_export_ok(string_to_boolean);
 
+%newobject amandaify_property_name;
 gchar * amandaify_property_name(const gchar *name);
 amglue_export_ok(amandaify_property_name);
index e3692c95c117ca66478f703e02106b41adf5f359..0b8294a82958c2dceff186364cf6a5aeb4512fce 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -106,6 +106,9 @@ $VXDUMP = "@VXDUMP@";
 $VXRESTORE = "@VXRESTORE@";
 $XFSDUMP = "@XFSDUMP@";
 $XFSRESTORE = "@XFSRESTORE@";
+$NC = "@NC@";
+$NC6 = "@NC6@";
+$NETCAT = "@NETCAT@";
 
 # non-AC_SUBST'd constants
 
index 7af789ea8cbd706c9ba003c87f81113c7b804b1c..062c3a390f3cd1e6fa42e0a3c3f98a570f44c865 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f05e0dac9c71edb307a8c5406bfadb87acf95d11..1cd8e78bf06dcc7526fc568f8684f004ba5e2f7f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 0aa88fa420bd946b73c6666a4bb8278a607d92ef..dc849da8d2c62aa90a7428019de07aa7d437c94b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f6ba2f598df690ebe6a30fa795fe0fa13d922696..f6e432c2242b7da3577f8299be4de578152c6e07 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 7c51edf26e08a6b7b75fbb045dbf4e2f9ba5a456..852965d77e91f5761dc8c11dab27d959b02f19ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index cfbb55fda36a96565203b0d946da124ab46f5298..395ffebf77418e4f50a48cfa0982127ff80de6b4 100644 (file)
@@ -1510,21 +1510,23 @@ SWIG_Perl_SetModule(swig_module_info *module) {
 #define SWIGTYPE_p_DevicePropertyBase swig_types[1]
 #define SWIGTYPE_p_DirectTCPAddr swig_types[2]
 #define SWIGTYPE_p_DirectTCPConnection swig_types[3]
-#define SWIGTYPE_p_GSList swig_types[4]
-#define SWIGTYPE_p_GValue swig_types[5]
-#define SWIGTYPE_p_a_STRMAX__char swig_types[6]
-#define SWIGTYPE_p_char swig_types[7]
-#define SWIGTYPE_p_double swig_types[8]
-#define SWIGTYPE_p_dumpfile_t swig_types[9]
-#define SWIGTYPE_p_float swig_types[10]
-#define SWIGTYPE_p_guint swig_types[11]
-#define SWIGTYPE_p_guint32 swig_types[12]
-#define SWIGTYPE_p_guint64 swig_types[13]
-#define SWIGTYPE_p_int swig_types[14]
-#define SWIGTYPE_p_p_DirectTCPAddr swig_types[15]
-#define SWIGTYPE_p_unsigned_char swig_types[16]
-static swig_type_info *swig_types[18];
-static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0};
+#define SWIGTYPE_p_GCond swig_types[4]
+#define SWIGTYPE_p_GMutex swig_types[5]
+#define SWIGTYPE_p_GSList swig_types[6]
+#define SWIGTYPE_p_GValue swig_types[7]
+#define SWIGTYPE_p_a_STRMAX__char swig_types[8]
+#define SWIGTYPE_p_char swig_types[9]
+#define SWIGTYPE_p_double swig_types[10]
+#define SWIGTYPE_p_dumpfile_t swig_types[11]
+#define SWIGTYPE_p_float swig_types[12]
+#define SWIGTYPE_p_guint swig_types[13]
+#define SWIGTYPE_p_guint32 swig_types[14]
+#define SWIGTYPE_p_guint64 swig_types[15]
+#define SWIGTYPE_p_int swig_types[16]
+#define SWIGTYPE_p_p_DirectTCPAddr swig_types[17]
+#define SWIGTYPE_p_unsigned_char swig_types[18]
+static swig_type_info *swig_types[20];
+static swig_module_info swig_module = {swig_types, 19, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -1985,6 +1987,12 @@ SWIGINTERN gboolean Device_start(Device *self,DeviceAccessMode mode,char *label,
 SWIGINTERN gboolean Device_finish(Device *self){
            return device_finish(self);
        }
+SWIGINTERN guint64 Device_get_bytes_read(Device *self){
+           return device_get_bytes_read(self);
+       }
+SWIGINTERN guint64 Device_get_bytes_written(Device *self){
+           return device_get_bytes_written(self);
+       }
 SWIGINTERN gboolean Device_start_file(Device *self,dumpfile_t *jobInfo){
            return device_start_file(self, jobInfo);
        }
@@ -2029,6 +2037,18 @@ SWIGINTERN DirectTCPConnection *Device_accept(Device *self){
            }
            return conn;
        }
+SWIGINTERN DirectTCPConnection *Device_accept_with_cond(Device *self,GMutex *abort_mutex,GCond *abort_cond){
+           DirectTCPConnection *conn = NULL;
+           gboolean rv;
+
+           rv = device_accept_with_cond(self, &conn, abort_mutex, abort_cond);
+           if (!rv && conn) {
+               /* conn is ref'd for our convenience, but we don't want it */
+               g_object_unref(conn);
+               conn = NULL;
+           }
+           return conn;
+       }
 SWIGINTERN DirectTCPConnection *Device_connect(Device *self,gboolean for_writing,DirectTCPAddr *addrs){
            DirectTCPConnection *conn = NULL;
            gboolean rv;
@@ -2041,6 +2061,19 @@ SWIGINTERN DirectTCPConnection *Device_connect(Device *self,gboolean for_writing
            }
            return conn;
        }
+SWIGINTERN DirectTCPConnection *Device_connect_with_cond(Device *self,gboolean for_writing,DirectTCPAddr *addrs,GMutex *abort_mutex,GCond *abort_cond){
+           DirectTCPConnection *conn = NULL;
+           gboolean rv;
+
+           rv = device_connect_with_cond(self, for_writing, addrs, &conn,
+                                         abort_mutex, abort_cond);
+           if (!rv && conn) {
+               /* conn is ref'd for our convenience, but we don't want it */
+               g_object_unref(conn);
+               conn = NULL;
+           }
+           return conn;
+       }
 SWIGINTERN gboolean Device_use_connection(Device *self,DirectTCPConnection *conn){
            return device_use_connection(self, conn);
        }
@@ -2713,6 +2746,76 @@ XS(_wrap_Device_finish) {
 }
 
 
+XS(_wrap_Device_get_bytes_read) {
+  {
+    Device *arg1 = (Device *) 0 ;
+    void *argp1 = 0 ;
+    int res1 = 0 ;
+    int argvi = 0;
+    guint64 result;
+    dXSARGS;
+    
+    if ((items < 1) || (items > 1)) {
+      SWIG_croak("Usage: Device_get_bytes_read(self);");
+    }
+    res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Device, 0 |  0 );
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Device_get_bytes_read" "', argument " "1"" of type '" "Device *""'"); 
+    }
+    arg1 = (Device *)(argp1);
+    result = Device_get_bytes_read(arg1);
+    {
+      SV *for_stack;
+      SP += argvi; PUTBACK;
+      for_stack = sv_2mortal(amglue_newSVu64(result));
+      SPAGAIN; SP -= argvi;
+      ST(argvi) = for_stack;
+      argvi++;
+    }
+    
+    XSRETURN(argvi);
+  fail:
+    
+    SWIG_croak_null();
+  }
+}
+
+
+XS(_wrap_Device_get_bytes_written) {
+  {
+    Device *arg1 = (Device *) 0 ;
+    void *argp1 = 0 ;
+    int res1 = 0 ;
+    int argvi = 0;
+    guint64 result;
+    dXSARGS;
+    
+    if ((items < 1) || (items > 1)) {
+      SWIG_croak("Usage: Device_get_bytes_written(self);");
+    }
+    res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Device, 0 |  0 );
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Device_get_bytes_written" "', argument " "1"" of type '" "Device *""'"); 
+    }
+    arg1 = (Device *)(argp1);
+    result = Device_get_bytes_written(arg1);
+    {
+      SV *for_stack;
+      SP += argvi; PUTBACK;
+      for_stack = sv_2mortal(amglue_newSVu64(result));
+      SPAGAIN; SP -= argvi;
+      ST(argvi) = for_stack;
+      argvi++;
+    }
+    
+    XSRETURN(argvi);
+  fail:
+    
+    SWIG_croak_null();
+  }
+}
+
+
 XS(_wrap_Device_start_file) {
   {
     Device *arg1 = (Device *) 0 ;
@@ -3171,6 +3274,54 @@ XS(_wrap_Device_accept) {
 }
 
 
+XS(_wrap_Device_accept_with_cond) {
+  {
+    Device *arg1 = (Device *) 0 ;
+    GMutex *arg2 = (GMutex *) 0 ;
+    GCond *arg3 = (GCond *) 0 ;
+    void *argp1 = 0 ;
+    int res1 = 0 ;
+    void *argp2 = 0 ;
+    int res2 = 0 ;
+    void *argp3 = 0 ;
+    int res3 = 0 ;
+    int argvi = 0;
+    DirectTCPConnection *result = 0 ;
+    dXSARGS;
+    
+    if ((items < 3) || (items > 3)) {
+      SWIG_croak("Usage: Device_accept_with_cond(self,abort_mutex,abort_cond);");
+    }
+    res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Device, 0 |  0 );
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Device_accept_with_cond" "', argument " "1"" of type '" "Device *""'"); 
+    }
+    arg1 = (Device *)(argp1);
+    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_GMutex, 0 |  0 );
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Device_accept_with_cond" "', argument " "2"" of type '" "GMutex *""'"); 
+    }
+    arg2 = (GMutex *)(argp2);
+    res3 = SWIG_ConvertPtr(ST(2), &argp3,SWIGTYPE_p_GCond, 0 |  0 );
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Device_accept_with_cond" "', argument " "3"" of type '" "GCond *""'"); 
+    }
+    arg3 = (GCond *)(argp3);
+    result = (DirectTCPConnection *)Device_accept_with_cond(arg1,arg2,arg3);
+    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DirectTCPConnection, SWIG_OWNER | SWIG_SHADOW); argvi++ ;
+    
+    
+    
+    XSRETURN(argvi);
+  fail:
+    
+    
+    
+    SWIG_croak_null();
+  }
+}
+
+
 XS(_wrap_Device_connect) {
   {
     Device *arg1 = (Device *) 0 ;
@@ -3244,6 +3395,104 @@ XS(_wrap_Device_connect) {
     
     
     
+    SWIG_croak_null();
+  }
+}
+
+
+XS(_wrap_Device_connect_with_cond) {
+  {
+    Device *arg1 = (Device *) 0 ;
+    gboolean arg2 ;
+    DirectTCPAddr *arg3 = (DirectTCPAddr *) 0 ;
+    GMutex *arg4 = (GMutex *) 0 ;
+    GCond *arg5 = (GCond *) 0 ;
+    void *argp1 = 0 ;
+    int res1 = 0 ;
+    void *argp4 = 0 ;
+    int res4 = 0 ;
+    void *argp5 = 0 ;
+    int res5 = 0 ;
+    int argvi = 0;
+    DirectTCPConnection *result = 0 ;
+    dXSARGS;
+    
+    if ((items < 5) || (items > 5)) {
+      SWIG_croak("Usage: Device_connect_with_cond(self,for_writing,addrs,abort_mutex,abort_cond);");
+    }
+    res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Device, 0 |  0 );
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Device_connect_with_cond" "', argument " "1"" of type '" "Device *""'"); 
+    }
+    arg1 = (Device *)(argp1);
+    {
+      arg2 = SvTRUE(ST(1));
+    }
+    {
+      AV *addrs_av;
+      int num_addrs, i;
+      
+      if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV) {
+        SWIG_exception_fail(SWIG_TypeError, "must provide an arrayref of DirectTCPAddrs");
+      }
+      addrs_av = (AV *)SvRV(ST(2));
+      num_addrs = av_len(addrs_av)+1;
+      
+      arg3 = g_new0(DirectTCPAddr, num_addrs+1);
+      
+      for (i = 0; i < num_addrs; i++) {
+        SV **svp = av_fetch(addrs_av, i, 0);
+        AV *addr_av;
+        sockaddr_union addr;
+        IV port;
+        
+        if (!svp || !SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVAV
+          || av_len((AV *)SvRV(*svp))+1 != 2) {
+          SWIG_exception_fail(SWIG_TypeError, "each DirectTCPAddr must be a 2-element arrayref");
+        }
+        
+        addr_av = (AV *)SvRV(*svp);
+        
+        /* get address */
+        svp = av_fetch(addr_av, 0, 0);
+        if (!svp || !SvPOK(*svp) || !str_to_sockaddr(SvPV_nolen(*svp), &addr)) {
+          SWIG_exception_fail(SWIG_TypeError, "invalid IPv4 addr in address");
+        }
+        
+        /* get port */
+        svp = av_fetch(addr_av, 1, 0);
+        if (!svp || !SvIOK(*svp) || (port = SvIV(*svp)) <= 0 || port >= 65536) {
+          SWIG_exception_fail(SWIG_TypeError, "invalid port in address");
+        }
+        SU_SET_PORT(&addr, port);
+        
+        copy_sockaddr(arg3, &addr);
+      }
+    }
+    res4 = SWIG_ConvertPtr(ST(3), &argp4,SWIGTYPE_p_GMutex, 0 |  0 );
+    if (!SWIG_IsOK(res4)) {
+      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "Device_connect_with_cond" "', argument " "4"" of type '" "GMutex *""'"); 
+    }
+    arg4 = (GMutex *)(argp4);
+    res5 = SWIG_ConvertPtr(ST(4), &argp5,SWIGTYPE_p_GCond, 0 |  0 );
+    if (!SWIG_IsOK(res5)) {
+      SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "Device_connect_with_cond" "', argument " "5"" of type '" "GCond *""'"); 
+    }
+    arg5 = (GCond *)(argp5);
+    result = (DirectTCPConnection *)Device_connect_with_cond(arg1,arg2,arg3,arg4,arg5);
+    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DirectTCPConnection, SWIG_OWNER | SWIG_SHADOW); argvi++ ;
+    
+    
+    
+    
+    
+    XSRETURN(argvi);
+  fail:
+    
+    
+    
+    
+    
     SWIG_croak_null();
   }
 }
@@ -4409,6 +4658,8 @@ static swig_type_info _swigt__p_Device = {"_p_Device", "struct Device *|Device *
 static swig_type_info _swigt__p_DevicePropertyBase = {"_p_DevicePropertyBase", "DevicePropertyBase *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_DirectTCPAddr = {"_p_DirectTCPAddr", "DirectTCPAddr *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_DirectTCPConnection = {"_p_DirectTCPConnection", "struct DirectTCPConnection *|DirectTCPConnection *", 0, 0, (void*)"Amanda::Device::DirectTCPConnection", 0};
+static swig_type_info _swigt__p_GCond = {"_p_GCond", "GCond *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_GMutex = {"_p_GMutex", "GMutex *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_GSList = {"_p_GSList", "GSList *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_GValue = {"_p_GValue", "GValue *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_a_STRMAX__char = {"_p_a_STRMAX__char", "char (*)[STRMAX]|string_t *", 0, 0, (void*)0, 0};
@@ -4428,6 +4679,8 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_DevicePropertyBase,
   &_swigt__p_DirectTCPAddr,
   &_swigt__p_DirectTCPConnection,
+  &_swigt__p_GCond,
+  &_swigt__p_GMutex,
   &_swigt__p_GSList,
   &_swigt__p_GValue,
   &_swigt__p_a_STRMAX__char,
@@ -4447,6 +4700,8 @@ static swig_cast_info _swigc__p_Device[] = {  {&_swigt__p_Device, 0, 0, 0},{0, 0
 static swig_cast_info _swigc__p_DevicePropertyBase[] = {  {&_swigt__p_DevicePropertyBase, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_DirectTCPAddr[] = {  {&_swigt__p_DirectTCPAddr, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_DirectTCPConnection[] = {  {&_swigt__p_DirectTCPConnection, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_GCond[] = {  {&_swigt__p_GCond, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_GMutex[] = {  {&_swigt__p_GMutex, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_GSList[] = {  {&_swigt__p_GSList, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_GValue[] = {  {&_swigt__p_GValue, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_a_STRMAX__char[] = {  {&_swigt__p_a_STRMAX__char, 0, 0, 0},{0, 0, 0, 0}};
@@ -4466,6 +4721,8 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_DevicePropertyBase,
   _swigc__p_DirectTCPAddr,
   _swigc__p_DirectTCPConnection,
+  _swigc__p_GCond,
+  _swigc__p_GMutex,
   _swigc__p_GSList,
   _swigc__p_GValue,
   _swigc__p_a_STRMAX__char,
@@ -4507,6 +4764,8 @@ static swig_command_info swig_commands[] = {
 {"Amanda::Devicec::Device_read_label", _wrap_Device_read_label},
 {"Amanda::Devicec::Device_start", _wrap_Device_start},
 {"Amanda::Devicec::Device_finish", _wrap_Device_finish},
+{"Amanda::Devicec::Device_get_bytes_read", _wrap_Device_get_bytes_read},
+{"Amanda::Devicec::Device_get_bytes_written", _wrap_Device_get_bytes_written},
 {"Amanda::Devicec::Device_start_file", _wrap_Device_start_file},
 {"Amanda::Devicec::Device_write_block", _wrap_Device_write_block},
 {"Amanda::Devicec::Device_finish_file", _wrap_Device_finish_file},
@@ -4518,7 +4777,9 @@ static swig_command_info swig_commands[] = {
 {"Amanda::Devicec::Device_directtcp_supported", _wrap_Device_directtcp_supported},
 {"Amanda::Devicec::Device_listen", _wrap_Device_listen},
 {"Amanda::Devicec::Device_accept", _wrap_Device_accept},
+{"Amanda::Devicec::Device_accept_with_cond", _wrap_Device_accept_with_cond},
 {"Amanda::Devicec::Device_connect", _wrap_Device_connect},
+{"Amanda::Devicec::Device_connect_with_cond", _wrap_Device_connect_with_cond},
 {"Amanda::Devicec::Device_use_connection", _wrap_Device_use_connection},
 {"Amanda::Devicec::Device_write_from_connection", _wrap_Device_write_from_connection},
 {"Amanda::Devicec::Device_read_to_connection", _wrap_Device_read_to_connection},
index cdd0af6e1310df5d8201aa8d7b57595b8dd6c95e..e6b49c87a9429117f37a71cbcd25a9428d06a6ac 100644 (file)
@@ -125,6 +125,8 @@ sub DESTROY {
 *read_label = *Amanda::Devicec::Device_read_label;
 *start = *Amanda::Devicec::Device_start;
 *finish = *Amanda::Devicec::Device_finish;
+*get_bytes_read = *Amanda::Devicec::Device_get_bytes_read;
+*get_bytes_written = *Amanda::Devicec::Device_get_bytes_written;
 *start_file = *Amanda::Devicec::Device_start_file;
 *write_block = *Amanda::Devicec::Device_write_block;
 *finish_file = *Amanda::Devicec::Device_finish_file;
@@ -136,7 +138,9 @@ sub DESTROY {
 *directtcp_supported = *Amanda::Devicec::Device_directtcp_supported;
 *listen = *Amanda::Devicec::Device_listen;
 *accept = *Amanda::Devicec::Device_accept;
+*accept_with_cond = *Amanda::Devicec::Device_accept_with_cond;
 *connect = *Amanda::Devicec::Device_connect;
+*connect_with_cond = *Amanda::Devicec::Device_connect_with_cond;
 *use_connection = *Amanda::Devicec::Device_use_connection;
 *write_from_connection = *Amanda::Devicec::Device_write_from_connection;
 *read_to_connection = *Amanda::Devicec::Device_read_to_connection;
index 10d3f8b6540f0313d724f119636dd0513497331d..3c8be7e3ad4bdcf63567d39ca244de2fb1c22b53 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index d40031605f9bbb5955f3b74857ced43ba0212182..ea46300c9e3bc310df71bb46e402bcbe873c81bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -284,6 +284,16 @@ typedef struct Device {
            return device_finish(self);
        }
 
+       guint64
+       get_bytes_read() {
+           return device_get_bytes_read(self);
+       }
+
+       guint64
+       get_bytes_written() {
+           return device_get_bytes_written(self);
+       }
+
        gboolean
        start_file(dumpfile_t *jobInfo) {
            return device_start_file(self, jobInfo);
@@ -351,6 +361,21 @@ typedef struct Device {
            return conn;
        }
 
+       %newobject accept_with_cond; /* connection is already ref'd, so we own it */
+       DirectTCPConnection *
+       accept_with_cond(GMutex *abort_mutex, GCond *abort_cond) {
+           DirectTCPConnection *conn = NULL;
+           gboolean rv;
+
+           rv = device_accept_with_cond(self, &conn, abort_mutex, abort_cond);
+           if (!rv && conn) {
+               /* conn is ref'd for our convenience, but we don't want it */
+               g_object_unref(conn);
+               conn = NULL;
+           }
+           return conn;
+       }
+
        %newobject connect; /* connection is already ref'd, so we own it */
        DirectTCPConnection *
        connect(gboolean for_writing, DirectTCPAddr *addrs) {
@@ -366,6 +391,23 @@ typedef struct Device {
            return conn;
        }
 
+       %newobject connect_with_cond; /* connection is already ref'd, so we own it */
+       DirectTCPConnection *
+       connect_with_cond(gboolean for_writing, DirectTCPAddr *addrs,
+                         GMutex *abort_mutex, GCond *abort_cond) {
+           DirectTCPConnection *conn = NULL;
+           gboolean rv;
+
+           rv = device_connect_with_cond(self, for_writing, addrs, &conn,
+                                         abort_mutex, abort_cond);
+           if (!rv && conn) {
+               /* conn is ref'd for our convenience, but we don't want it */
+               g_object_unref(conn);
+               conn = NULL;
+           }
+           return conn;
+       }
+
        gboolean
        use_connection(DirectTCPConnection *conn) {
            return device_use_connection(self, conn);
index 230c2cba146c08fa25948567095269d10bec4a82..f80cc6e608fb02e7721216729db426987b1a12a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 9a6eb57b313b7f93ed9dc7c9a9c27f2bf3b9a319..da65ae597a26e6c9b4c7fcf6b64f97ee1a203c89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 7a6019dea6059b867d85a59f3b828bf6c2471941..c22e2a99d6c41afd809d4c5d2e85fe8097c83c23 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index a66f39ab03ed6c5e6edd5348b984ef0402cc859e..e21c1e084cd743305ef23e12804b750c4c61a520 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 25b2bc572e0c922f6cfcc5f7de2f573dd6c2535f..faa12da99f482416522c05e51ebbc7443c2912af 100644 (file)
@@ -1509,19 +1509,19 @@ SWIG_Perl_SetModule(swig_module_info *module) {
 #define SWIGTYPE_p_GSList swig_types[0]
 #define SWIGTYPE_p_a_STRMAX__char swig_types[1]
 #define SWIGTYPE_p_a_dle_s swig_types[2]
-#define SWIGTYPE_p_char swig_types[3]
-#define SWIGTYPE_p_data_path_t swig_types[4]
-#define SWIGTYPE_p_dle_t swig_types[5]
-#define SWIGTYPE_p_double swig_types[6]
-#define SWIGTYPE_p_dumpfile_t swig_types[7]
-#define SWIGTYPE_p_estimatelist_t swig_types[8]
-#define SWIGTYPE_p_float swig_types[9]
-#define SWIGTYPE_p_int swig_types[10]
-#define SWIGTYPE_p_levellist_t swig_types[11]
-#define SWIGTYPE_p_off_t swig_types[12]
-#define SWIGTYPE_p_proplist_t swig_types[13]
-#define SWIGTYPE_p_scriptlist_t swig_types[14]
-#define SWIGTYPE_p_sl_t swig_types[15]
+#define SWIGTYPE_p_am_sl_t swig_types[3]
+#define SWIGTYPE_p_char swig_types[4]
+#define SWIGTYPE_p_data_path_t swig_types[5]
+#define SWIGTYPE_p_dle_t swig_types[6]
+#define SWIGTYPE_p_double swig_types[7]
+#define SWIGTYPE_p_dumpfile_t swig_types[8]
+#define SWIGTYPE_p_estimatelist_t swig_types[9]
+#define SWIGTYPE_p_float swig_types[10]
+#define SWIGTYPE_p_int swig_types[11]
+#define SWIGTYPE_p_levellist_t swig_types[12]
+#define SWIGTYPE_p_off_t swig_types[13]
+#define SWIGTYPE_p_proplist_t swig_types[14]
+#define SWIGTYPE_p_scriptlist_t swig_types[15]
 #define SWIGTYPE_p_unsigned_char swig_types[16]
 static swig_type_info *swig_types[18];
 static swig_module_info swig_module = {swig_types, 17, 0, 0, 0, 0};
@@ -4213,7 +4213,7 @@ XS(_wrap_C_from_string) {
     }
     arg1 = (char *)(buf1);
     result = (dumpfile_t *)C_from_string((char const *)arg1);
-    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_dumpfile_t, SWIG_OWNER | SWIG_SHADOW); argvi++ ;
+    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_dumpfile_t, 0 | SWIG_SHADOW); argvi++ ;
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
     XSRETURN(argvi);
   fail:
@@ -5708,7 +5708,7 @@ XS(_wrap_HeaderXML_auth_get) {
 XS(_wrap_HeaderXML_exclude_file_set) {
   {
     dle_t *arg1 = (dle_t *) 0 ;
-    sl_t *arg2 = (sl_t *) 0 ;
+    am_sl_t *arg2 = (am_sl_t *) 0 ;
     void *argp1 = 0 ;
     int res1 = 0 ;
     void *argp2 = 0 ;
@@ -5724,11 +5724,11 @@ XS(_wrap_HeaderXML_exclude_file_set) {
       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_exclude_file_set" "', argument " "1"" of type '" "dle_t *""'"); 
     }
     arg1 = (dle_t *)(argp1);
-    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_sl_t, SWIG_POINTER_DISOWN |  0 );
+    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_am_sl_t, SWIG_POINTER_DISOWN |  0 );
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_exclude_file_set" "', argument " "2"" of type '" "sl_t *""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_exclude_file_set" "', argument " "2"" of type '" "am_sl_t *""'"); 
     }
-    arg2 = (sl_t *)(argp2);
+    arg2 = (am_sl_t *)(argp2);
     if (arg1) (arg1)->exclude_file = arg2;
     ST(argvi) = sv_newmortal();
     
@@ -5748,7 +5748,7 @@ XS(_wrap_HeaderXML_exclude_file_get) {
     void *argp1 = 0 ;
     int res1 = 0 ;
     int argvi = 0;
-    sl_t *result = 0 ;
+    am_sl_t *result = 0 ;
     dXSARGS;
     
     if ((items < 1) || (items > 1)) {
@@ -5759,8 +5759,8 @@ XS(_wrap_HeaderXML_exclude_file_get) {
       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_exclude_file_get" "', argument " "1"" of type '" "dle_t *""'"); 
     }
     arg1 = (dle_t *)(argp1);
-    result = (sl_t *) ((arg1)->exclude_file);
-    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sl_t, 0 | 0); argvi++ ;
+    result = (am_sl_t *) ((arg1)->exclude_file);
+    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_am_sl_t, 0 | 0); argvi++ ;
     
     XSRETURN(argvi);
   fail:
@@ -5773,7 +5773,7 @@ XS(_wrap_HeaderXML_exclude_file_get) {
 XS(_wrap_HeaderXML_exclude_list_set) {
   {
     dle_t *arg1 = (dle_t *) 0 ;
-    sl_t *arg2 = (sl_t *) 0 ;
+    am_sl_t *arg2 = (am_sl_t *) 0 ;
     void *argp1 = 0 ;
     int res1 = 0 ;
     void *argp2 = 0 ;
@@ -5789,11 +5789,11 @@ XS(_wrap_HeaderXML_exclude_list_set) {
       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_exclude_list_set" "', argument " "1"" of type '" "dle_t *""'"); 
     }
     arg1 = (dle_t *)(argp1);
-    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_sl_t, SWIG_POINTER_DISOWN |  0 );
+    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_am_sl_t, SWIG_POINTER_DISOWN |  0 );
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_exclude_list_set" "', argument " "2"" of type '" "sl_t *""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_exclude_list_set" "', argument " "2"" of type '" "am_sl_t *""'"); 
     }
-    arg2 = (sl_t *)(argp2);
+    arg2 = (am_sl_t *)(argp2);
     if (arg1) (arg1)->exclude_list = arg2;
     ST(argvi) = sv_newmortal();
     
@@ -5813,7 +5813,7 @@ XS(_wrap_HeaderXML_exclude_list_get) {
     void *argp1 = 0 ;
     int res1 = 0 ;
     int argvi = 0;
-    sl_t *result = 0 ;
+    am_sl_t *result = 0 ;
     dXSARGS;
     
     if ((items < 1) || (items > 1)) {
@@ -5824,8 +5824,8 @@ XS(_wrap_HeaderXML_exclude_list_get) {
       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_exclude_list_get" "', argument " "1"" of type '" "dle_t *""'"); 
     }
     arg1 = (dle_t *)(argp1);
-    result = (sl_t *) ((arg1)->exclude_list);
-    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sl_t, 0 | 0); argvi++ ;
+    result = (am_sl_t *) ((arg1)->exclude_list);
+    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_am_sl_t, 0 | 0); argvi++ ;
     
     XSRETURN(argvi);
   fail:
@@ -5838,7 +5838,7 @@ XS(_wrap_HeaderXML_exclude_list_get) {
 XS(_wrap_HeaderXML_include_file_set) {
   {
     dle_t *arg1 = (dle_t *) 0 ;
-    sl_t *arg2 = (sl_t *) 0 ;
+    am_sl_t *arg2 = (am_sl_t *) 0 ;
     void *argp1 = 0 ;
     int res1 = 0 ;
     void *argp2 = 0 ;
@@ -5854,11 +5854,11 @@ XS(_wrap_HeaderXML_include_file_set) {
       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_include_file_set" "', argument " "1"" of type '" "dle_t *""'"); 
     }
     arg1 = (dle_t *)(argp1);
-    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_sl_t, SWIG_POINTER_DISOWN |  0 );
+    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_am_sl_t, SWIG_POINTER_DISOWN |  0 );
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_include_file_set" "', argument " "2"" of type '" "sl_t *""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_include_file_set" "', argument " "2"" of type '" "am_sl_t *""'"); 
     }
-    arg2 = (sl_t *)(argp2);
+    arg2 = (am_sl_t *)(argp2);
     if (arg1) (arg1)->include_file = arg2;
     ST(argvi) = sv_newmortal();
     
@@ -5878,7 +5878,7 @@ XS(_wrap_HeaderXML_include_file_get) {
     void *argp1 = 0 ;
     int res1 = 0 ;
     int argvi = 0;
-    sl_t *result = 0 ;
+    am_sl_t *result = 0 ;
     dXSARGS;
     
     if ((items < 1) || (items > 1)) {
@@ -5889,8 +5889,8 @@ XS(_wrap_HeaderXML_include_file_get) {
       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_include_file_get" "', argument " "1"" of type '" "dle_t *""'"); 
     }
     arg1 = (dle_t *)(argp1);
-    result = (sl_t *) ((arg1)->include_file);
-    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sl_t, 0 | 0); argvi++ ;
+    result = (am_sl_t *) ((arg1)->include_file);
+    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_am_sl_t, 0 | 0); argvi++ ;
     
     XSRETURN(argvi);
   fail:
@@ -5903,7 +5903,7 @@ XS(_wrap_HeaderXML_include_file_get) {
 XS(_wrap_HeaderXML_include_list_set) {
   {
     dle_t *arg1 = (dle_t *) 0 ;
-    sl_t *arg2 = (sl_t *) 0 ;
+    am_sl_t *arg2 = (am_sl_t *) 0 ;
     void *argp1 = 0 ;
     int res1 = 0 ;
     void *argp2 = 0 ;
@@ -5919,11 +5919,11 @@ XS(_wrap_HeaderXML_include_list_set) {
       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_include_list_set" "', argument " "1"" of type '" "dle_t *""'"); 
     }
     arg1 = (dle_t *)(argp1);
-    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_sl_t, SWIG_POINTER_DISOWN |  0 );
+    res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_am_sl_t, SWIG_POINTER_DISOWN |  0 );
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_include_list_set" "', argument " "2"" of type '" "sl_t *""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "HeaderXML_include_list_set" "', argument " "2"" of type '" "am_sl_t *""'"); 
     }
-    arg2 = (sl_t *)(argp2);
+    arg2 = (am_sl_t *)(argp2);
     if (arg1) (arg1)->include_list = arg2;
     ST(argvi) = sv_newmortal();
     
@@ -5943,7 +5943,7 @@ XS(_wrap_HeaderXML_include_list_get) {
     void *argp1 = 0 ;
     int res1 = 0 ;
     int argvi = 0;
-    sl_t *result = 0 ;
+    am_sl_t *result = 0 ;
     dXSARGS;
     
     if ((items < 1) || (items > 1)) {
@@ -5954,8 +5954,8 @@ XS(_wrap_HeaderXML_include_list_get) {
       SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "HeaderXML_include_list_get" "', argument " "1"" of type '" "dle_t *""'"); 
     }
     arg1 = (dle_t *)(argp1);
-    result = (sl_t *) ((arg1)->include_list);
-    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sl_t, 0 | 0); argvi++ ;
+    result = (am_sl_t *) ((arg1)->include_list);
+    ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_am_sl_t, 0 | 0); argvi++ ;
     
     XSRETURN(argvi);
   fail:
@@ -6559,6 +6559,7 @@ XS(_wrap_delete_HeaderXML) {
 static swig_type_info _swigt__p_GSList = {"_p_GSList", "GSList *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_a_STRMAX__char = {"_p_a_STRMAX__char", "char (*)[STRMAX]|string_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_a_dle_s = {"_p_a_dle_s", "struct a_dle_s *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_am_sl_t = {"_p_am_sl_t", "am_sl_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_char = {"_p_char", "gchar *|char *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_data_path_t = {"_p_data_path_t", "data_path_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_dle_t = {"_p_dle_t", "dle_t *", 0, 0, (void*)"Amanda::Header::HeaderXML", 0};
@@ -6571,13 +6572,13 @@ static swig_type_info _swigt__p_levellist_t = {"_p_levellist_t", "levellist_t *"
 static swig_type_info _swigt__p_off_t = {"_p_off_t", "off_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_proplist_t = {"_p_proplist_t", "proplist_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_scriptlist_t = {"_p_scriptlist_t", "scriptlist_t *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_sl_t = {"_p_sl_t", "sl_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "guchar *|unsigned char *", 0, 0, (void*)0, 0};
 
 static swig_type_info *swig_type_initial[] = {
   &_swigt__p_GSList,
   &_swigt__p_a_STRMAX__char,
   &_swigt__p_a_dle_s,
+  &_swigt__p_am_sl_t,
   &_swigt__p_char,
   &_swigt__p_data_path_t,
   &_swigt__p_dle_t,
@@ -6590,13 +6591,13 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_off_t,
   &_swigt__p_proplist_t,
   &_swigt__p_scriptlist_t,
-  &_swigt__p_sl_t,
   &_swigt__p_unsigned_char,
 };
 
 static swig_cast_info _swigc__p_GSList[] = {  {&_swigt__p_GSList, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_a_STRMAX__char[] = {  {&_swigt__p_a_STRMAX__char, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_a_dle_s[] = {  {&_swigt__p_a_dle_s, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_am_sl_t[] = {  {&_swigt__p_am_sl_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_char[] = {  {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_data_path_t[] = {  {&_swigt__p_data_path_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_dle_t[] = {  {&_swigt__p_dle_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -6609,13 +6610,13 @@ static swig_cast_info _swigc__p_levellist_t[] = {  {&_swigt__p_levellist_t, 0, 0
 static swig_cast_info _swigc__p_off_t[] = {  {&_swigt__p_off_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_proplist_t[] = {  {&_swigt__p_proplist_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_scriptlist_t[] = {  {&_swigt__p_scriptlist_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_sl_t[] = {  {&_swigt__p_sl_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_unsigned_char[] = {  {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}};
 
 static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_GSList,
   _swigc__p_a_STRMAX__char,
   _swigc__p_a_dle_s,
+  _swigc__p_am_sl_t,
   _swigc__p_char,
   _swigc__p_data_path_t,
   _swigc__p_dle_t,
@@ -6628,7 +6629,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_off_t,
   _swigc__p_proplist_t,
   _swigc__p_scriptlist_t,
-  _swigc__p_sl_t,
   _swigc__p_unsigned_char,
 };
 
index d8cc69275945307f770f3c848d360a8a3f6d6801..3b01eacbd8036b78c166269f0dc63565cf4c2afc 100644 (file)
@@ -482,7 +482,11 @@ sub from_string {
 sub get_dle {
     my $self = shift;
 
-    return Amanda::Header::HeaderXML->new($self->{'dle_str'});
+    if ($self->{'dle_str'}) {
+       return Amanda::Header::HeaderXML->new($self->{'dle_str'});
+    } else {
+       return undef;
+    }
 }
 
 package Amanda::Header::Header;
index 40898af673353336ed5e9f477322e7fb3830d2e2..8d4569ff800d35eb79482ad5cfdbc0befef933c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index a7d391b630246cf6c0de37835f12729e2e3c1c57..f249d862170aeaab2fdcd775f91ea74ce7c08aec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -123,7 +123,6 @@ typedef struct {
     }
 } dumpfile_t;
 
-%newobject C_from_string;
 %inline %{
 static dumpfile_t *C_from_string(const char *string) {
     dumpfile_t *result = g_new(dumpfile_t, 1);
@@ -151,7 +150,11 @@ sub from_string {
 sub get_dle {
     my $self = shift;
 
-    return Amanda::Header::HeaderXML->new($self->{'dle_str'});
+    if ($self->{'dle_str'}) {
+       return Amanda::Header::HeaderXML->new($self->{'dle_str'});
+    } else {
+       return undef;
+    }
 }
 
 package Amanda::Header::Header;
@@ -192,10 +195,10 @@ typedef struct {
     int     record;
     int     create_index;
     char   *auth;
-    sl_t   *exclude_file;
-    sl_t   *exclude_list;
-    sl_t   *include_file;
-    sl_t   *include_list;
+    am_sl_t   *exclude_file;
+    am_sl_t   *exclude_list;
+    am_sl_t   *include_file;
+    am_sl_t   *include_list;
     int     exclude_optional;
     int     include_optional;
     proplist_t application_property;
index a0108fc2b017441e4bd62e25132fac8df9a78682..d29345db2887d98d0a07bfac308ccd5cd8831be9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 34ede1c968495bdd17498b535ceef14f2fe9ca12..945cffe1d01dce260051cae892a7ee6844a391c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index f80b8f105745befa5a7648681d8fae897c809070..49459c0989a4efa27de251b45ea62aa7297f0c00 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index cc9b5d869eccab38420b44864dc5a56cff34cc9e..358501e629a8fb10c5acf26df32f04703773d5dd 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 25fe79de687e1740bfb44f2415e8e63a03ca203e..23a234187a21a085b58e3bec66de6300295ab312 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 648d969597f9703f4a6a4ec4d0a5628038e48812..f7b70aa81a94c2cbe7c1a0d0798581907833609e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 2b67216220e9e34e3b1cf3ea0d271e769a4c7591..33a273f4b9e6c43f9f3c36b04116981771bbeee8 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f3a6904ecc267356c2b3ad30e4553ea6c603f96e..2ba81a7dd8347702fc1faa7e034dd07b7eb8e885 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 851dc6c43f898020327f57395e3ba71ec62e120a..21e2eccb79881439d9ec7ab3ff782b54bf195dde 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010, 2011 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 9c1286cc8278d6c61dd8d8fe44f8c979c120c761..450d5a45c519fa15dfb7ba0cc62b1920a836bb5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 07047a0de80285a0dd0f87489068628b2df37421..8d628702ea4c92a492a8378293f3e4e97dcf7a25 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index a47e9c51288068f20c6d6c7d15417a02c0d9f66b..3504f2ba4299bf34430ce6cc39407bb47d155d9b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 6b66c457b09f18d771e6b02a8978cc7116207a04..457ff09c42301e6339e5deeb732c1d183782a26f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 27d0a51d61788ae74a67389ad13a67cd0f76bbc6..0efed0fe046b66acf9a4f7b60583759fd577bb1f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index b460c699f00242e14c33092140d0cde5c9814fb1..da63d4e7ff723bdf528df1dcdc7bf8ec03796043 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 0d94604ddaef4bc60adf32fd22501f54a491dbb0..a3e02489834c116ba39e1730f72ddde4d9a8c3b2 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 8a03a47b767029380c94afaa33875174d3dad119..01c6a7b8f5300485293e15260795392128bd4b1c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7531421dd1c7b5a5aa259faded153a054eb1ee8a..39b3c20cd58010d6156bfaf530b14b07f260884c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This library is free software; you can redistribute it and/or modify it
 # under the terms of the GNU Lesser General Public License version 2.1 as
@@ -233,7 +233,7 @@ sub get_xfer_src {
            unless exists $params{$rq_param};
     }
 
-    die "Clerk is already busy" if $self->{'xfer_state'};
+    confess "Clerk is already busy" if $self->{'xfer_state'};
 
     # set up a new xfer_state
     my $xfer_state = $self->{'xfer_state'} = {
@@ -267,8 +267,8 @@ sub start_recovery {
            unless exists $params{$rq_param};
     }
 
-    die "no xfer is in progress" unless $self->{'xfer_state'};
-    die "get_xfer_src has not finished"
+    confess "no xfer is in progress" unless $self->{'xfer_state'};
+    confess "get_xfer_src has not finished"
        if defined $self->{'xfer_state'}->{'xfer_src_cb'};
 
     my $xfer_state = $self->{'xfer_state'};
@@ -302,7 +302,7 @@ sub quit {
     my %params = @_;
     my $finished_cb = $params{'finished_cb'};
 
-    die "Cannot quit a Clerk while a transfer is in progress"
+    confess "Cannot quit a Clerk while a transfer is in progress"
        if $self->{'xfer_state'};
 
     my $steps = define_steps 
@@ -340,7 +340,7 @@ sub _xmsg_part_done {
     my $next_label = $xfer_state->{'next_part'}->{'label'};
     my $next_filenum = $xfer_state->{'next_part'}->{'filenum'};
 
-    die "read incorrect filenum"
+    confess "read incorrect filenum"
        unless $next_filenum == $msg->{'fileno'};
     $self->dbg("done reading file $next_filenum on '$next_label'");
 
@@ -374,6 +374,7 @@ sub _xmsg_done {
     return $xfer_state->{'recovery_cb'}->(
        result => $result,
        errors => $xfer_state->{'errors'},
+       bytes_read => $xfer_state->{'xfer_src'}->get_bytes_read()
     );
 }
 
@@ -416,7 +417,7 @@ sub _maybe_start_part {
        # first, see if anything remains to be done
        if (!exists $xfer_state->{'dump'}{'parts'}[$xfer_state->{'next_part_idx'}]) {
            # this should not happen until the xfer is started..
-           die "xfer should be running already"
+           confess "xfer should be running already"
                unless $xfer_state->{'xfer'};
 
            # tell the source to generate EOF
index a3100623c536562dc4f363ce0af3f9a223557f37..22809beeee465a90f19a82b9342796500c9359f1 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This library is free software; you can redistribute it and/or modify it
 # under the terms of the GNU Lesser General Public License version 2.1 as
@@ -395,61 +395,121 @@ sub make_plan_from_filelist {
            unless exists $params{$rq_param};
     }
 
-    # This is similarly tricky - in this case, we search for dumps matching
-    # both the dumpspec and the labels, filter that down to just the parts we
-    # want, and then check that only one dump remains.  Then we look up that
-    # dump.
-
-    my @labels;
-    my %files;
-    my @filelist = @{$params{'filelist'}};
-    while (@filelist) {
-       my $label = shift @filelist;
-       push @labels, $label;
-       $files{$label} = shift @filelist;
-    }
+    my $steps = define_steps
+       cb_ref => \$params{'plan_cb'};
 
-    my @parts = Amanda::DB::Catalog::get_parts(
-           $params{'dumpspec'}? (dumpspecs => [ $params{'dumpspec'} ]) : (),
-           labels => [ @labels ]);
+    step get_inventory => sub {
+       if (defined $params{'chg'} and $params{'chg'}->have_inventory()) {
+           return $params{'chg'}->inventory( inventory_cb => $steps->{'got_inventory'});
+       } else {
+           return $steps->{'got_inventory'}->(undef, undef);
+       }
+    };
+    step got_inventory => sub {
+       my ($err, $inventory) = @_;
+
+       # This is similarly tricky - in this case, we search for dumps matching
+       # both the dumpspec and the labels, filter that down to just the parts we
+       # want, and then check that only one dump remains.  Then we look up that
+       # dump.
+
+       my @labels;
+       my %files;
+       my @filelist = @{$params{'filelist'}};
+       while (@filelist) {
+           my $label = shift @filelist;
+           push @labels, $label;
+           $files{$label} = shift @filelist;
+       }
 
-    # filter down to the parts that match filelist (using %files)
-    @parts = grep {
-       my $filenum = $_->{'filenum'};
-       grep { $_ == $filenum } @{$files{$_->{'label'}}};
-    } @parts;
+       my @parts = Amanda::DB::Catalog::get_parts(
+               $params{'dumpspec'}? (dumpspecs => [ $params{'dumpspec'} ]) : (),
+               labels => [ @labels ]);
 
-    # extract the dumps, using a hash (on the perl identity of the dump) to
-    # ensure uniqueness
-    my %dumps = map { my $d = $_->{'dump'}; ($d, $d) } @parts;
-    my @dumps = values %dumps;
+       # filter down to the parts that match filelist (using %files)
+       @parts = grep {
+           my $filenum = $_->{'filenum'};
+           grep { $_ == $filenum } @{$files{$_->{'label'}}};
+       } @parts;
 
-    if (!@dumps) {
-       return $params{'plan_cb'}->(
+       # extract the dumps, using a hash (on the perl identity of the dump) to
+       # ensure uniqueness
+       my %dumps = map { my $d = $_->{'dump'}; ($d, $d) } @parts;
+       my @dumps = values %dumps;
+
+       if (!@dumps) {
+           return $params{'plan_cb'}->(
                "Specified file list does not match dumpspec");
-    } elsif (@dumps > 1) {
-       return $params{'plan_cb'}->(
-               "Specified file list matches multiple dumps; cannot continue recovery");
-    }
+       } elsif (@dumps > 1) {
+           # Check if they are all for the same dump
+           my $dump_timestamp = $dumps[0]->{'dump_timestamp'};
+           my $hostname = $dumps[0]->{'hostname'};
+           my $diskname = $dumps[0]->{'diskname'};
+           my $level = $dumps[0]->{'level'};
+           my $orig_kb = $dumps[0]->{'orig_kb'};
+
+           foreach my $dump (@dumps) {
+               if ($dump_timestamp != $dump->{'dump_timestamp'} ||
+                   $hostname ne $dump->{'hostname'} ||
+                   $diskname ne $dump->{'diskname'} ||
+                   $level != $dump->{'level'} ||
+                   $orig_kb != $dump->{'orig_kb'}) {
+                   return $params{'plan_cb'}->(
+                       "Specified file list matches multiple dumps; cannot continue recovery");
+               }
+           }
 
-    # now, because of the weak linking used by Amanda::DB::Catalog, we need to
-    # re-query for this dump.  If we don't do this, the parts will all be
-    # garbage-collected when we hand back the plan.  This is, chartiably, "less than
-    # ideal".  Note that this has the side-effect of filling in any parts of the
-    # dump that were missing from the filelist.
-    @dumps = Amanda::DB::Catalog::get_dumps(
-       hostname => $dumps[0]->{'hostname'},
-       diskname => $dumps[0]->{'diskname'},
-       level => $dumps[0]->{'level'},
-       dump_timestamp => $dumps[0]->{'dump_timestamp'},
-       write_timestamp => $dumps[0]->{'write_timestamp'},
-       dumpspecs => $params{'dumpspecs'});
-
-    # sanity check
-    die unless @dumps;
-    $self->{'dumps'} = [ $dumps[0] ];
+           # I would prefer the Planner to return alternate dump and the Clerk
+           # choose which one to use
+           if (defined $inventory) {
+               for my $dump (@dumps) {
+                   my $all_part_found = 0;
+                   my $part_found = 1;
+                   for my $part (@{$dump->{'parts'}}) {
+                       next if !defined $part;
+                       my $found = 0;
+                       foreach my $sl (@$inventory) {
+                           if (defined $sl->{'label'} and
+                               $sl->{'label'} eq $part->{'label'}) {
+                               $found = 1;
+                               last;
+                           }
+                       }
+                       if ($found == 0) {
+                           $part_found = 0;
+                           last;
+                       }
+                   }
+                   if ($part_found == 1) {
+                       @dumps = $dumps[0];
+                       last;
+                   }
+               }
+               # the first one will be used
+           } else {
+               # will uses the first dump.
+           }
+       }
 
-    Amanda::MainLoop::call_later($params{'plan_cb'}, undef, $self);
+       # now, because of the weak linking used by Amanda::DB::Catalog, we need to
+       # re-query for this dump.  If we don't do this, the parts will all be
+       # garbage-collected when we hand back the plan.  This is, chartiably, "less
+       # than ideal".  Note that this has the side-effect of filling in any parts of
+       # the dump that were missing from the filelist.
+       @dumps = Amanda::DB::Catalog::get_dumps(
+           hostname => $dumps[0]->{'hostname'},
+           diskname => $dumps[0]->{'diskname'},
+           level => $dumps[0]->{'level'},
+           dump_timestamp => $dumps[0]->{'dump_timestamp'},
+           write_timestamp => $dumps[0]->{'write_timestamp'},
+           dumpspecs => $params{'dumpspecs'});
+
+       # sanity check
+       confess "no dumps" unless @dumps;
+       $self->{'dumps'} = [ $dumps[0] ];
+
+       Amanda::MainLoop::call_later($params{'plan_cb'}, undef, $self);
+    };
 }
 
 sub split_dumps_per_part {
index 5a9fa729dc8ce5c047c9cef3770e4bf8e0fb750c..96ec8cf2c9de7f61843dedd282e89315c5dd660f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -283,8 +283,9 @@ sub find_volume {
        # check if label is in the inventory
        for my $i (0..(scalar(@$inventory)-1)) {
            my $sl = $inventory->[$i];
-           if (defined $sl->{'label'} &&
-               $sl->{'label'} eq $label) {
+           if (defined $sl->{'label'} and
+               $sl->{'label'} eq $label and
+               !defined $seen{$sl->{'slot'}}) {
                $slot_scanned = $sl->{'slot'};
                if ($sl->{'reserved'}) {
                    return $steps->{'handle_error'}->(
@@ -521,7 +522,7 @@ sub find_volume {
                    $scan_method = $self->{'scan_conf'}->{$err->{'reason'}};
                }
            } else {
-               die("error not defined");
+               confess("error not defined");
                $scan_method = SCAN_ASK_POLL;
            }
        }
@@ -561,7 +562,7 @@ sub find_volume {
        } elsif ($scan_method == SCAN_CONTINUE) {
            return $continue_cb->($err, undef);
        } else {
-           die("Invalid SCAN_* value:$err:$err->{'reason'}:$scan_method");
+           confess("Invalid SCAN_* value:$err:$err->{'reason'}:$scan_method");
        }
     };
 
@@ -591,7 +592,6 @@ sub find_volume {
        $interactivity_running = 0;
        $poll_src->remove() if defined $poll_src;
        $poll_src = undef;
-       $last_err = undef;
 
        if ($err) {
            if ($scan_running) {
@@ -613,6 +613,7 @@ sub find_volume {
            if ($new_chg->isa("Amanda::Changer::Error")) {
                return $steps->{'scan_interactivity'}->("$new_chg");
            }
+           $last_err = undef;
            $self->{'chg'}->quit();
            $self->{'chg'} = $new_chg;
            %seen = ();
index f94b0fc6dfecab3aedb15b0467c9d92ddabfc7db..8c514614efb6f0e5ccd2d90101075795ea6e49e7 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index b40890a3f438b32200ea182170066471c8bac205..1726fa1781c98a68a8c48790da6be8a9bcc72121 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -21,6 +21,7 @@ package Amanda::Report::human;
 
 use strict;
 use warnings;
+use Carp;
 
 use POSIX;
 use Data::Dumper;
@@ -313,7 +314,7 @@ sub print_human_amreport
     my ( $self, $fh ) = @_;
 
     $fh ||= $self->{fh}
-      || die "error: no file handle given to print_human_amreport\n";
+      || confess "error: no file handle given to print_human_amreport\n";
 
     ## collect statistics
     $self->calculate_stats();
@@ -1510,9 +1511,9 @@ sub set_col_spec
     my $disp_unit = $self->{disp_unit};
 
     $self->{col_spec} = [
-        [ "HostName", 0, 12, 12, 0, "%-*.*s", "HOSTNAME" ],
-        [ "Disk",     1, 11, 11, 0, "%-*.*s", "DISK" ],
-        [ "Level",    1, 1,  1,  0, "%*.*d",  "L" ],
+        [ "HostName", 0, 12, 12, 1, "%-*.*s", "HOSTNAME" ],
+        [ "Disk",     1, 11, 11, 1, "%-*.*s", "DISK" ],
+        [ "Level",    1, 1,  1,  1, "%*.*d",  "L" ],
         [ "OrigKB",   1, 7,  0,  1, "%*.*f",  "ORIG-" . $disp_unit . "B" ],
         [ "OutKB",    1, 7,  0,  1, "%*.*f",  "OUT-" . $disp_unit . "B" ],
         [ "Compress", 1, 6,  1,  1, "%*.*f",  "COMP%" ],
@@ -1531,11 +1532,10 @@ sub apply_col_spec_override
     my ($self) = @_;
     my $col_spec = $self->{col_spec};
 
-    my %col_spec_override = read_col_spec_override();
+    my %col_spec_override = $self->read_col_spec_override();
 
     foreach my $col (@$col_spec) {
         if ( my $col_override = $col_spec_override{ $col->[COLSPEC_NAME] } ) {
-
             my $override_col_val_if_def = sub {
                 my ( $field, $or_num ) = @_;
                 if ( defined $col_override->[$or_num]
@@ -1554,22 +1554,36 @@ sub apply_col_spec_override
 
 sub read_col_spec_override
 {
-    ## takes no arguments
+    my ($self) = @_;
+
     my $col_spec_str = getconf($CNF_COLUMNSPEC) || return;
     my %col_spec_override = ();
+    my $col_spec = $self->{col_spec};
 
     foreach (split(",", $col_spec_str)) {
 
         $_ =~ m/^(\w+)           # field name
                 =([-:\d]+)       # field values
                 $/x
-          or die "error: malformed columnspec string:$col_spec_str";
+          or confess "error: malformed columnspec string:$col_spec_str";
 
         my $field = $1;
+       my $found = 0;
+
+       foreach my $col (@$col_spec) {
+           if (lc $field eq lc $col->[0]) {
+               $field = $col->[0];
+               $found = 1;
+           }
+       }
+       if ($found == 0) {
+           die("Invalid field name: $field");
+       }
+
         my @field_values = split ':', $2;
 
         # too many values
-        die "error: malformed columnspec string:$col_spec_str"
+        confess "error: malformed columnspec string:$col_spec_str"
           if (@field_values > 3);
 
         # all values *should* be in the right place.  If not enough
index 2a8f589fb06e9211e369755877267366d206b78e..f7c15558fc3e02c7ebe5eceb1081aa2759d31815 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 6b5ea5038dca757379589ef6aa91cc1a82ce4a04..51b1eac2cb5aa01b9df1c565b8f6723198a2b2b9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index d47f67510a89251635318189451ce261593da63f..f5d4d7b12a95601ed05a43f8df9df0d799907710 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -264,10 +264,12 @@ sub _scan {
            $res->{device}->status == $DEVICE_STATUS_SUCCESS) {
            $label = $res->{device}->volume_label;
        }
+       my $relabeled = !defined($label) || $label !~ /$self->{'labelstr'}/;
        $self->_user_msg(slot_result => 1,
                         slot => $slot_scanned,
                         label => $label,
                         err  => $err,
+                        relabeled => $relabeled,
                         res  => $res);
        if ($res) {
            my $f_type;
@@ -500,7 +502,7 @@ sub _scan {
            return $result_cb->($err, $res);
        }
        $label = $res->{'device'}->volume_label;
-       if (!defined $label) {
+       if (!defined($label) || $label !~ /$self->{'labelstr'}/) {
            $res->get_meta_label(finished_cb => $steps->{'got_meta_label'});
            return;
        }
@@ -567,12 +569,13 @@ sub volume_is_labelable {
                             err          => $sl->{'device_error'},
                             slot         => $slot);
        return 0;
-    } elsif ($dev_status & $DEVICE_STATUS_SUCCESS and
+    } elsif ($dev_status == $DEVICE_STATUS_SUCCESS and
             $f_type == $Amanda::Header::F_TAPESTART and
             $label !~ /$self->{'labelstr'}/) {
        if (!$autolabel->{'other_config'}) {
            $self->_user_msg(slot_result  => 1,
-                            other_config => 1,
+                            label        => $label,
+                            does_not_match_labelstr => 1,
                             slot         => $slot);
            return 0;
        }
index c8333d60f5efe88ad8b5eda26f62a5c8e618ebc0..addd6f0f994900b852ed148530b399eeddc9d537 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index aac85e6fe90203d300501bbfaa6172cb4dd79ff0..f0ce34919ae837c9cb1190cc4ccd0985e9563135 100644 (file)
@@ -1,5 +1,5 @@
 # vim:ft=perl
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 1800253a9ada921396e2caeabbfe82f4bc81339c..611b085e0f60f4cdb5f1ad291d0e03cccd7493de 100644 (file)
@@ -1851,6 +1851,7 @@ XS(_wrap_list_new_tapes) {
     result = (char *)list_new_tapes(arg1);
     ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ;
     
+    free((char*)result);
     XSRETURN(argvi);
   fail:
     
index 1d266705c4a83f1695713187f97960159d0e10b3..b69680815ef7dfd0afd87f796e165ab6ef6c67d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index b514cac9020648b3ab2b217cdd07556b0fc484c0..0ce1987bb8e94e4ec189a154180649ed1f6662a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -269,6 +269,7 @@ sub _update_positions {
 %}
 
 char *get_last_reusable_tape_label(int skip);
+%newobject list_new_tapes;
 char *list_new_tapes(int nb);
 
 /* C functions -- should be called *only* from within this module */
index f6c839f66da731da28fa5369408588b1ff02e4ca..a1a6c091000cb494eb5233bd3b12b3bed7df63b1 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 89066ec91674f7cc6160ee7d46dea12a762d8fcb..04751718e0118c3271077e3ac837cc18058daa11 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f757b9b8602719b64dc063c2d1859bd899be2dd2..d8d7a414ab79490d3f4c76b74474969ebb378d1c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This library is free software; you can redistribute it and/or modify it
 # under the terms of the GNU Lesser General Public License version 2.1 as
index c69279ca54aae36c4de688ab93653c8bddce3682..44c2b0e1bcf2d0e3ea257eb76f3323ed667106e7 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index a7945a8d99c835646b534d0b83ef83d88349b561..c2bcb6d356aba1cfe9c9c5975f9675eed9cd4e46 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7c8235cbd54f2acf1d930856c36426c8a4f7b57e..ec6e96bb3105a9c6927cd1e0703dc500b545b75e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This library is free software; you can redistribute it and/or modify it
 # under the terms of the GNU Lesser General Public License version 2.1 as
@@ -390,10 +390,42 @@ sub stage_2 {
 
        if (!defined $autolabel->{'template'} ||
            $autolabel->{'template'} eq "") {
-           $self->_user_msg(slot_result  => 1,
-                            not_autolabel => 1,
-                            slot         => $slot,
-                            res          => $res);
+           if ($status & $DEVICE_STATUS_VOLUME_UNLABELED and
+               $dev->volume_header and
+               $dev->volume_header->{'type'} == $Amanda::Header::F_EMPTY) {
+               $self->_user_msg(slot_result   => 1,
+                                not_autolabel => 1,
+                                empty         => 1,
+                                slot          => $slot,
+                                res           => $res);
+           } elsif ($status & $DEVICE_STATUS_VOLUME_UNLABELED and
+               $dev->volume_header and
+               $dev->volume_header->{'type'} == $Amanda::Header::F_WEIRD) {
+               $self->_user_msg(slot_result   => 1,
+                                not_autolabel => 1,
+                                non_amanda    => 1,
+                                slot          => $slot,
+                                res           => $res);
+           } elsif ($status & $DEVICE_STATUS_VOLUME_ERROR) {
+               $self->_user_msg(slot_result   => 1,
+                                not_autolabel => 1,
+                                volume_error  => 1,
+                                err           => $dev->error_or_status(),
+                                slot          => $slot,
+                                res           => $res);
+           } elsif ($status != $DEVICE_STATUS_SUCCESS) {
+               $self->_user_msg(slot_result   => 1,
+                                not_autolabel => 1,
+                                not_success   => 1,
+                                err           => $dev->error_or_status(),
+                                slot          => $slot,
+                                res           => $res);
+           } else {
+               $self->_user_msg(slot_result   => 1,
+                                not_autolabel => 1,
+                                slot          => $slot,
+                                res           => $res);
+           }
            return $steps->{'try_continue'}->();
        }
 
index d135e3a8ad89ab787293c738fa3a40360a630ec9..31831b754451a62144bc9598c39962d6f48ce9f5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This library is free software; you can redistribute it and/or modify it
 # under the terms of the GNU Lesser General Public License version 2.1 as
@@ -498,7 +498,7 @@ sub start {
            unless exists $params{$rq_param};
     }
 
-    die "scribe already started" if $self->{'started'};
+    confess "scribe already started" if $self->{'started'};
 
     $self->dbg("starting");
     $self->{'write_timestamp'} = $params{'write_timestamp'};
@@ -527,7 +527,7 @@ sub quit {
        $self->dbg("quitting");
 
        if ($self->{'xfer'}) {
-           die "Scribe cannot quit while a transfer is active";
+           confess "Scribe cannot quit while a transfer is active";
            # Supporting this would be complicated:
            # - cancel the xfer and wait for it to complete
            # - ensure that the taperscan not be started afterward
@@ -590,7 +590,7 @@ sub check_data_path {
     my $device = $self->get_device();
 
     if (!defined $device) {
-       die "no device is available to check the datapath";
+       confess "no device is available to check the datapath";
     }
 
     my $use_directtcp = $device->directtcp_supported();
@@ -622,11 +622,11 @@ sub get_xfer_dest {
            unless exists $params{$rq_param};
     }
 
-    die "not yet started"
+    confess "not yet started"
        unless $self->{'write_timestamp'} and $self->{'started'};
-    die "xfer element already returned"
+    confess "xfer element already returned"
        if ($self->{'xdt'});
-    die "xfer already running"
+    confess "xfer already running"
        if ($self->{'xfer'});
 
     $self->{'xfer'} = undef;
@@ -656,7 +656,7 @@ sub get_xfer_dest {
 
     my $xdt_first_dev = $self->get_device();
     if (!defined $xdt_first_dev) {
-       die "no device is available to create an xfer_dest";
+       confess "no device is available to create an xfer_dest";
     }
     my $leom_supported = $xdt_first_dev->property_get("leom");
     my $use_directtcp = $xdt_first_dev->directtcp_supported();
@@ -747,7 +747,7 @@ sub start_dump {
     my $self = shift;
     my %params = @_;
 
-    die "no xfer dest set up; call get_xfer_dest first"
+    confess "no xfer dest set up; call get_xfer_dest first"
         unless defined $self->{'xdt'};
 
     # get the header ready for writing (totalparts was set by the caller)
@@ -767,29 +767,17 @@ sub cancel_dump {
     my $self = shift;
     my %params = @_;
 
-    die "no xfer dest set up; call get_xfer_dest first"
+    confess "no xfer dest set up; call get_xfer_dest first"
        unless defined $self->{'xdt'};
 
     # set up the dump_cb for when this dump is done, and keep the xfer
     $self->{'dump_cb'} = $params{'dump_cb'};
     $self->{'xfer'} = $params{'xfer'};
 
-    # XXX The cancel should call dump_cb, but right now the xfer stays hung in
-    # accept.  So we leave the xfer to its hang, and dump_cb is called and xdt
-    # and xfer are set to undef.  This should be fixed in 3.2.
+    # The cancel will can dump_cb.
 
     $self->{'xfer'}->cancel();
 
-    $self->{'dump_cb'}->(
-       result => "FAILED",
-       device_errors => [],
-       config_denial_message => undef,
-       size => 0,
-       duration => 0.0,
-       total_duration => 0,
-       nparts => 0);
-    $self->{'xdt'} = undef;
-    $self->{'xfer'} = undef;
 }
 
 sub close_volume {
@@ -886,7 +874,7 @@ sub _xmsg_part_done {
        $self->dbg("not notifying for empty, successful part");
     } else {
        # double-check partnum
-       die "Part numbers do not match!"
+       confess "Part numbers do not match!"
            unless ($self->{'dump_header'}->{'partnum'} == $msg->{'partnum'});
 
        # notify
@@ -1067,7 +1055,7 @@ sub _operation_failed {
             # _dump_done constructs the dump_cb from $self parameters
             $self->_dump_done();
         } else {
-            die "error with no callback to handle it: $error_message";
+            confess "error with no callback to handle it: $error_message";
         }
     }
 }
@@ -1386,10 +1374,14 @@ sub _device_start {
                               $reservation->{'barcode'});
            $tl->write();
            $self->dbg("generate new label '$new_label'");
-       } elsif (!defined $meta) {
+       } else {
            $tl->reload(0);
            my $tle = $tl->lookup_tapelabel($new_label);
-           my $meta = $tle->{'meta'};
+           $meta = $tle->{'meta'} if !defined $meta && $tle->{'meta'};
+           my $barcode = $tle->{'barcode'};
+           if (defined $barcode and $barcode ne $reservation->{'barcode'}) {
+               return $finished_cb->("tapelist for label '$new_label' have barcode '$barcode' but changer report '" . $reservation->{'barcode'} . "'");
+           }
        }
 
        # write the label to the device
@@ -1689,7 +1681,7 @@ sub get_volume {
     my $self = shift;
     my (%params) = @_;
 
-    die "already processing a volume request"
+    confess "already processing a volume request"
        if ($self->{'volume_cb'});
 
     $self->{'volume_cb'} = $params{'volume_cb'};
@@ -1742,6 +1734,21 @@ sub _start_scanning {
                if ($params{'label'}) {
                    $self->{'feedback'}->scribe_notif_log_info(
                        message => "Slot $params{'slot'} with label $params{'label'} is not labelable ");
+               } elsif ($params{'empty'}) {
+                   $self->{'feedback'}->scribe_notif_log_info(
+                       message => "Slot $params{'slot'} is empty, autolabel not set");
+               } elsif ($params{'non_amanda'}) {
+                   $self->{'feedback'}->scribe_notif_log_info(
+                       message => "Slot $params{'slot'} is a non-amanda volume, autolabel not set");
+               } elsif ($params{'volume_error'}) {
+                   $self->{'feedback'}->scribe_notif_log_info(
+                       message => "Slot $params{'slot'} is a volume in error: $params{'err'}, autolabel not set");
+               } elsif ($params{'not_success'}) {
+                   $self->{'feedback'}->scribe_notif_log_info(
+                       message => "Slot $params{'slot'} is a device in error: $params{'err'}, autolabel not set");
+               } elsif ($params{'err'}) {
+                   $self->{'feedback'}->scribe_notif_log_info(
+                       message => "$params{'err'}");
                } else {
                    $self->{'feedback'}->scribe_notif_log_info(
                        message => "Slot $params{'slot'} without label is not labelable ");
@@ -1767,6 +1774,9 @@ sub _start_scanning {
            } elsif (!defined $params{'label'}) {
                $self->{'feedback'}->scribe_notif_log_info(
                    message => "Slot $params{'slot'} without label can be labeled");
+           } elsif ($params{'relabeled'}) {
+               $self->{'feedback'}->scribe_notif_log_info(
+                   message => "Slot $params{'slot'} with label $params{'label'} will be relabeled");
            } else {
                $self->{'feedback'}->scribe_notif_log_info(
                    message => "Slot $params{'slot'} with label $params{'label'} is usable");
@@ -1817,10 +1827,10 @@ sub _start_request {
            } elsif ($params{'cause'} eq 'error') {
                $self->{'error_denial_message'} = $params{'message'};
            } else {
-               die "bad cause '" . $params{'cause'} . "'";
+               confess "bad cause '" . $params{'cause'} . "'";
            }
        } elsif (!defined $params{'allow'}) {
-           die "no allow or cause defined";
+           confess "no allow or cause defined";
        }
 
        $self->_maybe_callback();
index 7e6b9ea136068fdfb772a328fa236f253919d3f2..d8802be4076ffb068e8497293d0bcbcdda53c971 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -38,6 +38,7 @@ use warnings;
 
 package Amanda::Taper::Worker;
 
+use Carp;
 use POSIX qw( :errno_h );
 use Amanda::Changer;
 use Amanda::Config qw( :getconf config_dir_relative );
@@ -221,11 +222,14 @@ sub DONE {
     my $self = shift;
     my ($msgtype, %params) = @_;
 
-    $self->_assert_in_state("writing") or return;
-    $self->{'dumper_status'} = "DONE";
-    $self->{'orig_kb'} = $params{'orig_kb'};
-    if (defined $self->{'result'}) {
-       $self->result_cb(undef);
+    if (!defined $self->{'dumper_status'}) {
+       $self->{'dumper_status'} = "DONE";
+       $self->{'orig_kb'} = $params{'orig_kb'};
+       if (defined $self->{'result'}) {
+           $self->result_cb(undef);
+       }
+    } else {
+       # ignore the message
     }
 }
 
@@ -233,11 +237,20 @@ sub FAILED {
     my $self = shift;
     my ($msgtype, %params) = @_;
 
-    $self->_assert_in_state("writing") or return;
-
     $self->{'dumper_status'} = "FAILED";
-    if (defined $self->{'result'}) {
+    if (defined $self->{'header_xfer'}) {
+       $self->{'header_xfer'}->cancel();
+    } elsif (defined $self->{'result'}) {
        $self->result_cb(undef);
+    } elsif (!defined $self->{'scribe'}->{'xdt'}) {
+       # ignore, the dump is already cancelled or not yet started.
+    } elsif (!defined $self->{'scribe'}->{'xfer'}) {
+       # ignore, the dump is already cancelled or not yet started.
+    } else { # Abort the dump
+       push @{$self->{'input_errors'}}, "dumper failed";
+       $self->{'scribe'}->cancel_dump(
+               xfer => $self->{'scribe'}->{'xfer'},
+               dump_cb => $self->{'dump_cb'});
     }
 }
 
@@ -488,7 +501,7 @@ sub create_status_file {
     $self->{timer}->set_callback(sub {
        my $size = $self->{scribe}->get_bytes_written();
        seek $self->{status_fh}, 0, 0;
-       print {$self->{status_fh}} $size;
+       print {$self->{status_fh}} $size, '     ';
        $self->{status_fh}->flush();
     });
 }
@@ -497,7 +510,6 @@ sub send_port_and_get_header {
     my $self = shift;
     my ($finished_cb) = @_;
 
-    my $header_xfer;
     my ($xsrc, $xdst);
     my $errmsg;
 
@@ -517,8 +529,8 @@ sub send_port_and_get_header {
        ($xsrc, $xdst) = (
            Amanda::Xfer::Source::DirectTCPListen->new(),
            Amanda::Xfer::Dest::Buffer->new(0));
-       $header_xfer = Amanda::Xfer->new([$xsrc, $xdst]);
-       $header_xfer->start($steps->{'header_xfer_xmsg_cb'});
+       $self->{'header_xfer'} = Amanda::Xfer->new([$xsrc, $xdst]);
+       $self->{'header_xfer'}->start($steps->{'header_xfer_xmsg_cb'});
 
        my $header_addrs = $xsrc->get_addrs();
        my $header_port = $header_addrs->[0][1];
@@ -550,7 +562,7 @@ sub send_port_and_get_header {
        my $hdr_buf = $xdst->get();
 
        # close stuff up
-       $header_xfer = $xsrc = $xdst = undef;
+       $self->{'header_xfer'} = $xsrc = $xdst = undef;
 
        if (!defined $hdr_buf) {
            return $finished_cb->("Got empty header");
@@ -570,6 +582,8 @@ sub setup_and_start_dump {
     my ($msgtype, %params) = @_;
     my %get_xfer_dest_args;
 
+    $self->{'dump_cb'} = $params{'dump_cb'};
+
     # setting up the dump is a bit complex, due to the requirements of
     # a directtcp port_write.  This function:
     # 1. creates and starts a transfer (make_xfer)
@@ -618,7 +632,7 @@ sub setup_and_start_dump {
 
        my $device = $self->{'scribe'}->get_device();
        if (!defined $device) {
-           die "no device is available to create an xfer_dest";
+           confess "no device is available to create an xfer_dest";
        }
        $splitting_args{'leom_supported'} = $device->property_get("leom");
        # and convert those to get_xfer_dest args
@@ -690,7 +704,7 @@ sub setup_and_start_dump {
            $hdr->{'cont_filename'} = '';
 
            if (!defined $hdr || $hdr->{'type'} != $Amanda::Header::F_DUMPFILE) {
-               die("Could not read header from '$params{filename}'");
+               confess("Could not read header from '$params{filename}'");
            }
            $steps->{'start_dump'}->(undef);
        } else {
@@ -721,7 +735,7 @@ sub setup_and_start_dump {
             or $hdr->{'name'} ne $params{'hostname'}
             or $hdr->{'disk'} ne $params{'diskname'}
            or $hdr->{'datestamp'} ne $params{'datestamp'}) {
-            die("Header of dumpfile does not match command from driver");
+            confess("Header of dumpfile does not match command from driver");
         }
 
        # start producing status
index 8876cf62a680676e0f3aa4f1f14be8c066e8387f..27c192ccd2f83f3a40bed2abb667c5e7c62b767f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 0877e37c189f1b43f0689be174a65bb4eb75e525..6f834499dbf98e2ced24819fbc9a1d37bc2087d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 164245d8d8cc8241978aca9fd049895eeb0e88bc..4357d9f5b1b91862ece2e202217d206de16549fd 100644 (file)
@@ -2063,6 +2063,7 @@ XS(_wrap_sanitise_filename) {
     result = (char *)sanitise_filename(arg1);
     ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ;
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+    free((char*)result);
     XSRETURN(argvi);
   fail:
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
@@ -2092,6 +2093,7 @@ XS(_wrap_quote_string) {
     result = (char *)quote_string(arg1);
     ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ;
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+    free((char*)result);
     XSRETURN(argvi);
   fail:
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
@@ -2121,6 +2123,7 @@ XS(_wrap_unquote_string) {
     result = (char *)unquote_string(arg1);
     ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ;
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+    free((char*)result);
     XSRETURN(argvi);
   fail:
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
@@ -2249,8 +2252,10 @@ XS(_wrap_split_quoted_strings) {
         
         for (iter = result; *iter; iter++) {
           ST(argvi) = sv_2mortal(newSVpv(*iter, 0));
+          g_free(*iter);
           argvi++;
         }
+        g_free(result);
       }
     }
     if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
index 1b45a8c46e17cf2eb250664a51db46b6874742ab..ef97b3eaf87cb673a0ac76118f7955909102e594 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index e325a9e0a918bad8ac0e5ed4bb549f55dc52d3f4..43c4a99fc7cdf6e7360d3e24ffdc05512e15b2f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -315,8 +315,10 @@ sub safe_overwrite_file {
 
        for (iter = $1; *iter; iter++) {
            $result = sv_2mortal(newSVpv(*iter, 0));
+           g_free(*iter);
            argvi++;
        }
+       g_free($1);
     }
 }
 
@@ -338,12 +340,16 @@ char *perl_hexdecode_string(const char *str) {
 %}
 amglue_export_tag(encoding, hexencode hexdecode);
 
+%newobject sanitise_filename;
 char *sanitise_filename(char *inp);
+%newobject quote_string;
 char *quote_string(char *);
+%newobject unquote_string;
 char *unquote_string(char *);
 GPtrArray *expand_braced_alternates(char *);
 %newobject collapse_braced_alternates;
 char *collapse_braced_alternates(GPtrArray *source);
+%newobject split_quoted_strings;
 gchar **split_quoted_strings(const gchar *string);
 amglue_export_tag(quoting, quote_string unquote_string skip_quoted_string
                sanitise_filename split_quoted_strings split_quoted_strings_friendly);
@@ -443,6 +449,7 @@ set_blocking(int fd, gboolean blocking)
 
 typedef struct file_lock {
     %extend {
+       %newobject file_lock;
        file_lock(const char *filename) {
            return file_lock_new(filename);
        }
index f449b517cf4f3bc819067e1fb457e2d091f76a0b..913ce4c2a0144f00b52d5c0b1b8e0074b274f1ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 31c5b7dfdb87ad8812d57c0735d9250862db0217..c5b0fd962bc21dd8c506851b4635b7f654f2af31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 4e4e80dcfdcfed204f329c6d122d89654ca596b4..3ab6e645925fa3cbe2a28f983af98385e6f0fdfb 100644 (file)
@@ -1946,6 +1946,37 @@ XS(_wrap_xfer_source_holding) {
 }
 
 
+XS(_wrap_xfer_source_holding_get_bytes_read) {
+  {
+    XferElement *arg1 = (XferElement *) 0 ;
+    int argvi = 0;
+    guint64 result;
+    dXSARGS;
+    
+    if ((items < 1) || (items > 1)) {
+      SWIG_croak("Usage: xfer_source_holding_get_bytes_read(self);");
+    }
+    {
+      arg1 = xfer_element_from_sv(ST(0));
+    }
+    result = xfer_source_holding_get_bytes_read(arg1);
+    {
+      SV *for_stack;
+      SP += argvi; PUTBACK;
+      for_stack = sv_2mortal(amglue_newSVu64(result));
+      SPAGAIN; SP -= argvi;
+      ST(argvi) = for_stack;
+      argvi++;
+    }
+    
+    XSRETURN(argvi);
+  fail:
+    
+    SWIG_croak_null();
+  }
+}
+
+
 XS(_wrap_xfer_dest_taper_splitter) {
   {
     Device *arg1 = (Device *) 0 ;
@@ -2380,6 +2411,37 @@ XS(_wrap_xfer_source_recovery_use_device) {
 }
 
 
+XS(_wrap_xfer_source_recovery_get_bytes_read) {
+  {
+    XferElement *arg1 = (XferElement *) 0 ;
+    int argvi = 0;
+    guint64 result;
+    dXSARGS;
+    
+    if ((items < 1) || (items > 1)) {
+      SWIG_croak("Usage: xfer_source_recovery_get_bytes_read(self);");
+    }
+    {
+      arg1 = xfer_element_from_sv(ST(0));
+    }
+    result = xfer_source_recovery_get_bytes_read(arg1);
+    {
+      SV *for_stack;
+      SP += argvi; PUTBACK;
+      for_stack = sv_2mortal(amglue_newSVu64(result));
+      SPAGAIN; SP -= argvi;
+      ST(argvi) = for_stack;
+      argvi++;
+    }
+    
+    XSRETURN(argvi);
+  fail:
+    
+    SWIG_croak_null();
+  }
+}
+
+
 
 /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
 
@@ -2459,6 +2521,7 @@ static swig_command_info swig_commands[] = {
 {"Amanda::XferServerc::xfer_source_device", _wrap_xfer_source_device},
 {"Amanda::XferServerc::xfer_dest_device", _wrap_xfer_dest_device},
 {"Amanda::XferServerc::xfer_source_holding", _wrap_xfer_source_holding},
+{"Amanda::XferServerc::xfer_source_holding_get_bytes_read", _wrap_xfer_source_holding_get_bytes_read},
 {"Amanda::XferServerc::xfer_dest_taper_splitter", _wrap_xfer_dest_taper_splitter},
 {"Amanda::XferServerc::xfer_dest_taper_cacher", _wrap_xfer_dest_taper_cacher},
 {"Amanda::XferServerc::xfer_dest_taper_directtcp", _wrap_xfer_dest_taper_directtcp},
@@ -2469,6 +2532,7 @@ static swig_command_info swig_commands[] = {
 {"Amanda::XferServerc::xfer_source_recovery", _wrap_xfer_source_recovery},
 {"Amanda::XferServerc::xfer_source_recovery_start_part", _wrap_xfer_source_recovery_start_part},
 {"Amanda::XferServerc::xfer_source_recovery_use_device", _wrap_xfer_source_recovery_use_device},
+{"Amanda::XferServerc::xfer_source_recovery_get_bytes_read", _wrap_xfer_source_recovery_get_bytes_read},
 {0,0}
 };
 /* -----------------------------------------------------------------------------
index a1d30ffc13f0d520891132dbd505ffa51b63c350..0c9c5535b323108fef89ed5960351ad9453bf48a 100644 (file)
@@ -56,6 +56,7 @@ package Amanda::XferServer;
 *xfer_source_device = *Amanda::XferServerc::xfer_source_device;
 *xfer_dest_device = *Amanda::XferServerc::xfer_dest_device;
 *xfer_source_holding = *Amanda::XferServerc::xfer_source_holding;
+*xfer_source_holding_get_bytes_read = *Amanda::XferServerc::xfer_source_holding_get_bytes_read;
 *xfer_dest_taper_splitter = *Amanda::XferServerc::xfer_dest_taper_splitter;
 *xfer_dest_taper_cacher = *Amanda::XferServerc::xfer_dest_taper_cacher;
 *xfer_dest_taper_directtcp = *Amanda::XferServerc::xfer_dest_taper_directtcp;
@@ -66,6 +67,7 @@ package Amanda::XferServer;
 *xfer_source_recovery = *Amanda::XferServerc::xfer_source_recovery;
 *xfer_source_recovery_start_part = *Amanda::XferServerc::xfer_source_recovery_start_part;
 *xfer_source_recovery_use_device = *Amanda::XferServerc::xfer_source_recovery_use_device;
+*xfer_source_recovery_get_bytes_read = *Amanda::XferServerc::xfer_source_recovery_get_bytes_read;
 
 # ------- VARIABLE STUBS --------
 
@@ -122,6 +124,7 @@ sub new {
 
     Amanda::XferServer::xfer_source_holding(@_);
 }
+*get_bytes_read = *Amanda::XferServer::xfer_source_holding_get_bytes_read;
 
 package Amanda::Xfer::Dest::Taper;
 
@@ -181,4 +184,5 @@ sub new {
 }
 *start_part = *Amanda::XferServer::xfer_source_recovery_start_part;
 *use_device = *Amanda::XferServer::xfer_source_recovery_use_device;
+*get_bytes_read = *Amanda::XferServer::xfer_source_recovery_get_bytes_read;
 1;
index c8707dfc830e0a862e3112c7c31a0eb2f86bac0d..054bf93c771b54d89061b2722b7303cdfb9ad831 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index becc5792d81b6b4381f556cb9be0483bc1d53f81..4f25a21926ff54440569c77409933601f70f68af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -47,6 +47,9 @@ XferElement *xfer_dest_device(
 XferElement * xfer_source_holding(
     const char *filename);
 
+guint64 xfer_source_holding_get_bytes_read(
+    XferElement *self);
+
 %newobject xfer_dest_taper_splitter;
 XferElement *xfer_dest_taper_splitter(
     Device *first_device,
@@ -96,6 +99,10 @@ void xfer_source_recovery_use_device(
     XferElement *self,
     Device *device);
 
+guint64 xfer_source_recovery_get_bytes_read(
+    XferElement *self);
+
+
 /* ---- */
 
 PACKAGE(Amanda::Xfer::Source::Device)
@@ -113,6 +120,7 @@ DECLARE_CONSTRUCTOR(Amanda::XferServer::xfer_dest_device)
 PACKAGE(Amanda::Xfer::Source::Holding)
 XFER_ELEMENT_SUBCLASS()
 DECLARE_CONSTRUCTOR(Amanda::XferServer::xfer_source_holding)
+DECLARE_METHOD(get_bytes_read, Amanda::XferServer::xfer_source_holding_get_bytes_read)
 
 /* ---- */
 
@@ -148,3 +156,5 @@ XFER_ELEMENT_SUBCLASS()
 DECLARE_CONSTRUCTOR(Amanda::XferServer::xfer_source_recovery)
 DECLARE_METHOD(start_part, Amanda::XferServer::xfer_source_recovery_start_part)
 DECLARE_METHOD(use_device, Amanda::XferServer::xfer_source_recovery_use_device)
+DECLARE_METHOD(get_bytes_read, Amanda::XferServer::xfer_source_recovery_get_bytes_read)
+
index 7c953c1a23ba10d364a389097ba29d90c75d8155..cdf7eb12c94eceab9e4a2711427dcf4c60fc7daa 100644 (file)
@@ -526,7 +526,7 @@ EXTRA_DIST += Amanda/Application/Zfs.pm
 if WANT_CYGWIN_COPY_PERL_DLL
 amperldirauto="$(DESTDIR)$(amperldir)/auto/Amanda"
 install-data-hook:
-       @for cygdll in $(amperldirauto)/bin/cyg*.dll; do \
+       @for cygdll in $(wildcard $(amperldirauto)/bin/cyg*.dll); do \
            destfname=`echo $$cygdll|sed 's!/bin/cyg\([^.]*\).dll!/\1/\1.dll!'`; \
           cp "$$cygdll" "$$destfname"; \
        done
index 87e58ab44aa4a15db55e4fcbd2bec49f9b3d56b9..241fcc5e2f3d29a33a8684c0ae14ed515c364c76 100644 (file)
@@ -16,7 +16,7 @@
 @SET_MAKE@
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -38,7 +38,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -327,7 +327,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -1148,6 +1149,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
@@ -3411,7 +3415,7 @@ html: make_html amperl.css $(PM_FILES)
 # PACKAGE: Amanda::Feature
 Amanda/Feature.pm: ../common-src/amfeatures.h
 @WANT_CYGWIN_COPY_PERL_DLL_TRUE@install-data-hook:
-@WANT_CYGWIN_COPY_PERL_DLL_TRUE@       @for cygdll in $(amperldirauto)/bin/cyg*.dll; do \
+@WANT_CYGWIN_COPY_PERL_DLL_TRUE@       @for cygdll in $(wildcard $(amperldirauto)/bin/cyg*.dll); do \
 @WANT_CYGWIN_COPY_PERL_DLL_TRUE@           destfname=`echo $$cygdll|sed 's!/bin/cyg\([^.]*\).dll!/\1/\1.dll!'`; \
 @WANT_CYGWIN_COPY_PERL_DLL_TRUE@          cp "$$cygdll" "$$destfname"; \
 @WANT_CYGWIN_COPY_PERL_DLL_TRUE@       done
index f12ba03d367b2094e62d0d5635460f28a611b083..9514960b4cba72af7bad0353d54fa187e3ade91b 100644 (file)
@@ -16,7 +16,7 @@
 @SET_MAKE@
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -38,7 +38,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -280,7 +280,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -841,6 +842,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 9dab77c26ea47b498ae73b077ff66f8680a0fe52..67184d0015a0972c46705fd051b8b3a6809d64db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index f5f3b9a0d4611a6a3326bfa8aeac0d731d2a9e6e..094902570150302a53190daa3a454d60c7ac2b57 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index a46c50864cdd05e031d019d3bfee5c83fe422243..33c5a5f2304999b216445999eb4dfa8a3242979c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index f194ef2e64f38ae35496ada1238d9304a88df616..556ed83b687c0d6844c5edb89d7a0b7bbd0e034d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 641b9187d7ad6b473e30a38aca6c5edcc4df5719..27d78301b6df3ab494c0ccdc6ee316728e396978 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 746787468795e56f79b3f25142cd59d2465f2e4f..5a0eba55eb4e72da5dcb8a4640619d1d98a53de1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 7b74f95f4db4860fd53e5337e4dfa9007abf32ed..19b792bf8154c11738d8dbd4083fe787d49c1a89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index b8b6f53bf9a89e2f6b42bd9d1d672259fb83fc9f..64998863e9ded9fb55a3f8015668fb74bbac5c3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 50d493ff606b2b670e1652b463cc35b2fdd9441c..679cf2ba597f1a495e8bea7ea84be9315941df47 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 2c1ce07005db65265c711b510ca616bfed055fd3..3844b6e57bf580749549f9b3edb2e0d8f2c9cfce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 32b77177d37c3bc8ed71b42ed48ee2a9c66ab69a..038906a9d657f8eb45add85ee2455b8c2e96915d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 29e95f20ffd7dd092428be27ba6d558272a99166..5ce1edacb80fca9a925f4ce389f0c2aa53c101c7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 612dcac610bbbe550912de681cc249bf6b8c0283..fe077156d22f744727c5d50331c530c2418b8b43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index fb50580a38d43483ba8e6ac06b5f30dc2671ddec..5ec9e9172c71171178ca019287dd7d5cfaed950f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 0acd6699b1aa8411972031f1f3a9b8d8f888a42c..24c309ea9d948316f2a878893ecc762fba64b587 100644 (file)
@@ -186,7 +186,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -701,6 +702,9 @@ MSGMERGE = msgmerge
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index fa8f5e4390b6a0c0891b7a88937f2b405567c1cb..9acb85cff47371fac0476af74924b2a7c41d816c 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda file recovery programs.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -268,7 +268,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -819,6 +820,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index a5a4251341a7b71670a96803c6338dcc623ec3b2..1744ad6e37fa73d2e26800c71d454e6dfca46812 100644 (file)
@@ -2307,7 +2307,7 @@ extract_files(void)
     g_options.hostname = dump_hostname;
     for (elist = first_tape_list(); elist != NULL;
         elist = next_tape_list(elist)) {
-       level_t *level = g_new0(level_t, 1);
+       am_level_t *level = g_new0(am_level_t, 1);
        level->level = elist->level;
        all_level = g_slist_append(all_level, level);
     }
@@ -2349,13 +2349,13 @@ extract_files(void)
        dump_datestamp = newstralloc(dump_datestamp, elist->date);
 
        if (last_level != -1 && dump_dle) {
-           level_t *level;
+           am_level_t *level;
 
-           level = g_new0(level_t, 1);
+           level = g_new0(am_level_t, 1);
            level->level = last_level;
            dump_dle->levellist = g_slist_append(dump_dle->levellist, level);
 
-           level = g_new0(level_t, 1);
+           level = g_new0(am_level_t, 1);
            level->level = elist->level;
            dump_dle->levellist = g_slist_append(dump_dle->levellist, level);
            run_client_scripts(EXECUTE_ON_INTER_LEVEL_RECOVER, &g_options,
@@ -2372,9 +2372,9 @@ extract_files(void)
            return;
        }
        if (dump_dle) {
-           level_t *level;
+           am_level_t *level;
 
-           level = g_new0(level_t, 1);
+           level = g_new0(am_level_t, 1);
            level->level = elist->level;
            dump_dle->levellist = g_slist_append(dump_dle->levellist, level);
            run_client_scripts(EXECUTE_ON_PRE_LEVEL_RECOVER, &g_options,
index 8d84135d7d0539fce2defdfb0f8defb1293d63a7..f6532d0703e86a064b066a8d7ae9f7c2e0b86bae 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda server programs.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -40,7 +40,7 @@
 # scripts in this directory.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -352,7 +352,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -987,6 +988,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 8c62d0ecd27b8fe34a1951fe83c1d08779a458dc..45b161e8aa88c9ec1f1b750155b1b938134e6fc8 100755 (executable)
@@ -1,6 +1,6 @@
 #!@PERL@
 #
-# Copyright (c) 2007,2008 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index bd26906c1553ac5e6ce6131dae8d209206967b9b..b7dea49e2f1dced774070377e81cc9c87a894059 100644 (file)
@@ -42,6 +42,7 @@
 #include "util.h"
 #include "timestamp.h"
 #include "server_util.h"
+#include <getopt.h>
 
 disklist_t diskq;
 
@@ -88,6 +89,12 @@ static void show_config(int argc, char **argv);
 static char *conf_tapelist = NULL;
 static char *displayunit;
 static long int unitdivisor;
+static gboolean print_default = 1;
+static gboolean print_source = 0;
+static int opt_days = -1;
+static char *opt_sort = NULL;
+static gboolean opt_long = 0;
+static gboolean opt_outdated = 0;
 
 static const struct {
     const char *name;
@@ -143,6 +150,15 @@ static const struct {
 };
 #define        NCMDS   (int)(sizeof(cmdtab) / sizeof(cmdtab[0]))
 
+static struct option long_options[] = {
+    {"version"       , 0, NULL,  1},
+    {"no-default"    , 0, NULL,  2},
+    {"print-source"  , 0, NULL,  3},
+    {"days"          , 1, NULL,  4},
+    {"sort"          , 1, NULL,  5},
+    {NULL, 0, NULL, 0}
+};
+
 int
 main(
     int                argc,
@@ -176,6 +192,35 @@ main(
 
     cfg_ovr = extract_commandline_config_overrides(&argc, &argv);
 
+    while (1) {
+       int option_index = 0;
+        int c;
+        c = getopt_long(argc, argv, "ld", long_options, &option_index);
+
+       if (c == -1) {
+           break;
+       }
+
+       switch(c) {
+       case 1: printf("amadmin-%s\n", VERSION);
+               return 0;
+       case 2: print_default = 0;
+               break;
+       case 3: print_source = 1;
+               break;
+       case 4: opt_days = atoi(optarg);
+               break;
+       case 5: opt_sort = g_strdup(optarg);
+               break;
+       case 'l': opt_long = TRUE;
+               break;
+       case 'd': opt_outdated = TRUE;
+               break;
+       default: usage();
+       }
+    }
+    argc -= optind-1, argv += optind-1;
+
     if(argc < 3) usage();
 
     set_config_overrides(cfg_ovr);
@@ -246,7 +291,7 @@ usage(void)
 {
     int i;
 
-    g_fprintf(stderr, _("\nUsage: %s [-o configoption]* <conf> <command> {<args>} ...\n"),
+    g_fprintf(stderr, _("\nUsage: %s [--version] [--no-default] [--print-source] [-o configoption]*\n               <conf> <command> {<args>} ...\n"),
            get_pname());
     g_fprintf(stderr, _("    Valid <command>s are:\n"));
     for (i = 0; i < NCMDS; i++)
@@ -898,8 +943,8 @@ tape(
 
 void
 balance(
-    int                argc,
-    char **    argv)
+    int                argc G_GNUC_UNUSED,
+    char **    argv G_GNUC_UNUSED)
 {
     disk_t *dp;
     struct balance_stats {
@@ -921,9 +966,10 @@ balance(
     overdue = 0;
     max_overdue = 0;
 
-    if(argc > 4 && strcmp(argv[3],"--days") == 0) {
-       later = atoi(argv[4]);
-       if(later < 0) later = conf_dumpcycle;
+    if (opt_days > 0) {
+       later = opt_days;
+    } else if (opt_days == 0) {
+       later = conf_dumpcycle;
     }
     if(later > 10000) later = 10000;
 
@@ -1118,11 +1164,11 @@ find(
 
 
     sort_order = newstralloc(sort_order, DEFAULT_SORT_ORDER);
-    if(argc > 4 && strcmp(argv[3],"--sort") == 0) {
+    if (opt_sort) {
        size_t i, valid_sort=1;
 
-       for(i = strlen(argv[4]); i > 0; i--) {
-           switch (argv[4][i - 1]) {
+       for(i = strlen(opt_sort); i > 0; i--) {
+           switch (opt_sort[i - 1]) {
            case 'h':
            case 'H':
            case 'k':
@@ -1144,15 +1190,13 @@ find(
            }
        }
        if(valid_sort) {
-           sort_order = newstralloc(sort_order, argv[4]);
+           sort_order = newstralloc(sort_order, opt_sort);
        } else {
-           g_printf(_("Invalid sort order: %s\n"), argv[4]);
+           g_printf(_("Invalid sort order: %s\n"), opt_sort);
            g_printf(_("Use default sort order: %s\n"), sort_order);
        }
-       start_argc=6;
-    } else {
-       start_argc=4;
     }
+    start_argc=4;
     errstr = match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
 
     /* check all log file exists */
@@ -1454,22 +1498,9 @@ holding(
             return;
 
         case HOLDING_LIST:
+           long_list = opt_long;
+           outdated_list = opt_outdated;
             argc -= 4; argv += 4;
-           while (argc && argv[0][0] == '-') {
-               switch (argv[0][1]) {
-                   case 'l': 
-                       long_list = 1; 
-                       break;
-                   case 'd': /* have to use '-d', and not '-o', because of parse_config */
-                       outdated_list = 1;
-                       break;
-                   default:
-                       g_fprintf(stderr, _("Unknown option -%c\n"), argv[0][1]);
-                       usage();
-                       return;
-               }
-               argc--; argv++;
-           }
 
            /* header */
             if (long_list) {
@@ -1539,7 +1570,7 @@ int
 bump_thresh(
     int                level)
 {
-    int bump = getconf_int(CNF_BUMPSIZE);
+    gint64 bump = getconf_int64(CNF_BUMPSIZE);
     double mult = getconf_real(CNF_BUMPMULT);
 
     while(--level)
@@ -1561,8 +1592,8 @@ bumpsize(
 
     g_printf(_("Current bump parameters:\n"));
     if(conf_bumppercent == 0) {
-       g_printf(_("  bumpsize %5d KB\t- minimum savings (threshold) to bump level 1 -> 2\n"),
-              getconf_int(CNF_BUMPSIZE));
+       g_printf(_("  bumpsize %5jd KB\t- minimum savings (threshold) to bump level 1 -> 2\n"),
+              (intmax_t)getconf_int64(CNF_BUMPSIZE));
        g_printf(_("  bumpdays %5d\t- minimum days at each level\n"),
               getconf_int(CNF_BUMPDAYS));
        g_printf(_("  bumpmult %5.5lg\t- threshold = bumpsize * bumpmult**(level-1)\n\n"),
@@ -2092,9 +2123,6 @@ disklist_one(
 {
     am_host_t *hp;
     netif_t *ip;
-    sle_t *excl;
-    identlist_t pp_scriptlist;
-    estimatelist_t  estimates;
     dumptype_t *dtype = lookup_dumptype(dp->dtype_name);
 
     hp = dp->host;
@@ -2111,222 +2139,10 @@ disklist_one(
     g_printf("        program \"%s\"\n", dp->program);
     if (dp->application)
        g_printf("        application \"%s\"\n", dp->application);
-    g_printf("        data-path %s\n", data_path_to_string(dp->data_path));
-    if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
-       g_printf("        exclude file");
-       for(excl = dp->exclude_file->first; excl != NULL; excl = excl->next) {
-           g_printf(" \"%s\"", excl->name);
-       }
-       g_printf("\n");
-    }
-    if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
-       g_printf("        exclude list");
-       if(dp->exclude_optional) g_printf(" optional");
-       for(excl = dp->exclude_list->first; excl != NULL; excl = excl->next) {
-           g_printf(" \"%s\"", excl->name);
-       }
-       g_printf("\n");
-    }
-    if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
-       g_printf("        include file");
-       for(excl = dp->include_file->first; excl != NULL; excl = excl->next) {
-           g_printf(" \"%s\"", excl->name);
-       }
-       g_printf("\n");
-    }
-    if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
-       g_printf("        include list");
-       if (dp->include_optional) g_printf(" optional");
-       for(excl = dp->include_list->first; excl != NULL; excl = excl->next) {
-           g_printf(" \"%s\"", excl->name);
-       }
-       g_printf("\n");
-    }
-    g_printf("        priority %d\n", dp->priority);
-    g_printf("        dumpcycle %d\n", dp->dumpcycle);
-    g_printf("        maxdumps %d\n", dp->maxdumps);
-    g_printf("        maxpromoteday %d\n", dp->maxpromoteday);
-    if (dp->bumppercent > 0) {
-       g_printf("        bumppercent %d\n", dp->bumppercent);
-    }
-    else {
-       g_printf("        bumpsize %lld\n",
-               (long long)dp->bumpsize);
-    }
-    g_printf("        bumpdays %d\n", dp->bumpdays);
-    g_printf("        bumpmult %lf\n", dp->bumpmult);
-
-    g_printf("        strategy ");
-    switch(dp->strategy) {
-    case DS_SKIP:
-       g_printf("SKIP\n");
-       break;
-    case DS_STANDARD:
-       g_printf("STANDARD\n");
-       break;
-    case DS_NOFULL:
-       g_printf("NOFULL\n");
-       break;
-    case DS_NOINC:
-       g_printf("NOINC\n");
-       break;
-    case DS_HANOI:
-       g_printf("HANOI\n");
-       break;
-    case DS_INCRONLY:
-       g_printf("INCRONLY\n");
-       break;
-    }
-    g_printf("        ignore %s\n", (dp->ignore? "YES" : "NO"));
-    g_printf("        estimate ");
-    estimates = dp->estimatelist;
-    while (estimates) {
-       switch((estimate_t)GPOINTER_TO_INT(estimates->data)) {
-       case ES_CLIENT:
-           g_printf("CLIENT");
-           break;
-       case ES_SERVER:
-           g_printf("SERVER");
-           break;
-       case ES_CALCSIZE:
-           g_printf("CALCSIZE");
-           break;
-       case ES_ES:
-           break;
-       }
-       estimates = estimates->next;
-       if (estimates)
-           g_printf(", ");
-    }
-    g_printf("\n");
 
-    g_printf("        compress ");
-    switch(dp->compress) {
-    case COMP_NONE:
-       g_printf("NONE\n");
-       break;
-    case COMP_FAST:
-       g_printf("CLIENT FAST\n");
-       break;
-    case COMP_BEST:
-       g_printf("CLIENT BEST\n");
-       break;
-    case COMP_CUST:
-       g_printf("CLIENT CUSTOM\n");
-       g_printf("        client-custom-compress \"%s\"\n",
-                   dp->clntcompprog? dp->clntcompprog : "");
-       break;
-    case COMP_SERVER_FAST:
-       g_printf("SERVER FAST\n");
-       break;
-    case COMP_SERVER_BEST:
-       g_printf("SERVER BEST\n");
-       break;
-    case COMP_SERVER_CUST:
-       g_printf("SERVER CUSTOM\n");
-       g_printf("        server-custom-compress \"%s\"\n",
-                   dp->srvcompprog? dp->srvcompprog : "");
-       break;
-    }
-    if(dp->compress != COMP_NONE) {
-       g_printf("        comprate %.2lf %.2lf\n",
-              dp->comprate[0], dp->comprate[1]);
-    }
-
-    g_printf("        encrypt ");
-    switch(dp->encrypt) {
-    case ENCRYPT_NONE:
-       g_printf("NONE\n");
-       break;
-    case ENCRYPT_CUST:
-       g_printf("CLIENT\n");
-       g_printf("        client-encrypt \"%s\"\n",
-                   dp->clnt_encrypt? dp->clnt_encrypt : "");
-       g_printf("        client-decrypt-option \"%s\"\n",
-                   dp->clnt_decrypt_opt? dp->clnt_decrypt_opt : "");
-       break;
-    case ENCRYPT_SERV_CUST:
-       g_printf("SERVER\n");
-       g_printf("        server-encrypt \"%s\"\n",
-                   dp->srv_encrypt? dp->srv_encrypt : "");
-       g_printf("        server-decrypt-option \"%s\"\n",
-                   dp->srv_decrypt_opt? dp->srv_decrypt_opt : "");
-       break;
-    }
-
-    g_printf("        auth \"%s\"\n", dp->auth);
-    g_printf("        kencrypt %s\n", (dp->kencrypt? "YES" : "NO"));
-    g_printf("        amandad-path \"%s\"\n", dp->amandad_path);
-    g_printf("        client-username \"%s\"\n", dp->client_username);
-    g_printf("        client-port \"%s\"\n", dp->client_port);
-    g_printf("        ssh-keys \"%s\"\n", dp->ssh_keys);
-
-    g_printf("        holdingdisk ");
-    switch(dp->to_holdingdisk) {
-    case HOLD_NEVER:
-       g_printf("NEVER\n");
-       break;
-    case HOLD_AUTO:
-       g_printf("AUTO\n");
-       break;
-    case HOLD_REQUIRED:
-       g_printf("REQUIRED\n");
-       break;
-    }
-
-    g_printf("        record %s\n", (dp->record? "YES" : "NO"));
-    g_printf("        index %s\n", (dp->index? "YES" : "NO"));
-    g_printf("        starttime %04d\n", (int)dp->starttime);
-    if(dp->tape_splitsize > (off_t)0) {
-       g_printf("        tape-splitsize %lld\n",
-              (long long)dp->tape_splitsize);
-    }
-    if(dp->split_diskbuffer) {
-       g_printf("        split-diskbuffer %s\n", dp->split_diskbuffer);
-    }
-    if(dp->fallback_splitsize > (off_t)0) {
-       g_printf("        fallback-splitsize %lldMb\n",
-              (long long)(dp->fallback_splitsize / (off_t)1024));
-    }
-    g_printf("        skip-incr %s\n", (dp->skip_incr? "YES" : "NO"));
-    g_printf("        skip-full %s\n", (dp->skip_full? "YES" : "NO"));
-    g_printf("        allow-split %s\n", (dp->allow_split ? "YES" : "NO"));
-    if (dumptype_seen(dtype, DUMPTYPE_RECOVERY_LIMIT)) {
-       char **rl, **r1;
-       rl = val_t_display_strs(dumptype_getconf((dtype),
-                               DUMPTYPE_RECOVERY_LIMIT), 1);
-       for(r1 = rl; *r1 != NULL; r1++) {
-           g_printf("        recovery-limit %s\n", *r1);
-       free(*r1);
-       }
-    }
-    if (dumptype_seen(dtype, DUMPTYPE_DUMP_LIMIT)) {
-       char **rl, **r1;
-       rl = val_t_display_strs(dumptype_getconf((dtype),
-                               DUMPTYPE_DUMP_LIMIT), 1);
-       for(r1 = rl; *r1 != NULL; r1++) {
-           g_printf("        dump-limit %s\n", *r1);
-       free(*r1);
-       }
-    }
-    g_printf("        spindle %d\n", dp->spindle);
-    pp_scriptlist = dp->pp_scriptlist;
-    while (pp_scriptlist != NULL) {
-       g_printf("        script \"%s\"\n", (char *)pp_scriptlist->data);
-       pp_scriptlist = pp_scriptlist->next;
-    }
-
-    {
-       char **prop, **p1;;
+    dump_dumptype(dtype, "  ", print_default, print_source);
 
-       prop = val_t_display_strs(dumptype_getconf((dtype), DUMPTYPE_PROPERTY),
-                                 0);
-       for(p1 = prop; *p1 != NULL; p1++) {
-           g_printf("        property %s\n", *p1);
-           free(*p1);
-       }
-       amfree(prop);
-    }
+    g_printf("        spindle %d\n", dp->spindle);
 
     g_printf("\n");
 }
@@ -2402,6 +2218,6 @@ void show_config(
     int argc G_GNUC_UNUSED,
     char **argv G_GNUC_UNUSED)
 {
-    dump_configuration();
+    dump_configuration(print_default, print_source);
 }
 
index 3a72bbe0053a0296889163fc22edb45fc589dc91..87331a6fa27a01d07a8f56243addd74e9fc6c232 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2009, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -119,7 +119,12 @@ sub _user_msg_fn {
                 } elsif ($dev->status & $DEVICE_STATUS_VOLUME_UNLABELED and
                          $dev->volume_header and
                          $dev->volume_header->{'type'} == $Amanda::Header::F_WEIRD) {
-                    print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n";
+                   my $autolabel = getconf($CNF_AUTOLABEL);
+                   if ($autolabel->{'non_amanda'}) {
+                       print STDERR " contains a non-Amanda volume\n";
+                   } else {
+                       print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n";
+                   }
                 } elsif ($dev->status & $DEVICE_STATUS_VOLUME_ERROR) {
                     my $message = $dev->error_or_status();
                     print STDERR " Can't read label: $message\n";
@@ -184,7 +189,12 @@ sub do_check {
        if (defined $res->{'device'} and defined $res->{'device'}->volume_label()) {
            print "Will $modestr to volume '$label' in slot $slot.\n";
        } else {
-           print "Will $modestr label '$label' to new volume in slot $slot.\n";
+           my $header = $res->{'device'}->volume_header();
+           if ($header->{'type'} == $Amanda::Header::F_WEIRD) {
+               print "Will $modestr label '$label' to non-Amanda volume in slot $slot.\n";
+           } else {
+               print "Will $modestr label '$label' to new volume in slot $slot.\n";
+           }
        }
 
        $steps->{'check_access_type'}->();
index 937f78dec46cf615beb10a30f59a2e10b50663ee..92382e909f96ec73bf16307b8a000f72a8a87741 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 # 
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published 
@@ -222,7 +222,7 @@ sub find_validation_command {
             "TAR" => [ $Amanda::Constants::GNUTAR, qw(--ignore-zeros -tf -) ],
             "GTAR" => [ $Amanda::Constants::GNUTAR, qw(--ignore-zeros -tf -) ],
             "GNUTAR" => [ $Amanda::Constants::GNUTAR, qw(--ignore-zeros -tf -) ],
-            "SMBCLIENT" => [ $Amanda::Constants::GNUTAR, qw(--ignore-zeros -tf -) ],
+            "SMBCLIENT" => [ $Amanda::Constants::GNUTAR, qw(-tf -) ],
            "PKZIP" => undef,
         );
        if (!exists $validation_programs{$program}) {
@@ -261,7 +261,9 @@ sub main {
     my $all_success = 1;
     my @xfer_errs;
     my %all_filter;
-    my $check_done;
+    my $current_dump;
+    my $recovery_done;
+    my %recovery_params;
 
     my $steps = define_steps
        cb_ref => \$finished_cb,
@@ -340,6 +342,10 @@ sub main {
 
     step check_dumpfile => sub {
        my ($dump) = @_;
+       $current_dump = $dump;
+
+       $recovery_done = 0;
+       %recovery_params = ();
 
        print "Validating image " . $dump->{hostname} . ":" .
            $dump->{diskname} . " dumped " . $dump->{dump_timestamp} . " level ".
@@ -436,8 +442,8 @@ sub main {
                    delete $all_filter{$src};
                    $src->remove();
                    POSIX::close($fd);
-                   if (!%all_filter and $check_done) {
-                       $finished_cb->();
+                   if (!%all_filter and $recovery_done) {
+                       $steps->{'filter_done'}->();
                    }
                } else {
                    $buffer .= $b;
@@ -453,7 +459,7 @@ sub main {
        }
 
        my $xfer = Amanda::Xfer->new([ $xfer_src, @filters, $xfer_dest ]);
-       $xfer->start($steps->{'handle_xmsg'});
+       $xfer->start($steps->{'handle_xmsg'}, 0, $current_dump->{'bytes'});
        $clerk->start_recovery(
            xfer => $xfer,
            recovery_cb => $steps->{'recovery_cb'});
@@ -471,12 +477,17 @@ sub main {
     };
 
     step recovery_cb => sub {
-       my %params = @_;
+       %recovery_params = @_;
+       $recovery_done = 1;
+
+       $steps->{'filter_done'}->() if !%all_filter;
+    };
 
+    step filter_done => sub {
        # distinguish device errors from validation errors
-       if (@{$params{'errors'}}) {
+       if (@{$recovery_params{'errors'}}) {
            print STDERR "While reading from volumes:\n";
-           print STDERR "$_\n" for @{$params{'errors'}};
+           print STDERR "$_\n" for @{$recovery_params{'errors'}};
            return $steps->{'quit'}->("validation aborted");
        }
 
@@ -500,8 +511,8 @@ sub main {
        if ($err) {
            $exit_code = 1;
            print STDERR $err, "\n";
-           return $clerk->quit(finished_cb => $steps->{'quit1'}) if defined $clerk;;
-           return $steps->{'quit1'}->();
+           return $clerk->quit(finished_cb => $finished_cb) if defined $clerk;
+           return $finished_cb->();
        }
 
        if ($all_success) {
@@ -511,16 +522,9 @@ sub main {
            $exit_code = 1;
        }
 
-       return $clerk->quit(finished_cb => $steps->{'quit1'});
+       return $clerk->quit(finished_cb => $finished_cb);
     };
 
-    step quit1 => sub {
-       $check_done = 1;
-
-       if (!%all_filter) {
-           $finished_cb->();
-       }
-    }
 }
 
 main(sub { Amanda::MainLoop::quit(); });
index 915e72fe2a552cd398fc6b8e60b6198072cfcb47..c97f41b523601bc56ec70b920f23ebd056febdf9 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 # 
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published 
index 768e7a8a4e38b855f878949e671c64dbc44eb6be..952c5a62c5bdc194dd674a246ed04ef412ec5044 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 04499f5b89318fe808c3d8e42ab0df02b36b57b8..725fa5b9348b64edbba1c7da474ebb1a37b07963 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7e3bba019787be00a38377a7041431215659c8d7..2778634648770be07a041a569a572a27c4620edc 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index b1e1fb904d638a454c199a1b52981a5749c2d262..652f619b9f21be9daedb783f80a053cf81ace073 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -113,7 +113,10 @@ sub usage {
     my ($msg) = @_;
     print STDERR <<EOF;
 Usage: amfetchdump [-c|-C|-l] [-p|-n] [-a] [-O directory] [-d device]
-    [-h] [--header-file file] [--header-fd fd] [-o configoption]* config
+    [-h|--header-file file|--header-fd fd]i
+    [--decrypt|--no-decrypt|--server-decrypt|--client-decrypt]
+    [--decompress|--no-decompress|--server-decompress|--client-decompress]
+    [-o configoption]* config
     hostname [diskname [datestamp [hostname [diskname [datestamp ... ]]]]]
 EOF
     print STDERR "ERROR: $msg\n" if $msg;
@@ -129,7 +132,16 @@ my $config_overrides = new_config_overrides($#ARGV+1);
 
 my ($opt_config, $opt_no_reassembly, $opt_compress, $opt_compress_best, $opt_pipe,
     $opt_assume, $opt_leave, $opt_blocksize, $opt_device, $opt_chdir, $opt_header,
-    $opt_header_file, $opt_header_fd, @opt_dumpspecs);
+    $opt_header_file, $opt_header_fd, @opt_dumpspecs,
+    $opt_decrypt, $opt_server_decrypt, $opt_client_decrypt,
+    $opt_decompress, $opt_server_decompress, $opt_client_decompress);
+
+my $NEVER = 0;
+my $ALWAYS = 1;
+my $ONLY_SERVER = 2;
+my $ONLY_CLIENT = 3;
+my $decrypt;
+my $decompress;
 
 debug("Arguments: " . join(' ', @ARGV));
 Getopt::Long::Configure(qw(bundling));
@@ -145,6 +157,12 @@ GetOptions(
     'h' => \$opt_header,
     'header-file=s' => \$opt_header_file,
     'header-fd=i' => \$opt_header_fd,
+    'decrypt!' => \$opt_decrypt,
+    'server-decrypt' => \$opt_server_decrypt,
+    'client-decrypt' => \$opt_client_decrypt,
+    'decompress!' => \$opt_decompress,
+    'server-decompress' => \$opt_server_decompress,
+    'client-decompress' => \$opt_client_decompress,
     'b=s' => \$opt_blocksize,
     'd=s' => \$opt_device,
     'O=s' => \$opt_chdir,
@@ -153,11 +171,10 @@ GetOptions(
 usage() unless (@ARGV);
 $opt_config = shift @ARGV;
 
-$opt_compress = 1 if $opt_compress_best;
-
-usage("must specify at least a hostname") unless @ARGV;
-@opt_dumpspecs = Amanda::Cmdline::parse_dumpspecs([@ARGV],
-    $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL);
+if (defined $opt_compress and defined $opt_compress_best) {
+    print STDERR "Can't use -c and -C\n";
+    usage();
+}
 
 usage("The -b option is no longer supported; set readblocksize in the tapetype section\n" .
       "of amanda.conf instead.")
@@ -167,9 +184,85 @@ usage("-l is not compatible with -c or -C")
 usage("-p is not compatible with -n")
     if ($opt_leave and $opt_no_reassembly);
 usage("-h, --header-file, and --header-fd are mutually incompatible")
-    if (($opt_header and $opt_header_file or $opt_header_fd)
+    if (($opt_header and ($opt_header_file or $opt_header_fd))
            or ($opt_header_file and $opt_header_fd));
 
+if (defined $opt_leave) {
+    if (defined $opt_decrypt and $opt_decrypt) {
+       print STDERR "-l is incompatible with --decrypt\n";
+       usage();
+    }
+    if (defined $opt_server_decrypt) {
+       print STDERR "-l is incompatible with --server-decrypt\n";
+       usage();
+    }
+    if (defined $opt_client_decrypt) {
+       print STDERR "-l is incompatible with --client-decrypt\n";
+       usage();
+    }
+    if (defined $opt_decompress and $opt_decompress) {
+       print STDERR "-l is incompatible with --decompress\n";
+       usage();
+    }
+    if (defined $opt_server_decompress) {
+       print STDERR "-l is incompatible with --server-decompress\n";
+       usage();
+    }
+    if (defined $opt_client_decompress) {
+       print STDERR "-l is incompatible with --client-decompress\n";
+       usage();
+    }
+}
+
+if (defined($opt_decrypt) +
+    defined($opt_server_decrypt) +
+    defined($opt_client_decrypt) > 1) {
+    print STDERR "Can't use only on of --decrypt, --no-decrypt, --server-decrypt or --client-decrypt\n";
+    usage();
+}
+if (defined($opt_decompress) +
+    defined($opt_server_decompress) +
+    defined($opt_client_decompress) > 1) {
+    print STDERR "Can't use only on of --decompress, --no-decompress, --server-decompress or --client-decompress\n";
+    usage();
+}
+
+if (defined($opt_compress) and
+    defined($opt_decompress) +
+    defined($opt_server_decompress) +
+    defined($opt_client_decompress) > 0) {
+    print STDERR "Can't specify -c with one of --decompress, --no-decompress, --server-decompress or --client-decompress\n";
+    usage();
+}
+if (defined($opt_compress_best) and
+    defined($opt_decompress) +
+    defined($opt_server_decompress) +
+    defined($opt_client_decompress) > 0) {
+    print STDERR "Can't specify -C with one of --decompress, --no-decompress, --server-decompress or --client-decompress\n";
+    usage();
+}
+
+$decompress = $ALWAYS;
+$decrypt = $ALWAYS;
+$decrypt = $NEVER  if defined $opt_leave;
+$decrypt = $NEVER  if defined $opt_decrypt and !$opt_decrypt;
+$decrypt = $ALWAYS if defined $opt_decrypt and $opt_decrypt;
+$decrypt = $ONLY_SERVER if defined $opt_server_decrypt;
+$decrypt = $ONLY_CLIENT if defined $opt_client_decrypt;
+
+$opt_compress = 1 if $opt_compress_best;
+
+$decompress = $NEVER  if defined $opt_compress;
+$decompress = $NEVER  if defined $opt_leave;
+$decompress = $NEVER  if defined $opt_decompress and !$opt_decompress;
+$decompress = $ALWAYS if defined $opt_decompress and $opt_decompress;
+$decompress = $ONLY_SERVER if defined $opt_server_decompress;
+$decompress = $ONLY_CLIENT if defined $opt_client_decompress;
+
+usage("must specify at least a hostname") unless @ARGV;
+@opt_dumpspecs = Amanda::Cmdline::parse_dumpspecs([@ARGV],
+    $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL);
+
 set_config_overrides($config_overrides);
 config_init($CONFIG_INIT_EXPLICIT_NAME, $opt_config);
 my ($cfgerr_level, @cfgerr_errors) = config_errors();
@@ -205,11 +298,12 @@ use Amanda::MainLoop;
 
 sub new {
     my $class = shift;
-    my ($chg, $dev_name) = @_;
+    my ($chg, $dev_name, $is_tty) = @_;
 
     return bless {
        chg => $chg,
        dev_name => $dev_name,
+       is_tty => $is_tty,
     }, $class;
 }
 
@@ -217,6 +311,7 @@ sub clerk_notif_part {
     my $self = shift;
     my ($label, $filenum, $header) = @_;
 
+    print STDERR "\n" if $self->{'is_tty'};
     print STDERR "amfetchdump: $filenum: restoring ", $header->summary(), "\n";
 }
 
@@ -225,6 +320,7 @@ sub clerk_notif_holding {
     my ($filename, $header) = @_;
 
     # this used to give the fd from which the holding file was being read.. why??
+    print STDERR "\n" if $self->{'is_tty'};
     print STDERR "Reading '$filename'\n", $header->summary(), "\n";
 }
 
@@ -237,7 +333,11 @@ sub main {
     my $plan;
     my @xfer_errs;
     my %all_filter;
-    my $fetch_done;
+    my $recovery_done;
+    my %recovery_params;
+    my $timer;
+    my $is_tty;
+    my $delay;
 
     my $steps = define_steps
        cb_ref => \$finished_cb;
@@ -252,6 +352,13 @@ sub main {
            return failure("Cannot chdir to $destdir: $!", $finished_cb);
        }
 
+       $is_tty = -t STDERR;
+       if($is_tty) {
+           $delay = 1000; # 1 second
+       } else {
+           $delay = 5000; # 5 seconds
+       }
+
        my $interactivity = Amanda::Interactivity::amfetchdump->new();
        # if we have an explicit device, then the clerk doesn't get a changer --
        # we operate the changer via Amanda::Recovery::Scan
@@ -263,7 +370,7 @@ sub main {
                                interactivity => $interactivity);
            return failure($scan, $finished_cb) if $scan->isa("Amanda::Changer::Error");
            $clerk = Amanda::Recovery::Clerk->new(
-               feedback => main::Feedback->new($chg, $opt_device),
+               feedback => main::Feedback->new($chg, $opt_device, $is_tty),
                scan     => $scan);
        } else {
            my $scan = Amanda::Recovery::Scan->new(
@@ -272,7 +379,7 @@ sub main {
 
            $clerk = Amanda::Recovery::Clerk->new(
                changer => $chg,
-               feedback => main::Feedback->new($chg, undef),
+               feedback => main::Feedback->new($chg, undef, $is_tty),
                scan     => $scan);
        }
 
@@ -294,6 +401,7 @@ sub main {
 
        # if we are doing a -p operation, only keep the first dump
        if ($opt_pipe) {
+           print STDERR "WARNING: Fetch first dump only because of -p argument\n" if @{$plan->{'dumps'}} > 1;
            @{$plan->{'dumps'}} = ($plan->{'dumps'}[0]);
        }
 
@@ -321,10 +429,14 @@ sub main {
 
     step start_dump => sub {
        $current_dump = shift @{$plan->{'dumps'}};
+
        if (!$current_dump) {
            return $steps->{'finished'}->();
        }
 
+       $recovery_done = 0;
+       %recovery_params = ();
+
        $clerk->get_xfer_src(
            dump => $current_dump,
            xfer_src_cb => $steps->{'xfer_src_cb'});
@@ -359,11 +471,25 @@ sub main {
            }
        }
 
+       $timer = Amanda::MainLoop::timeout_source($delay);
+       $timer->set_callback(sub {
+           my $size = $xfer_src->get_bytes_read();
+           if ($is_tty) {
+               print STDERR "\r" . int($size/1024) . " kb ";
+           } else {
+               print STDERR "READ SIZE: " . int($size/1024) . " kb\n";
+           }
+       });
+
        my $xfer_dest = Amanda::Xfer::Dest::Fd->new($dest_fh);
 
+       my $dle = $hdr->get_dle();
+
        # set up any filters that need to be applied; decryption first
        my @filters;
-       if ($hdr->{'encrypted'} and not $opt_leave) {
+       if ($hdr->{'encrypted'} and
+           (($hdr->{'srv_encrypt'} and ($decrypt == $ALWAYS || $decrypt == $ONLY_SERVER)) ||
+            ($hdr->{'clnt_encrypt'} and ($decrypt == $ALWAYS || $decrypt == $ONLY_CLIENT)))) {
            if ($hdr->{'srv_encrypt'}) {
                push @filters,
                    Amanda::Xfer::Filter::Process->new(
@@ -385,16 +511,23 @@ sub main {
            $hdr->{'encrypt_suffix'} = 'N';
        }
 
-       if ($hdr->{'compressed'} and not $opt_compress and not $opt_leave) {
+       if ($hdr->{'compressed'} and not $opt_compress and
+           (($hdr->{'srvcompprog'} and ($decompress == $ALWAYS || $decompress == $ONLY_SERVER)) ||
+            ($hdr->{'clntcompprog'} and ($decompress == $ALWAYS || $decompress == $ONLY_CLIENT)) ||
+            ($dle->{'compress'} == $Amanda::Config::COMP_SERVER_FAST and ($decompress == $ALWAYS || $decompress == $ONLY_SERVER)) ||
+            ($dle->{'compress'} == $Amanda::Config::COMP_SERVER_BEST and ($decompress == $ALWAYS || $decompress == $ONLY_SERVER)) ||
+            ($dle->{'compress'} == $Amanda::Config::COMP_FAST and ($decompress == $ALWAYS || $decompress == $ONLY_CLIENT)) ||
+            ($dle->{'compress'} == $Amanda::Config::COMP_BEST and ($decompress == $ALWAYS || $decompress == $ONLY_CLIENT)))) {
            # need to uncompress this file
-
-           if ($hdr->{'srvcompprog'}) {
-               # TODO: this assumes that srvcompprog takes "-d" to decrypt
+           if ($hdr->{'encrypted'}) {
+               print "Not decompressing because the backup image is not decrypted\n";
+           } elsif ($hdr->{'srvcompprog'}) {
+               # TODO: this assumes that srvcompprog takes "-d" to decompress
                push @filters,
                    Amanda::Xfer::Filter::Process->new(
                        [ $hdr->{'srvcompprog'}, "-d" ], 0);
            } elsif ($hdr->{'clntcompprog'}) {
-               # TODO: this assumes that clntcompprog takes "-d" to decrypt
+               # TODO: this assumes that clntcompprog takes "-d" to decompress
                push @filters,
                    Amanda::Xfer::Filter::Process->new(
                        [ $hdr->{'clntcompprog'}, "-d" ], 0);
@@ -458,8 +591,8 @@ sub main {
                    delete $all_filter{$src};
                    $src->remove();
                    POSIX::close($fd);
-                   if (!%all_filter and $fetch_done) {
-                       $finished_cb->();
+                   if (!%all_filter and $recovery_done) {
+                       $steps->{'filter_done'}->();
                    }
                } else {
                    $buffer .= $b;
@@ -493,14 +626,24 @@ sub main {
     };
 
     step recovery_cb => sub {
-       my %params = @_;
+       %recovery_params = @_;
+       $recovery_done = 1;
+
+       $steps->{'filter_done'}->() if !%all_filter;
+    };
 
-       @xfer_errs = (@xfer_errs, @{$params{'errors'}})
-           if $params{'errors'};
+    step filter_done => sub {
+       if ($is_tty) {
+           print STDERR "\r" . int($recovery_params{'bytes_read'}/1024) . " kb ";
+       } else {
+           print STDERR "READ SIZE: " . int($recovery_params{'bytes_read'}/1024) . " kb\n";
+       }
+       @xfer_errs = (@xfer_errs, @{$recovery_params{'errors'}})
+           if $recovery_params{'errors'};
        return failure(join("; ", @xfer_errs), $finished_cb)
            if @xfer_errs;
        return failure("recovery failed", $finished_cb)
-           if $params{'result'} ne 'DONE';
+           if $recovery_params{'result'} ne 'DONE';
 
        $steps->{'start_dump'}->();
     };
@@ -516,13 +659,14 @@ sub main {
     step quit => sub {
        my ($err) = @_;
 
+       if (defined $timer) {
+           $timer->remove();
+           $timer = undef;
+       }
+       print STDERR "\n" if $is_tty;
        return failure($err, $finished_cb) if $err;
 
-#do all filter are done reading stderr
-       $fetch_done = 1;
-        if (!%all_filter) {
-           $finished_cb->();
-       }
+       $finished_cb->();
     };
 }
 
index 855d59a1f867d396720e287d766c5d8e4eebc268..54fe4bd07aa0cd369d454a645dec3370ba9ee420 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -403,6 +403,7 @@ sub make_plan {
 
        return Amanda::Recovery::Planner::make_plan(
            filelist => $filelist,
+           chg => $chg,
            $spec? (dumpspec => $spec) : (),
            plan_cb => sub { $self->plan_cb(@_); });
     }
@@ -546,7 +547,6 @@ sub xfer_src_cb {
     if ($header->{'compressed'}) {
        # need to uncompress this file
        debug("..with decompression applied");
-       my $dle = $header->get_dle();
 
        if ($header->{'srvcompprog'}) {
            # TODO: this assumes that srvcompprog takes "-d" to decrypt
@@ -569,9 +569,11 @@ sub xfer_src_cb {
                $header->{'clntcompprog'} = '';
            }
        } else {
-           if (!$self->{'their_features'}->has($Amanda::Feature::fe_amrecover_receive_unfiltered) ||
-               $dle->{'compress'} == $Amanda::Config::COMP_SERVER_FAST ||
-               $dle->{'compress'} == $Amanda::Config::COMP_SERVER_BEST) {
+           my $dle = $header->get_dle();
+           if ($dle &&
+               (!$self->{'their_features'}->has($Amanda::Feature::fe_amrecover_receive_unfiltered) ||
+                $dle->{'compress'} == $Amanda::Config::COMP_SERVER_FAST ||
+                $dle->{'compress'} == $Amanda::Config::COMP_SERVER_BEST)) {
                push @filters,
                    Amanda::Xfer::Filter::Process->new(
                        [ $Amanda::Constants::UNCOMPRESS_PATH,
index bc56ed4f48cbedb83c61ce97b7ab5f95112ab6b7..91d7db69d6761e5e1747179eba869c14dc34d10f 100644 (file)
@@ -282,9 +282,16 @@ uncompress_file(
 
        /* start the sort process */
        putenv(stralloc("LC_ALL=C"));
-       pid_sort = pipespawn(SORT_PATH, STDIN_PIPE|STDERR_PIPE, 0,
-                            &pipe_to_sort, &indexfd, &sort_errfd,
-                            SORT_PATH, NULL);
+       if (getconf_seen(CNF_TMPDIR)) {
+           gchar *tmpdir = getconf_str(CNF_TMPDIR);
+           pid_sort = pipespawn(SORT_PATH, STDIN_PIPE|STDERR_PIPE, 0,
+                                &pipe_to_sort, &indexfd, &sort_errfd,
+                                SORT_PATH, "-T", tmpdir, NULL);
+       } else {
+           pid_sort = pipespawn(SORT_PATH, STDIN_PIPE|STDERR_PIPE, 0,
+                                &pipe_to_sort, &indexfd, &sort_errfd,
+                                SORT_PATH, NULL);
+       }
        aclose(indexfd);
 
        /* start a subprocess */
index 98c5c7847204baec25c77c99a60b3e0d7cb14f7b..a054975936fb18ea06041e6d60bf07cf9fa3a3fa 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 9611a8a39ca118f6cf00b126005ee8b52c4c9fd2..bc5cdcce186213bb832b231433af8258dacf95e3 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f5e5b31d4adfbbfb0006f48698590186fdaa43ac..54d8153130ce1c3f5b2fe887181a15bb51505256 100644 (file)
@@ -1,5 +1,5 @@
 #!@PERL@
-# Copyright (c) 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index ae73bab9587158c6794050c95b8f0e272bdcb0bb..cd0432fab3e0c51c8c8f676fe607e211397b8b8e 100755 (executable)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 362ee65d8e105f023522bee82000edd1715fa7c9..879aec434f1431460b8a2afe531d22e1eb764160 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -173,6 +173,16 @@ sub main {
        return failure($err, $finished_cb) if $err;
 
        $dev = $res->{'device'};
+
+       if ($opt_blocksize) {
+           if ( !$dev->property_set("BLOCK_SIZE", $opt_blocksize)) {
+               return failure($dev->error_or_status, $finished_cb);
+           }
+
+           # re-read the label with the correct blocksize
+           $dev->read_label();
+       }
+
        if ($dev->status != $DEVICE_STATUS_SUCCESS) {
            return failure($dev->error_or_status, $finished_cb);
        }
index 7c052a52216f16b1752d13d223157450d2779305..f7d37081a4c60ade7f8adc7651a4d0534d86f09c 100644 (file)
@@ -1,6 +1,6 @@
 #!@PERL@
 #
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 3c53a8811697e031270f92130d73a84756709c99..a05dd18b2b124949bda68f3af3e2f1eea3599498 100755 (executable)
@@ -1,6 +1,6 @@
 #!@PERL@
 #
-# Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index 7192e181e1605b63b5e8b0ccd2ba381851708385..443e7e503f43bea075b8f53c50db38432cab8c51 100644 (file)
@@ -259,8 +259,8 @@ while($lineX = <AMDUMP>) {
                        $dump_started{$hostpart}=-1;
                        $level{$hostpart}=$line[5];
                        $error{$hostpart}="planner: " . $line[6];
-       } elsif($line[1] eq "time") {
-               if($line[3] eq "got") {
+       } elsif($line[1] eq "time") {
+               if($line[3] eq "got") {
                                if($line[4] eq "result") {
                                        $host = $line[7];
                                        $partition = $line[9];
@@ -410,6 +410,7 @@ while($lineX = <AMDUMP>) {
                                        }
                                        $running_dumper{$dumper} = $hostpart;
                                        $error{$hostpart}="";
+                                       $taper_error{$hostpart}="";
                                        $size{$hostpart} = 0;
                                        $dumpers_active++;
                                        if(! defined($dumpers_active[$dumpers_active])) {
@@ -483,6 +484,7 @@ while($lineX = <AMDUMP>) {
                                        $taper_started{$hostpart}=1;
                                        $taper_finished{$hostpart}=0;
                                        $taper_time{$hostpart}=$current_time;
+                                       $taper_error{$hostpart}="";
                                        $ntchunk_size = 0;
                                }
                                elsif($line[6] eq "PORT-WRITE") {
@@ -498,6 +500,7 @@ while($lineX = <AMDUMP>) {
                                        $taper_started{$hostpart}=1;
                                        $taper_finished{$hostpart}=0;
                                        $taper_time{$hostpart}=$current_time;
+                                       $taper_error{$hostpart}="";
                                        $size{$hostpart} = 0;
                                        $ntchunk_size = 0;
                                }
@@ -518,10 +521,12 @@ while($lineX = <AMDUMP>) {
                                                $dump_finished{$hostpart}=-3;
                                        }
                                        $busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
-                             $running_dumper{$line[5]} = "0";
-                             $dump_time{$hostpart}=$current_time;
-                             $error{$hostpart}="dumper: $error";
-                             $dumpers_active--;
+                                       $running_dumper{$line[5]} = "0";
+                                       $dump_time{$hostpart}=$current_time;
+                                       if (!$taper_error{$hostpart}) {
+                                               $error{$hostpart}="dumper: $error";
+                                       }
+                                       $dumpers_active--;
 
                                }
                                elsif($line[6] eq "DONE") {
@@ -597,15 +602,16 @@ while($lineX = <AMDUMP>) {
                        }
                        elsif($line[5] eq "taper") {
                                if($line[6] eq "DONE" || $line[6] eq "PARTIAL") {
-                                       #7:handle 8:label 9:filenum 10:errstr
+                                       #DONE:    7:handle 8:label 9:filenum 10:errstr
+                                       #PARTIAL: 7:handle 8:INPUT-* 9:TAPE-* 10:errstr 11:INPUT-MSG 12:TAPE-MSG
                                        $serial=$line[7];
-                                       $label=$line[8];
+
                                        $status_taper = "Idle";
                                        $hostpart=$serial{$serial};
                                        $line[10] =~ /sec (\S+) (kb|bytes) (\d+) kps/;
                                        if ($2 eq 'kb') {
                                                $size=$3 / $unitdivisor;
-                                  } else {
+                                       } else {
                                                $size=$3 / ( $unitdivisor * 1024);
                                        }
                                        $taper_finished{$hostpart}=1;
@@ -624,6 +630,10 @@ while($lineX = <AMDUMP>) {
                                        }
                                        if ($line[6] eq "PARTIAL") {
                                                $partial{$hostpart} = 1;
+                                               if ($line[9] eq "TAPE-ERROR") {
+                                                       $error{$hostpart} = "taper: $line[12]";
+                                                       $taper_error{$hostpart} = "taper: $line[12]";
+                                               }
                                        }
                                        else {
                                                $partial{$hostpart} = 0;
@@ -933,7 +943,7 @@ foreach $host (sort @hosts) {
                                                $taper_started{$hostpart}==1 &&
                                                $dump_finished{$hostpart}!=-3) {
                                        if(defined $dump_started{$hostpart} &&
-                                               $dump_started{$hostpart} == 1 &&
+                                               $dump_started{$hostpart} == 1 &&
                                                        $dump_finished{$hostpart} == -1) {
                                                if(defined $opt_failed) {
                                                        printf "%8s ", $datestamp if defined $opt_date;
@@ -946,7 +956,7 @@ foreach $host (sort @hosts) {
                                                $fpartition++;
                                                $fsize+=$esize{$hostpart};
                                        } elsif(defined $dump_started{$hostpart} &&
-                                               $dump_started{$hostpart} == 1 &&
+                                               $dump_started{$hostpart} == 1 &&
                                                        $dump_finished{$hostpart} == 0 &&
                                                        $taper_started{$hostpart} == 1) {
                                                if( defined $opt_dumpingtape ||
@@ -995,6 +1005,7 @@ foreach $host (sort @hosts) {
                                                                $exit_status |= $STATUS_FAILED;
                                                        }
                                                        if($in_flush == 0) {
+                                                               print " dump done," if defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1;
                                                                print " writing to tape";
                                                        }
                                                        else {
@@ -1065,6 +1076,7 @@ foreach $host (sort @hosts) {
                                                        printf "%8s ", $datestamp if defined $opt_date;
                                                        printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
                                                        printf "%9d$unit", $xsize;
+                                                   print " dump done," if defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1;
                                                        if($in_flush == 0) {
                                                                print " failed to tape";
                                                        }
@@ -1072,7 +1084,7 @@ foreach $host (sort @hosts) {
                                                                print " failed to flush";
                                                        }
                                                        print ": ",$error{$hostpart} if defined $error{$hostpart};
-                                               
+
                                                        print " (will retry)" unless $taper_finished{$hostpart} < -1;
                                                        if( defined $starttime ) {
                                                                print " (", &showtime($taper_time{$hostpart}), ")";
index bb290014808ccca54956d6ba4ad41cc1e6097bfd..dec31ea6e62c7fad61f3913a009f95689b72a2d0 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -550,7 +550,12 @@ sub {
                } elsif ($dev->status & $DEVICE_STATUS_VOLUME_UNLABELED and
                         $dev->volume_header and
                         $dev->volume_header->{'type'} == $Amanda::Header::F_WEIRD) {
-                   print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n";
+                   my $autolabel = getconf($CNF_AUTOLABEL);
+                   if ($autolabel->{'non_amanda'}) {
+                       print STDERR " contains a non-Amanda volume\n";
+                   } else {
+                       print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n";
+                   }
                } elsif ($dev->status & $DEVICE_STATUS_VOLUME_ERROR) {
                    my $message = $dev->error_or_status();
                    print STDERR " can't read label: $message\n";
@@ -594,7 +599,12 @@ sub {
        if (defined $res->{'device'} and defined $res->{'device'}->volume_label()) {
            print STDERR "Will $modestr to volume '$label' in slot $slot.\n";
        } else {
-           print STDERR "Will $modestr label '$label' to new volume in slot $slot.\n";
+           my $header = $res->{'device'}->volume_header();
+           if ($header->{'type'} == $Amanda::Header::F_WEIRD) {
+               print STDERR "Will $modestr label '$label' to non-Amanda volume in slot $slot.\n";
+           } else {
+               print STDERR "Will $modestr label '$label' to new volume in slot $slot.\n";
+           }
        }
        $res->release(finished_cb => sub {
            my ($err) = @_;
index 87a43fb95790c2aacf3c5862a2062f37ff6adb51..88111f7c9728b3324ce4e4d9911f450c235fd474 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -141,6 +141,7 @@ sub new {
        exporting => 0, # is an export in progress?
        call_after_export => undef, # call this when export complete
        config_overrides_opts => $params{'config_overrides_opts'},
+       trace_log_filename => getconf($CNF_LOGDIR) . "/log",
 
        # called when the operation is complete, with the exit
        # status
@@ -148,6 +149,47 @@ sub new {
     }, $class;
 }
 
+sub run_subprocess {
+    my ($proc, @args) = @_;
+
+    my $pid = POSIX::fork();
+    if ($pid == 0) {
+       my $null = POSIX::open("/dev/null", POSIX::O_RDWR);
+       POSIX::dup2($null, 0);
+       POSIX::dup2($null, 1);
+       POSIX::dup2($null, 2);
+       exec $proc, @args;
+       die "Could not exec $proc: $!";
+    }
+    waitpid($pid, 0);
+    my $s = $? >> 8;
+    debug("$proc exited with code $s: $!");
+}
+
+sub do_amcleanup {
+    my $self = shift;
+
+    return 1 unless -f $self->{'trace_log_filename'};
+
+    # logfiles are still around.  First, try an amcleanup -p to see if
+    # the actual processes are already dead
+    debug("runing amcleanup -p");
+    run_subprocess("$sbindir/amcleanup", '-p', $self->{'config_name'},
+                  $self->{'config_overrides_opts'});
+
+    return 1 unless -f $self->{'trace_log_filename'};
+
+    return 0;
+}
+
+sub bail_already_running() {
+    my $self = shift;
+    my $msg = "An Amanda process is already running - please run amcleanup manually";
+    print "$msg\n";
+    debug($msg);
+    $self->{'exit_cb'}->(1);
+}
+
 sub run {
     my $self = shift;
     my ($exit_cb) = @_;
@@ -163,7 +205,20 @@ sub run {
 
     # open up a trace log file and put our imprimatur on it, unless dry_runing
     if (!$self->{'opt_dry_run'}) {
+       if (!$self->do_amcleanup()) {
+           return $self->bail_already_running();
+       }
        log_add($L_INFO, "amvault pid $$");
+
+       # Check we own the log file
+       open(my $tl, "<", $self->{'trace_log_filename'})
+           or die("could not open trace log file '$self->{'trace_log_filename'}': $!");
+       if (<$tl> !~ /^INFO amvault amvault pid $$/) {
+           debug("another amdump raced with this one, and won");
+           close($tl);
+           return $self->bail_already_running();
+       }
+       close($tl);
        log_add($L_START, "date " . $self->{'dst_write_timestamp'});
        Amanda::Debug::add_amanda_log_handler($amanda_log_trace_log);
        $self->{'cleanup'}{'roll_trace_log'} = 1;
@@ -249,7 +304,7 @@ sub setup_src {
        # convert the timestamp and level to a dumpspec
        my $level = $self->{'fulls_only'}? "0" : undef;
        push @dumpspecs, Amanda::Cmdline::dumpspec_t->new(
-               undef, undef, $self->{'src_write_timestamp'}, $level, undef);
+               undef, undef, undef, $level, $self->{'src_write_timestamp'});
     }
 
     # if we ignored all of the dumpspecs and didn't create any, then dump
index 28a842f73158997ebd24db81912d8a22c2dbfe88..600d50060477ff221816c2e4618aac15f5db0b0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 2806c1ad80a434dc068becd7421b4f57896651a8..b1e6cad93f49cba9aa7550cd68289e0c36a2cad1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007,2008 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index b25b749af1a7705d0d5f445a26169e2189dd2ef6..544346a66e7d307d461cf005fe1fe908a834fd46 100644 (file)
@@ -205,6 +205,7 @@ add_disk(
     bzero(disk, SIZEOF(disk_t));
     disk->line = 0;
     disk->allow_split = 0;
+    disk->max_warnings = 20;
     disk->splitsize = (off_t)0;
     disk->tape_splitsize = (off_t)0;
     disk->split_diskbuffer = NULL;
@@ -687,6 +688,7 @@ parse_diskline(
     disk->auth               = dumptype_get_auth(dtype);
     disk->maxdumps          = dumptype_get_maxdumps(dtype);
     disk->allow_split        = dumptype_get_allow_split(dtype);
+    disk->max_warnings       = dumptype_get_max_warnings(dtype);
     disk->tape_splitsize     = dumptype_get_tape_splitsize(dtype);
     disk->split_diskbuffer   = dumptype_get_split_diskbuffer(dtype);
     disk->fallback_splitsize = dumptype_get_fallback_splitsize(dtype);
index 28ed50e8edcba795a9623252d1e49dc26b6b3874..f4b930e6481c49c136e20a8269a9118f145b1933 100644 (file)
@@ -79,14 +79,15 @@ typedef struct disk_s {
     char       *client_username;       /* username to connect on the client */
     char       *client_port;           /* port to connect on the client */
     char       *ssh_keys;              /* ssh_key file to use */
-    sl_t       *exclude_file;          /* file exclude spec */
-    sl_t       *exclude_list;          /* exclude list */
-    sl_t       *include_file;          /* file include spec */
-    sl_t       *include_list;          /* include list */
+    am_sl_t    *exclude_file;          /* file exclude spec */
+    am_sl_t    *exclude_list;          /* exclude list */
+    am_sl_t    *include_file;          /* file include spec */
+    am_sl_t    *include_list;          /* include list */
     int                exclude_optional;       /* exclude list are optional */
     int                include_optional;       /* include list are optional */
     int                priority;               /* priority of disk */
     int                allow_split;
+    int         max_warnings;
     off_t      splitsize;
     off_t      tape_splitsize;         /* size of dumpfile chunks on tape */
     char       *split_diskbuffer;      /* place where we can buffer PORT-WRITE dumps other than RAM */
index 5560171f205e894d23154f9dfd4ae62b7081082c..af5095ab93a8715c3a50fee552bcb1c1aca19b89 100644 (file)
@@ -1949,7 +1949,7 @@ handle_taper_result(
            for (taper = tapetable;
                 taper < tapetable + conf_taper_parallel_write;
                  taper++) {
-               if (taper && taper->disk && taper->result != LAST_TOK) {
+               if (taper && taper->disk) {
                    taper->tape_error = newstralloc(taper->tape_error,"BOGUS");
                    taper->result = cmd;
                    if (taper->dumper) {
@@ -2477,14 +2477,12 @@ handle_dumper_result(
                dumper->chunker->result != LAST_TOK)
                dumper_chunker_result(dp);
        } else { /* send the dumper result to the taper */
-           if (taper->sendresult) {
-               if (cmd == DONE) {
-                   taper_cmd(DONE, dp, NULL, 0, NULL);
-               } else {
-                   taper_cmd(FAILED, dp, NULL, 0, NULL);
-               }
-               taper->sendresult = 0;
+           if (cmd == DONE) {
+               taper_cmd(DONE, dp, NULL, 0, NULL);
+           } else {
+               taper_cmd(FAILED, dp, NULL, 0, NULL);
            }
+           taper->sendresult = 0;
            if (taper->dumper && taper->result != LAST_TOK) {
                dumper_taper_result(dp);
            }
@@ -3756,19 +3754,19 @@ tape_action(
        if (dumper->busy && !sched(dumper->dp)->taper)
            dumpers_size += sched(dumper->dp)->est_size;
     }
-    driver_debug(1, _("dumpers_size: %lld\n"), (long long)dumpers_size);
+    driver_debug(2, _("dumpers_size: %lld\n"), (long long)dumpers_size);
 
     runq_size = 0;
     for(dp = runq.head; dp != NULL; dp = dp->next) {
        runq_size += sched(dp)->est_size;
     }
-    driver_debug(1, _("runq_size: %lld\n"), (long long)runq_size);
+    driver_debug(2, _("runq_size: %lld\n"), (long long)runq_size);
 
     directq_size = 0;
     for(dp = directq.head; dp != NULL; dp = dp->next) {
        directq_size += sched(dp)->est_size;
     }
-    driver_debug(1, _("directq_size: %lld\n"), (long long)directq_size);
+    driver_debug(2, _("directq_size: %lld\n"), (long long)directq_size);
 
     tapeq_size = directq_size;
     for(dp = tapeq.head; dp != NULL; dp = dp->next) {
@@ -3800,7 +3798,11 @@ tape_action(
            if (data_to_go > taper1->left) {
                data_next_tape += data_to_go - taper1->left;
                data_lost += taper1->written + taper1->left;
-               dle_free--;
+               if (taper1->state & TAPER_STATE_TAPE_STARTED) {
+                   dle_free--;
+               } else {
+                   dle_free += conf_max_dle_by_volume - 2;
+               }
            } else {
                data_free += taper1->left - data_to_go;
            }
@@ -3808,18 +3810,19 @@ tape_action(
        }
     }
     data_lost_next_tape = tape_length + data_free - data_next_tape - runq_size - directq_size - tapeq_size;
-    driver_debug(1, _("data_lost: %lld\n"), (long long)data_lost);
-    driver_debug(1, _("data_free: %lld\n"), (long long)data_free);
-    driver_debug(1, _("data_next_tape: %lld\n"), (long long)data_next_tape);
-    driver_debug(1, _("data_lost_next_tape: %lld\n"), (long long)data_lost_next_tape);
+    driver_debug(2, _("dle_free: %d\n"), dle_free);
+    driver_debug(2, _("data_lost: %lld\n"), (long long)data_lost);
+    driver_debug(2, _("data_free: %lld\n"), (long long)data_free);
+    driver_debug(2, _("data_next_tape: %lld\n"), (long long)data_next_tape);
+    driver_debug(2, _("data_lost_next_tape: %lld\n"), (long long)data_lost_next_tape);
 ;
-    driver_debug(1, _("tapeq_size: %lld\n"), (long long)tapeq_size);
+    driver_debug(2, _("tapeq_size: %lld\n"), (long long)tapeq_size);
 
     sched_size = runq_size + directq_size + tapeq_size + dumpers_size;
-    driver_debug(1, _("sched_size: %lld\n"), (long long)sched_size);
+    driver_debug(2, _("sched_size: %lld\n"), (long long)sched_size);
 
     dump_to_disk_size = dumpers_size + runq_size + directq_size;
-    driver_debug(1, _("dump_to_disk_size: %lld\n"), (long long)dump_to_disk_size);
+    driver_debug(2, _("dump_to_disk_size: %lld\n"), (long long)dump_to_disk_size);
 
     dump_to_disk_terminated = schedule_done && dump_to_disk_size == 0;
 
@@ -3835,11 +3838,16 @@ tape_action(
                           (dle_free < (queue_length(runq) +
                                        queue_length(directq) +
                                        queue_length(tapeq)));
+    driver_debug(2, "queue_length(runq) %d\n", queue_length(runq));
+    driver_debug(2, "queue_length(directq) %d\n", queue_length(directq));
+    driver_debug(2, "queue_length(tapeq) %d\n", queue_length(tapeq));
+    driver_debug(2, "allow_size_or_number %d\n", allow_size_or_number);
 
     // Changing conditionals can produce a driver hang, take care.
     // 
     // when to start writting to a new tape
     if (taper->state & TAPER_STATE_TAPE_REQUESTED) {
+       driver_debug(2, "tape_action: TAPER_STATE_TAPE_REQUESTED\n");
        if (current_tape >= conf_runtapes && taper_nb_scan_volume == 0 &&
            nb_taper_active == 0) {
            *why_no_new_tape = g_strdup_printf(_("%d tapes filled; runtapes=%d "
@@ -3867,6 +3875,7 @@ tape_action(
          (force_flush == 1 ||                          //  if force_flush
           dump_to_disk_terminated))                    //  or all dump to disk terminated
        )) {
+       driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NEW_TAPE\n");
        result |= TAPE_ACTION_NEW_TAPE;
     // when to stop using new tape
     } else if ((taper->state & TAPER_STATE_WAIT_FOR_TAPE) &&
@@ -3874,19 +3883,24 @@ tape_action(
               (force_flush == 1 ||                     //  if force_flush
                dump_to_disk_terminated))               //  or all dump to disk
              ) {
+       driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE B\n");
        if (nb_taper_active <= 0) {
            if (current_tape >= conf_runtapes) {
                *why_no_new_tape = g_strdup_printf(_("%d tapes filled; runtapes=%d "
                      "does not allow additional tapes"), current_tape, conf_runtapes);
-           } else {
+               driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NO_NEW_TAPE\n");
+               result |= TAPE_ACTION_NO_NEW_TAPE;
+           } else if (dumpers_size <= 0) {
                *why_no_new_tape = _("taperflush criteria not met");
+               driver_debug(2, "tape_action: TAPER_STATE_WAIT_FOR_TAPE return TAPE_ACTION_NO_NEW_TAPE\n");
+               result |= TAPE_ACTION_NO_NEW_TAPE;
            }
-           result |= TAPE_ACTION_NO_NEW_TAPE;
        }
     }
 
     // when to start a flush
     if (taper->state & TAPER_STATE_IDLE) {
+       driver_debug(2, "tape_action: TAPER_STATE_IDLE\n");
        if (!degraded_mode && (!empty(tapeq) || !empty(directq)) &&
            (taper->state & TAPER_STATE_TAPE_STARTED ||         // tape already started 
              !empty(roomq) ||                                  // holding disk constraint
index 57782754606b943b9410bf5a930cc72ff9329864..c2632eb22ba2ebef7b42e91f58d062c2c559e9a4 100644 (file)
@@ -574,6 +574,7 @@ dumper_cmd(
     char *cmdline = NULL;
     char number[NUM_STR_SIZE];
     char numberport[NUM_STR_SIZE];
+    char maxwarnings[NUM_STR_SIZE];
     char *o, *oo;
     char *device;
     char *features;
@@ -611,6 +612,7 @@ dumper_cmd(
            qname = quote_string(dp->name);
            g_snprintf(number, SIZEOF(number), "%d", sched(dp)->level);
            g_snprintf(numberport, SIZEOF(numberport), "%d", dumper->output_port);
+           g_snprintf(maxwarnings, SIZEOF(maxwarnings), "%d", dp->max_warnings);
            features = am_feature_to_string(dp->host->features);
            if (am_has_feature(dp->host->features, fe_req_xml)) {
                o = xml_optionstr(dp, 1);
@@ -664,6 +666,7 @@ dumper_cmd(
                            " ", dp->auth,
                            " ", data_path_to_string(dp->data_path),
                            " ", dp->dataport_list,
+                           " ", maxwarnings,
                            " |", o,
                            "\n", NULL);
            amfree(qplugin);
index 32f9258780d457650c3d2f575c34f646b875a734..d9fd9ca52df3afa7965525f643e16fe47697ecbf 100644 (file)
@@ -73,6 +73,8 @@ struct databuf {
     pid_t encryptpid;          /* valid if fd is pipe to encrypt */
 };
 
+struct databuf *g_databuf = NULL;
+
 typedef struct filter_s {
     int             fd;
     char           *name;
@@ -124,6 +126,7 @@ static int set_datafd;
 static char *dle_str = NULL;
 static char *errfname = NULL;
 static int   errf_lines = 0;
+static int   max_warnings = 0;
 
 static dumpfile_t file;
 
@@ -535,6 +538,11 @@ main(
            }
            dataport_list = newstralloc(dataport_list, cmdargs->argv[a++]);
 
+           if(a >= cmdargs->argc) {
+               error(_("error [dumper PORT-DUMP: not enough args: max_warnings]"));
+           }
+           max_warnings = atoi(cmdargs->argv[a++]);
+
            if(a >= cmdargs->argc) {
                error(_("error [dumper PORT-DUMP: not enough args: options]"));
            }
@@ -576,6 +584,7 @@ main(
                break;
            }
            databuf_init(&db, outfd);
+           g_databuf = &db;
 
            if (am_has_feature(their_features, fe_req_xml))
                xml_check_options(options); /* note: modifies globals */
@@ -1006,14 +1015,18 @@ log_msgout(
 {
     char *line;
     int   count = 0;
+    int   to_unlink = 1;
 
     fflush(errf);
     if (fseeko(errf, 0L, SEEK_SET) < 0) {
        dbprintf(_("log_msgout: warning - seek failed: %s\n"), strerror(errno));
     }
     while ((line = agets(errf)) != NULL) {
-       if (errf_lines >= 100 && count >= 20)
+       if (max_warnings > 0 && errf_lines >= max_warnings && count >= max_warnings) {
+           log_add(typ, "Look in the '%s' file for full error messages", errfname);
+           to_unlink = 0;
            break;
+       }
        if (line[0] != '\0') {
                log_add(typ, "%s", line);
        }
@@ -1022,11 +1035,7 @@ log_msgout(
     }
     amfree(line);
 
-    if (errf_lines >= 100) {
-       log_add(typ, "Look in the '%s' file for full error messages", errfname);
-    }
-
-    return errf_lines < 100;
+    return to_unlink;
 }
 
 /* ------------- */
@@ -1889,6 +1898,7 @@ stop_dump(void)
        }
     }
     aclose(indexout);
+    aclose(g_databuf->fd);
     timeout(0);
 }
 
@@ -1925,6 +1935,12 @@ runcompress(
        return (-1);
     }
 
+    if (comptype != COMP_SERVER_CUST) {
+       g_debug("execute: %s %s", COMPRESS_PATH,
+               comptype == COMP_BEST ? COMPRESS_BEST_OPT : COMPRESS_FAST_OPT);
+    } else {
+       g_debug("execute: %s", srvcompprog);
+    }
     switch (*pid = fork()) {
     case -1:
        errstr = newvstrallocf(errstr, _("couldn't fork: %s"), strerror(errno));
@@ -1948,7 +1964,6 @@ runcompress(
        filter->allocated_size = 0;
        filter->event = event_register((event_id_t)filter->fd, EV_READFD,
                                       handle_filter_stderr, filter);
-g_debug("event register %s %d", name, filter->fd);
        return (rval);
     case 0:
        close(outpipe[1]);
@@ -2021,6 +2036,7 @@ runencrypt(
        return (-1);
     }
 
+    g_debug("execute: %s", srv_encrypt);
     switch (*pid = fork()) {
     case -1:
        errstr = newvstrallocf(errstr, _("couldn't fork: %s"), strerror(errno));
@@ -2047,7 +2063,6 @@ runencrypt(
        filter->allocated_size = 0;
        filter->event = event_register((event_id_t)filter->fd, EV_READFD,
                                       handle_filter_stderr, filter);
-g_debug("event register %s %d", "encrypt data", filter->fd);
        return (rval);
        }
     case 0: {
index 0edd6af8bfd3c28f2f981a6d86fdb4ad94549eeb..0b0348f3d75093360dce9964cfaa4bc4f7e98deb 100644 (file)
@@ -711,7 +711,8 @@ search_logfile(
     char *ck_label=NULL;
     int level = 0;
     off_t filenum;
-    char *ck_datestamp, *datestamp;
+    char *ck_datestamp=NULL;
+    char *datestamp;
     char *s;
     int ch;
     disk_t *dp;
@@ -745,6 +746,8 @@ search_logfile(
     filenum = (off_t)0;
     while(get_logline(logf)) {
        if (curlog == L_START && curprog == P_TAPER) {
+           amfree(ck_label);
+           ck_datestamp = NULL;
            if(parse_taper_datestamp_log(curstr, &ck_datestamp,
                                          &ck_label) == 0) {
                g_printf(_("strange log line in %s \"start taper %s\"\n"),
@@ -770,11 +773,14 @@ search_logfile(
            }
             amfree(current_label);
             current_label = ck_label;
+           ck_label = NULL;
             if (datestamp == NULL) {
                 datestamp = g_strdup(ck_datestamp);
             }
            filenum = (off_t)0;
        }
+       if (!datestamp)
+           continue;
        if (right_label &&
            (curlog == L_SUCCESS ||
             curlog == L_CHUNK || curlog == L_PART || curlog == L_PARTPARTIAL) &&
index c8501e2f35aced2ab93db61374600e0fd921c0ef..aa816292f18a97051b9cc63b220e5fc82d2f0c95 100644 (file)
@@ -108,6 +108,7 @@ typedef struct est_s {
     double fullcomp, incrcomp;
     char *errstr;
     char *degr_mesg;
+    info_t *info;
 } est_t;
 
 #define est(dp)        ((est_t *)(dp)->up)
@@ -756,7 +757,7 @@ setup_estimate(
      disk_t *dp)
 {
     est_t *ep;
-    info_t info;
+    info_t *info;
     int i;
     char *qname;
     int overwrite_runs;
@@ -770,7 +771,8 @@ setup_estimate(
 
     /* get current information about disk */
 
-    if(get_info(dp->host->hostname, dp->name, &info)) {
+    info = g_new0(info_t, 1);
+    if(get_info(dp->host->hostname, dp->name, info)) {
        /* no record for this disk, make a note of it */
        log_add(L_INFO, _("Adding new disk %s:%s."), dp->host->hostname, qname);
     }
@@ -810,6 +812,7 @@ setup_estimate(
 
     ep = alloc(SIZEOF(est_t));
     dp->up = (void *) ep;
+    ep->info = info;
     ep->state = DISK_READY;
     ep->dump_priority = dp->priority;
     ep->errstr = 0;
@@ -821,7 +824,7 @@ setup_estimate(
 
     /* calculated fields */
 
-    if (ISSET(info.command, FORCE_FULL)) {
+    if (ISSET(info->command, FORCE_FULL)) {
        /* force a level 0, kind of like a new disk */
        if(dp->strategy == DS_NOFULL) {
            /*
@@ -840,18 +843,18 @@ setup_estimate(
                    dp->host->hostname, qname);
 
            /* clear force command */
-           CLR(info.command, FORCE_FULL);
-           ep->last_level = last_level(&info);
-           ep->next_level0 = next_level0(dp, &info);
+           CLR(info->command, FORCE_FULL);
+           ep->last_level = last_level(info);
+           ep->next_level0 = next_level0(dp, info);
        } else if (dp->strategy == DS_INCRONLY) {
            log_add(L_WARNING,
                    _("Cannot force full dump of %s:%s with incronly option."),
                    dp->host->hostname, qname);
 
            /* clear force command */
-           CLR(info.command, FORCE_FULL);
-           ep->last_level = last_level(&info);
-           ep->next_level0 = next_level0(dp, &info);
+           CLR(info->command, FORCE_FULL);
+           ep->last_level = last_level(info);
+           ep->next_level0 = next_level0(dp, info);
        } else {
            ep->degr_mesg = _("Skipping: force-full disk can't be dumped in degraded mode");
            ep->last_level = -1;
@@ -863,44 +866,44 @@ setup_estimate(
     else if(dp->strategy == DS_NOFULL) {
        /* force estimate of level 1 */
        ep->last_level = 1;
-       ep->next_level0 = next_level0(dp, &info);
+       ep->next_level0 = next_level0(dp, info);
     }
     else {
-       ep->last_level = last_level(&info);
-       ep->next_level0 = next_level0(dp, &info);
+       ep->last_level = last_level(info);
+       ep->next_level0 = next_level0(dp, info);
     }
 
     /* adjust priority levels */
 
     /* warn if dump will be overwritten */
-    if (ep->last_level > -1 && strlen(info.inf[0].label) > 0) {
-       overwrite_runs = when_overwrite(info.inf[0].label);
+    if (ep->last_level > -1 && strlen(info->inf[0].label) > 0) {
+       overwrite_runs = when_overwrite(info->inf[0].label);
        if(overwrite_runs == 0) {
            log_add(L_WARNING, _("Last full dump of %s:%s "
                    "on tape %s overwritten on this run."),
-                   dp->host->hostname, qname, info.inf[0].label);
+                   dp->host->hostname, qname, info->inf[0].label);
        } else if(overwrite_runs <= RUNS_REDZONE) {
            log_add(L_WARNING,
                    plural(_("Last full dump of %s:%s on tape %s overwritten in %d run."),
                           _("Last full dump of %s:%s on tape %s overwritten in %d runs."), overwrite_runs),
-                   dp->host->hostname, qname, info.inf[0].label,
+                   dp->host->hostname, qname, info->inf[0].label,
                    overwrite_runs);
        }
     }
 
     /* warn if last level 1 will be overwritten */
-    if (ep->last_level > 1 && strlen(info.inf[1].label) > 0) {
-       overwrite_runs = when_overwrite(info.inf[1].label);
+    if (ep->last_level > 1 && strlen(info->inf[1].label) > 0) {
+       overwrite_runs = when_overwrite(info->inf[1].label);
        if(overwrite_runs == 0) {
            log_add(L_WARNING, _("Last level 1 dump of %s:%s "
                    "on tape %s overwritten on this run, resetting to level 1"),
-                   dp->host->hostname, qname, info.inf[1].label);
+                   dp->host->hostname, qname, info->inf[1].label);
            ep->last_level = 0;
        } else if(overwrite_runs <= RUNS_REDZONE) {
            log_add(L_WARNING,
                    plural(_("Last level 1 dump of %s:%s on tape %s overwritten in %d run."),
                           _("Last level 1 dump of %s:%s on tape %s overwritten in %d runs."), overwrite_runs),
-                   dp->host->hostname, qname, info.inf[1].label,
+                   dp->host->hostname, qname, info->inf[1].label,
                    overwrite_runs);
        }
     }
@@ -912,7 +915,7 @@ setup_estimate(
                dp->host->hostname, qname, (-ep->next_level0));
        ep->dump_priority -= ep->next_level0;
     }
-    else if (ISSET(info.command, FORCE_FULL))
+    else if (ISSET(info->command, FORCE_FULL))
        ep->dump_priority += 1;
     /* else XXX bump up the priority of incrementals that failed last night */
 
@@ -921,11 +924,11 @@ setup_estimate(
     if(dp->skip_full && dp->strategy != DS_NOINC) {
        if(ep->next_level0 <= 0) {
            /* update the date field */
-           info.inf[0].date = today;
-           CLR(info.command, FORCE_FULL);
+           info->inf[0].date = today;
+           CLR(info->command, FORCE_FULL);
            ep->next_level0 += conf_dumpcycle;
            ep->last_level = 0;
-           if(put_info(dp->host->hostname, dp->name, &info)) {
+           if(put_info(dp->host->hostname, dp->name, info)) {
                error(_("could not put info record for %s:%s: %s"),
                      dp->host->hostname, qname, strerror(errno));
                /*NOTREACHED*/
@@ -935,9 +938,9 @@ setup_estimate(
            g_fprintf(stderr,_("%s:%s lev 0 skipped due to skip-full flag\n"),
                    dp->host->hostname, qname);
            /* don't enqueue the disk */
-           askfor(ep, 0, -1, &info);
-           askfor(ep, 1, -1, &info);
-           askfor(ep, 2, -1, &info);
+           askfor(ep, 0, -1, info);
+           askfor(ep, 1, -1, info);
+           askfor(ep, 2, -1, info);
            g_fprintf(stderr, _("%s: SKIPPED %s %s 0 [skip-full]\n"),
                    get_pname(), dp->host->hostname, qname);
            log_add(L_SUCCESS, _("%s %s %s 0 [skipped: skip-full]"),
@@ -957,11 +960,11 @@ setup_estimate(
        }
     }
 
-    if(dp->strategy == DS_INCRONLY && ep->last_level == -1 && !ISSET(info.command, FORCE_FULL)) {
+    if(dp->strategy == DS_INCRONLY && ep->last_level == -1 && !ISSET(info->command, FORCE_FULL)) {
        /* don't enqueue the disk */
-       askfor(ep, 0, -1, &info);
-       askfor(ep, 1, -1, &info);
-       askfor(ep, 2, -1, &info);
+       askfor(ep, 0, -1, info);
+       askfor(ep, 1, -1, info);
+       askfor(ep, 2, -1, info);
        log_add(L_FAIL, _("%s %s 19000101 1 [Skipping incronly because no full dump were done]"),
                dp->host->hostname, qname);
        g_fprintf(stderr,_("%s:%s lev 1 skipped due to strategy incronly and no full dump were done\n"),
@@ -976,9 +979,9 @@ setup_estimate(
        g_fprintf(stderr,_("%s:%s lev 1 skipped due to skip-incr flag\n"),
                dp->host->hostname, qname);
        /* don't enqueue the disk */
-       askfor(ep, 0, -1, &info);
-       askfor(ep, 1, -1, &info);
-       askfor(ep, 2, -1, &info);
+       askfor(ep, 0, -1, info);
+       askfor(ep, 1, -1, info);
+       askfor(ep, 2, -1, info);
 
        g_fprintf(stderr, _("%s: SKIPPED %s %s 1 [skip-incr]\n"),
                get_pname(), dp->host->hostname, qname);
@@ -998,15 +1001,16 @@ setup_estimate(
        ep->next_level0 = 0;
     }
 
-    if(ep->last_level == 0) ep->level_days = 0;
-    else ep->level_days = runs_at(&info, ep->last_level);
-    ep->last_lev0size = info.inf[0].csize;
+    //if(ep->last_level == 0) ep->level_days = 0;
+    //else ep->level_days = runs_at(info, ep->last_level);
+    ep->level_days = runs_at(info, ep->last_level);
+    ep->last_lev0size = info->inf[0].csize;
 
-    ep->fullrate = perf_average(info.full.rate, 0.0);
-    ep->incrrate = perf_average(info.incr.rate, 0.0);
+    ep->fullrate = perf_average(info->full.rate, 0.0);
+    ep->incrrate = perf_average(info->incr.rate, 0.0);
 
-    ep->fullcomp = perf_average(info.full.comp, dp->comprate[0]);
-    ep->incrcomp = perf_average(info.incr.comp, dp->comprate[1]);
+    ep->fullcomp = perf_average(info->full.comp, dp->comprate[0]);
+    ep->incrcomp = perf_average(info->incr.comp, dp->comprate[1]);
 
     /* determine which estimates to get */
 
@@ -1014,10 +1018,10 @@ setup_estimate(
 
     if (dp->strategy == DS_NOINC ||
        (!dp->skip_full &&
-        (!ISSET(info.command, FORCE_BUMP) ||
+        (!ISSET(info->command, FORCE_BUMP) ||
          dp->skip_incr ||
          ep->last_level == -1))) {
-       if(ISSET(info.command, FORCE_BUMP) && ep->last_level == -1) {
+       if(ISSET(info->command, FORCE_BUMP) && ep->last_level == -1) {
            log_add(L_INFO,
                  _("Remove force-bump command of %s:%s because it's a new disk."),
                    dp->host->hostname, qname);
@@ -1025,7 +1029,7 @@ setup_estimate(
        switch (dp->strategy) {
        case DS_STANDARD: 
        case DS_NOINC:
-           askfor(ep, i++, 0, &info);
+           askfor(ep, i++, 0, info);
            if (ep->last_level == -1)
                ep->degr_mesg = _("Skipping: new disk can't be dumped in degraded mode");
            else
@@ -1035,7 +1039,7 @@ setup_estimate(
                        "because the strategy is NOINC."),
                        dp->host->hostname, qname);
            }
-           if(ISSET(info.command, FORCE_BUMP)) {
+           if(ISSET(info->command, FORCE_BUMP)) {
                log_add(L_INFO,
                 _("Ignoring FORCE_BUMP for %s:%s because the strategy is NOINC."),
                        dp->host->hostname, qname);
@@ -1047,7 +1051,7 @@ setup_estimate(
            break;
 
        case DS_INCRONLY:
-           if (ISSET(info.command, FORCE_FULL))
+           if (ISSET(info->command, FORCE_FULL))
                ep->last_level = 0;
            break;
        }
@@ -1058,7 +1062,7 @@ setup_estimate(
            if (ep->degr_mesg == NULL)
                ep->degr_mesg = _("Skipping: new disk can't be dumped in degraded mode");
            if(dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY) {
-               askfor(ep, i++, 1, &info);
+               askfor(ep, i++, 1, info);
            } else {
                assert(!dp->skip_full);         /* should be handled above */
            }
@@ -1067,23 +1071,23 @@ setup_estimate(
 
            curr_level = ep->last_level;
 
-           if (ISSET(info.command, FORCE_NO_BUMP)) {
+           if (ISSET(info->command, FORCE_NO_BUMP)) {
                if(curr_level > 0) { /* level 0 already asked for */
-                   askfor(ep, i++, curr_level, &info);
+                   askfor(ep, i++, curr_level, info);
                }
                log_add(L_INFO,_("Preventing bump of %s:%s as directed."),
                        dp->host->hostname, qname);
                ep->degr_mesg = _("Skipping: force-no-bump disk can't be dumped in degraded mode");
-           } else if (ISSET(info.command, FORCE_BUMP)
+           } else if (ISSET(info->command, FORCE_BUMP)
                       && curr_level + 1 < DUMP_LEVELS) {
-               askfor(ep, i++, curr_level+1, &info);
+               askfor(ep, i++, curr_level+1, info);
                log_add(L_INFO,_("Bumping of %s:%s at level %d as directed."),
                        dp->host->hostname, qname, curr_level+1);
                ep->degr_mesg = _("Skipping: force-bump disk can't be dumped in degraded mode");
            } else if (curr_level == 0) {
-               askfor(ep, i++, 1, &info);
+               askfor(ep, i++, 1, info);
            } else {
-               askfor(ep, i++, curr_level, &info);
+               askfor(ep, i++, curr_level, info);
                /*
                 * If last time we dumped less than the threshold, then this
                 * time we will too, OR the extra size will be charged to both
@@ -1091,25 +1095,25 @@ setup_estimate(
                 * if we haven't been at this level 2 days, or the dump failed
                 * last night, we can't bump.
                 */
-               if((info.inf[curr_level].size == (gint64)0 || /* no data, try it anyway */
-                   (((info.inf[curr_level].size > bump_thresh(curr_level, info.inf[0].size,dp->bumppercent, dp->bumpsize, dp->bumpmult)))
+               if((info->inf[curr_level].size == (gint64)0 || /* no data, try it anyway */
+                   (((info->inf[curr_level].size > bump_thresh(curr_level, info->inf[0].size,dp->bumppercent, dp->bumpsize, dp->bumpmult)))
                     && ep->level_days >= dp->bumpdays))
                   && curr_level + 1 < DUMP_LEVELS) {
-                   askfor(ep, i++, curr_level+1, &info);
+                   askfor(ep, i++, curr_level+1, info);
                }
-           } 
+           }
        }
     }
 
-    while(i < MAX_LEVELS)      /* mark end of estimates */
-       askfor(ep, i++, -1, &info);
+    while(i < MAX_LEVELS)      /* mark end of estimates */
+       askfor(ep, i++, -1, info);
 
     /* debug output */
 
     g_fprintf(stderr, _("setup_estimate: %s:%s: command %u, options: %s    "
-           "last_level %d next_level0 %d level_days %d    getting estimates "
+           "last_level %d next_level0 %d level_days %d    getting estimates "
            "%d (%lld) %d (%lld) %d (%lld)\n"),
-           dp->host->hostname, qname, info.command,
+           dp->host->hostname, qname, info->command,
            dp->strategy == DS_NOFULL ? "no-full" :
                 dp->strategy == DS_INCRONLY ? "incr-only" :
                 dp->skip_full ? "skip-full" :
@@ -1287,10 +1291,9 @@ static int runs_at(
 
     last = last_level(info);
     if(lev != last) return 0;
-    if(lev == 0) return 1;
-
     if(info->consecutive_runs != -1)
        return info->consecutive_runs;
+    if(lev == 0) return 1;
 
     /* to keep compatibility with old infofile */
     cur_tape = lookup_tapelabel(info->inf[lev].label);
@@ -2226,7 +2229,8 @@ static void analyze_estimate(
                /* fill in degraded mode info */
                g_fprintf(stderr,_("(picking inclevel for degraded mode)"));
                ep->degr_est = pick_inclevel(dp);
-               if (ep->degr_est->csize == (gint64)-1) {
+               if (ep->degr_est->level >= 0 &&
+                   ep->degr_est->csize == (gint64)-1) {
                     ep->degr_est = est_for_level(dp, ep->degr_est->level + 1);
                }
                if (ep->degr_est->csize == (gint64)-1) {
@@ -2476,6 +2480,7 @@ static void delay_dumps(void)
     disk_t *   dp;
     disk_t *   ndp;
     disk_t *   preserve;
+    disk_t *   delayed_dp;
     bi_t *     bi;
     bi_t  *    nbi;
     gint64     new_total;              /* New total_size */
@@ -2485,6 +2490,8 @@ static void delay_dumps(void)
     int                delete;
     char *     message;
     gint64     full_size;
+    time_t      timestamps;
+    int         priority;
 
     biq.head = biq.tail = NULL;
 
@@ -2550,7 +2557,7 @@ static void delay_dumps(void)
            }
            else {
                delete = 0;
-               message = _("full dump delayed");
+               message = _("full dump delayed, doing incremental");
            }
        }
        else {
@@ -2576,51 +2583,71 @@ static void delay_dumps(void)
 
     nb_forced_level_0 = 0;
     preserve = NULL;
-    for(dp = schedq.head; dp != NULL && preserve == NULL; dp = dp->next)
-       if(est(dp)->dump_est->level == 0)
-           preserve = dp;
+    timestamps = 2147483647;
+    priority = 0;
+    for(dp = schedq.head; dp != NULL; dp = dp->next) {
+       if (est(dp)->dump_est->level == 0) {
+           if (!preserve ||
+               est(dp)->dump_priority > priority ||
+               (est(dp)->dump_priority == priority &&
+                est(dp)->info->inf[0].date < timestamps)) {
+               priority = est(dp)->dump_priority;
+               timestamps = est(dp)->info->inf[0].date;
+               preserve = dp;
+           }
+       }
+    }
 
     /* 2.a. Do not delay forced full */
-    for(dp = schedq.tail;
+    delayed_dp = NULL;
+    do {
+       delayed_dp = 0;
+       timestamps = 0;
+       for(dp = schedq.tail;
                dp != NULL && total_size > tape_length;
                dp = ndp) {
-       ndp = dp->prev;
-
-       if(est(dp)->dump_est->level != 0) continue;
+           ndp = dp->prev;
 
-       get_info(dp->host->hostname, dp->name, &info);
-       if(ISSET(info.command, FORCE_FULL)) {
-           nb_forced_level_0 += 1;
-           preserve = dp;
-           continue;
-       }
+           if(est(dp)->dump_est->level != 0) continue;
 
-       if(dp != preserve) {
+           get_info(dp->host->hostname, dp->name, &info);
+           if(ISSET(info.command, FORCE_FULL)) {
+               nb_forced_level_0 += 1;
+               preserve = dp;
+               continue;
+           }
 
+           if (dp != preserve &&
+               est(dp)->info->inf[0].date > timestamps) {
+               delayed_dp = dp;
+               timestamps = est(dp)->info->inf[0].date;
+           }
+       }
+       if (delayed_dp) {
            /* Format dumpsize for messages */
            g_snprintf(est_kb, 20, "%lld KB,",
-                       (long long)est(dp)->dump_est->csize);
+                       (long long)est(delayed_dp)->dump_est->csize);
 
-           if(dp->skip_incr) {
+           if(delayed_dp->skip_incr) {
                delete = 1;
                message = _("but cannot incremental dump skip-incr disk");
            }
-           else if(est(dp)->last_level < 0) {
+           else if(est(delayed_dp)->last_level < 0) {
                delete = 1;
                message = _("but cannot incremental dump new disk");
            }
-           else if(est(dp)->degr_est->level < 0) {
+           else if(est(delayed_dp)->degr_est->level < 0) {
                delete = 1;
                message = _("but no incremental estimate");
            }
            else {
                delete = 0;
-               message = _("full dump delayed");
+               message = _("full dump delayed, doing incremental");
            }
-           delay_one_dump(dp, delete, _("dumps too big,"), est_kb,
+           delay_one_dump(delayed_dp, delete, _("dumps too big,"), est_kb,
                           message, NULL);
        }
-    }
+    } while (delayed_dp);
 
     /* 2.b. Delay forced full if needed */
     if(nb_forced_level_0 > 0 && total_size > tape_length) {
index 8e4400bf4a9d49a9a99933661fd80c2bf3c26317..faf58759bb510625a11337a4c8751b035cda8552 100644 (file)
@@ -50,7 +50,7 @@ read_tapelist(
     char *line = NULL;
     int status = 0;
 
-    tape_list = NULL;
+    clear_tapelist();
     if((tapef = fopen(tapefile,"r")) == NULL) {
        if (errno == ENOENT) {
            /* no tapelist is equivalent to an empty tapelist */
@@ -132,6 +132,9 @@ clear_tapelist(void)
     for(tp = tape_list; tp; tp = next) {
        amfree(tp->label);
        amfree(tp->datestamp);
+       amfree(tp->barcode);
+       amfree(tp->meta);
+       amfree(tp->comment);
        next = tp->next;
        amfree(tp);
     }
@@ -275,6 +278,9 @@ remove_tapelabel(
        }
        amfree(tp->datestamp);
        amfree(tp->label);
+       amfree(tp->meta);
+       amfree(tp->comment);
+       amfree(tp->barcode);
        amfree(tp);
     }
 }
@@ -289,7 +295,7 @@ add_tapelabel(
 
     /* insert a new record to the front of the list */
 
-    new = (tape_t *) alloc(SIZEOF(tape_t));
+    new = g_new0(tape_t, 1);
 
     new->datestamp = stralloc(datestamp);
     new->position = 0;
@@ -362,19 +368,17 @@ parse_tapeline(
     int ch;
 
     *status = 0;
-    tp = (tape_t *) alloc(SIZEOF(tape_t));
-
-    tp->prev = NULL;
-    tp->next = NULL;
 
     s = line;
     ch = *s++;
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       amfree(tp);
        return NULL;
     }
+
+    tp = g_new0(tape_t, 1);
+
     s1 = s - 1;
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
@@ -409,8 +413,6 @@ parse_tapeline(
        s[-1] = '\0';
        skip_whitespace(s, ch);
        tp->barcode = stralloc(s1);
-    } else {
-       tp->barcode = NULL;
     }
 
     if (strncmp_const(s - 1, "META:") == 0) {
@@ -419,8 +421,6 @@ parse_tapeline(
        s[-1] = '\0';
        skip_whitespace(s, ch);
        tp->meta = stralloc(s1);
-    } else {
-       tp->meta = NULL;
     }
 
     if (strncmp_const(s - 1, "BLOCKSIZE:") == 0) {
@@ -429,13 +429,9 @@ parse_tapeline(
        s[-1] = '\0';
        skip_whitespace(s, ch);
        tp->blocksize = atol(s1);
-    } else {
-       tp->blocksize = 0;
     }
     if (*(s - 1) == '#') {
        tp->comment = stralloc(s); /* skip leading '#' */
-    } else {
-       tp->comment = NULL;
     }
 
     return tp;
index b685a5276374bba6334c2d71ac407298e14663dc..8422dbc39b4ae90b3de86c440e1bc703770aabbc 100644 (file)
@@ -1,5 +1,5 @@
 #! @PERL@
-# Copyright (c) 2009, 2010 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2009-2012 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
index f8178d10f20c0ce8743eaef1d99aa1aaf69a0ad0..34e18146a1d8dd3dffa78c836b2d5849383d263f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -38,5 +38,8 @@
 XferElement *xfer_source_holding(
     const char *filename);
 
+guint64
+xfer_source_holding_get_bytes_read(
+    XferElement *elt);
 
 #endif
index a53c512d8f866a331d2a6049bb06a631470568fd..4776acc5c0c77d0f56c49928441ef0114011f257 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2009-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -49,6 +49,7 @@ typedef struct XferSourceHolding {
 
     int fd;
     char *next_filename;
+    guint64 bytes_read;
 
     XferElement *dest_taper;
 } XferSourceHolding;
@@ -195,6 +196,7 @@ pull_buffer_impl(
        bytes_read = full_read(self->fd, buf, HOLDING_BLOCK_SIZE);
        if (bytes_read > 0) {
            *size = bytes_read;
+           self->bytes_read += bytes_read;
            return buf;
        }
 
@@ -296,7 +298,17 @@ xfer_source_holding(
     XferElement *elt = XFER_ELEMENT(self);
 
     self->next_filename = g_strdup(filename);
+    self->bytes_read = 0;
 
     return elt;
 }
 
+guint64
+xfer_source_holding_get_bytes_read(
+    XferElement *elt)
+{
+    XferSourceHolding *self = (XferSourceHolding *)elt;
+
+    return self->bytes_read;
+}
+
index 86690cff8399b3cd73761dbc24acd16f43eb7bce..c83f280bf0017417537741eb1439949cb76c7281 100644 (file)
@@ -18,7 +18,7 @@
 # Makefile for Amanda library.
 
 # vim:ft=automake
-# Copyright (c) 2007,2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
@@ -269,7 +269,8 @@ am__aclocal_m4_deps =  \
        $(top_srcdir)/config/ltoptions.m4 \
        $(top_srcdir)/config/ltsugar.m4 \
        $(top_srcdir)/config/ltversion.m4 \
-       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/configure.in
+       $(top_srcdir)/config/lt~obsolete.m4 $(top_srcdir)/FULL_VERSION \
+       $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
@@ -842,6 +843,9 @@ MSGMERGE = @MSGMERGE@
 MT = @MT@
 MTX = @MTX@
 MT_FILE_FLAG = @MT_FILE_FLAG@
+NC = @NC@
+NC6 = @NC6@
+NETCAT = @NETCAT@
 NETINET_IN_H = @NETINET_IN_H@
 NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
 NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
index 2333deac466d8643bcc2778c99a31b0c1ad6fd31..ab89d2fdfd6b489310f9c1fab984569fba0a36aa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 1d41e5a6644caaf91f86cbdf8d21a591a89900c2..4e85a7079bb18265008f103e366fd597779b57e9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 72c59613890de9fdbed17df91ba6671019cca9ff..d739bf812d963dc03c02627cdbcf7468e2992851 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index da3cc7f4fc52bfc3f82b3128a012bbed82835476..345bbbecf2ae318db0d659df9c375fabd7f80d10 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 6eee1d417d9c56db3d927722ede345f6bf673e97..962d3dd4aee6f668e1c079ab50d1efe32bff43ef 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index c5260a5bb8b7f875f205ecb66bab2036016627de..c4a49efda0985ed79bbce8ffcfd6df56c0bbd1ad 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 319b576080658f3639913c52adf03c90e9fc6937..bb31e938dd0f2206efb6ce99da56ba2992279fa6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -220,7 +220,7 @@ do_directtcp_connect(
     /* set up the sockaddr -- IPv4 only */
     copy_sockaddr(&addr, addrs);
 
-    g_debug("making data connection to %s", str_sockaddr(&addr));
+    g_debug("do_directtcp_connect making data connection to %s", str_sockaddr(&addr));
     sock = socket(SU_GET_FAMILY(&addr), SOCK_STREAM, 0);
     if (sock < 0) {
        xfer_cancel_with_error(elt,
index d4f94e501d4bf7239128403d87c204ae98625bcf..1838bfd688492df2b8960aa18fb1cc07ddbe9e41 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index aa23b0bdf4079e13f0e2448d0d2cd168e6874370..fbbe8e819bf48b01cd383556c160df76b51d9cef 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 7d836657c6171430eb03c01dd9f8881f12b3f031..112570c132491583406de58067d9d45f613eeab1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 61c6070e012f611a7173082ce61bf60e647336ae..b7ddc5bae2660a4902b47d438038a89326848a33 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 82bac75e588f5adb23bad6c52fcb46b2e59d004c..8d3611c33d95c74522b922e268d10b1db3bb5a57 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 9d1814a19d1be84a5c588965ec4c9f3992fa38ab..fedeba6a98ae507e8825ecac739c8ea024b04b52 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 5a4aad836625c593341876f951845439898b757f..1a9432ff05209a45471e2ce0b83efde9c393ae30 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2011 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index b7c8f4b6dcb97ac865ab94d97bb516b828c0abb4..0683b6f83e622d4ecb86fd52acb49da00446e632 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index dd94e3ca126faafa4ca3ffd055c5fdae49e08ec5..37e3377de8cea3bee41eca649318a71608bec55d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -238,11 +238,15 @@ xfer_element_pull_buffer(
     XferElement *elt,
     size_t *size)
 {
+    xfer_status status;
     /* Make sure that the xfer is running before calling upstream's
      * pull_buffer method; this avoids a race condition where upstream
      * hasn't finished its xfer_element_start yet, and isn't ready for
      * a pull */
-    if (elt->xfer->status == XFER_START)
+    g_mutex_lock(elt->xfer->status_mutex);
+    status = elt->xfer->status;
+    g_mutex_unlock(elt->xfer->status_mutex);
+    if (status == XFER_START)
        wait_until_xfer_running(elt->xfer);
 
     return XFER_ELEMENT_GET_CLASS(elt)->pull_buffer(elt, size);
index 5d45ac03f0c33ab1689a6ca6ffce4eea0cbfb694..6c4ebed80ee91ec4c09a568d0e3882598c4bafe8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index f83448af4bebe98049d9ed51c7011a90fe36ce38..9c43b4a1c87cd65787152c3198f478e6365f46f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index ac97198c34cc6d46d1a9afc9712e679354c3455c..97b71473642859dc6bcad874904bff4dcdc66171 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -269,7 +269,10 @@ xfer_cancel(
 {
     /* Since xfer_cancel can be called from any thread, we just send a message.
      * The action takes place when the message is received. */
-    XferElement *src = g_ptr_array_index(xfer->elements, 0);
+    XferElement *src;
+    if (xfer->cancelled > 0) return;
+    xfer->cancelled++;
+    src = g_ptr_array_index(xfer->elements, 0);
     xfer_queue_message(xfer, xmsg_new(src, XMSG_CANCEL, 0));
 }
 
index 3d6773a02f969d3684ce91f64282c177747d3389..16a6a784818197583cdf4cf6b1cd70d0b6298f74 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -90,6 +90,8 @@ struct Xfer {
     /* Used to coordinate handing off file descriptors among elements of this
      * xfer */
     GMutex *fd_mutex;
+
+    int cancelled;
 };
 
 typedef struct Xfer Xfer;
index 99c9a5414ab56461bcc89638d4c64cb95b28c68b..a67624c7d0c035fe7a781691f00976352cc2a05a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
index 172561a03196eb628e1a3e63e28f0cafbbf349d4..85ba2cac5388c838a5ecdb31ca245612f8692325 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published