Imported Debian patch 2.5.1-1 debian/2.5.1-1
authorBdale Garbee <bdale@gag.com>
Wed, 18 Oct 2006 07:02:23 +0000 (01:02 -0600)
committerBdale Garbee <bdale@gag.com>
Tue, 20 May 2008 04:47:27 +0000 (22:47 -0600)
409 files changed:
ChangeLog
Makefile.am
Makefile.in
NEWS
ReleaseNotes [new file with mode: 0644]
amandad-src/Makefile.am [new file with mode: 0644]
amandad-src/Makefile.in [new file with mode: 0644]
amandad-src/amandad.c [new file with mode: 0644]
amandad-src/amandad.h [new file with mode: 0644]
amandad-src/amandad_util.c [new file with mode: 0644]
amplot/Makefile.in
amplot/amplot.sh.in
changer-src/Makefile.am
changer-src/Makefile.in
changer-src/chg-chio.pl.in
changer-src/chg-chs.sh.in
changer-src/chg-disk.sh.in
changer-src/chg-iomega.pl.in
changer-src/chg-juke.sh.in
changer-src/chg-manual.sh.in
changer-src/chg-mcutil.sh.in
changer-src/chg-mtx.sh.in
changer-src/chg-multi.sh.in
changer-src/chg-null.sh.in
changer-src/chg-rait.sh.in
changer-src/chg-scsi-chio.c
changer-src/chg-scsi.c
changer-src/chg-zd-mtx.sh.in
changer-src/libscsi.h
changer-src/scsi-aix.c
changer-src/scsi-bsd.c
changer-src/scsi-cam.c
changer-src/scsi-changer-driver.c
changer-src/scsi-chio.c
changer-src/scsi-defs.h
changer-src/scsi-hpux.c
changer-src/scsi-hpux_new.c
changer-src/scsi-irix.c
changer-src/scsi-linux.c
changer-src/scsi-proto.c
changer-src/scsi-solaris.c
changer-src/sense.c
client-src/Makefile.am
client-src/Makefile.in
client-src/amandad.c [deleted file]
client-src/amandad.h [deleted file]
client-src/amandates.c
client-src/amandates.h
client-src/calcsize.c
client-src/client_util.c
client-src/client_util.h
client-src/clientconf.c [new file with mode: 0644]
client-src/clientconf.h [new file with mode: 0644]
client-src/findpass.c
client-src/findpass.h
client-src/getfsent.c
client-src/getfsent.h
client-src/killpgrp.c
client-src/noop.c
client-src/patch-system.sh.in
client-src/rundump.c
client-src/runtar.c
client-src/selfcheck.c
client-src/sendbackup-dump.c
client-src/sendbackup-gnutar.c
client-src/sendbackup.c
client-src/sendbackup.h
client-src/sendsize.c
client-src/unctime.c
client-src/versionsuffix.c
common-src/Makefile.am
common-src/Makefile.in
common-src/alloc.c
common-src/alloca.c
common-src/amanda.h
common-src/amfeatures.c
common-src/amfeatures.h
common-src/amflock.c
common-src/amregex.h
common-src/arglist.h
common-src/bsd-security.c
common-src/bsdtcp-security.c [new file with mode: 0644]
common-src/bsdudp-security.c [new file with mode: 0644]
common-src/clock.c
common-src/clock.h
common-src/debug.c
common-src/dgram.c
common-src/dgram.h
common-src/error.c
common-src/event.c
common-src/event.h
common-src/file.c
common-src/fileheader.c
common-src/fileheader.h
common-src/genversion.c
common-src/getcwd.c
common-src/krb4-security.c
common-src/krb5-security.c
common-src/match.c
common-src/mktime.c
common-src/packet.c
common-src/packet.h
common-src/pipespawn.c
common-src/pipespawn.h
common-src/protocol.c
common-src/protocol.h
common-src/regcomp.c
common-src/rsh-security.c
common-src/security-util.c [new file with mode: 0644]
common-src/security-util.h [new file with mode: 0644]
common-src/security.c
common-src/security.h
common-src/sl.c
common-src/sl.h
common-src/ssh-security.c
common-src/statfs.c
common-src/statfs.h
common-src/strcasecmp.c
common-src/stream.c
common-src/stream.h
common-src/strerror.c
common-src/strftime.c
common-src/strncasecmp.c
common-src/tapelist.c
common-src/tapelist.h
common-src/token.c
common-src/token.h
common-src/util.c
common-src/util.h
common-src/version.c
common-src/version.h
common-src/versuff.c
common-src/versuff.c.in
config/Makefile.in
config/config.h.in
config/config.sub
configure
configure.in
contrib/set_prod_link.pl
debian/amanda-server.README.Debian
debian/changelog
debian/po/ar.po
debian/po/cs.po
debian/po/da.po
debian/po/de.po
debian/po/es.po
debian/po/fr.po
debian/po/it.po
debian/po/ja.po
debian/po/nl.po
debian/po/pt.po
debian/po/pt_BR.po
debian/po/ru.po
debian/po/sv.po
debian/po/templates.pot
debian/po/vi.po
debian/rules
debian/templates
docs/Appendix.txt
docs/Makefile.am
docs/Makefile.in
docs/amadmin.8.txt
docs/amaespipe.8.txt [new file with mode: 0644]
docs/amanda-client.conf.5.txt [new file with mode: 0644]
docs/amanda.8.txt
docs/amanda.conf.5.txt
docs/amcheck.8.txt
docs/amcheckdb.8.txt
docs/amcleanup.8.txt
docs/amcrypt-asym-ossl.8.txt [new file with mode: 0644]
docs/amcrypt-ossl.8.txt [new file with mode: 0644]
docs/amcrypt.8.txt [new file with mode: 0644]
docs/amdd.8.txt
docs/amdump.8.txt
docs/amfetchdump.8.txt [new file with mode: 0644]
docs/amflush.8.txt
docs/amgetconf.8.txt
docs/amlabel.8.txt
docs/ammt.8.txt
docs/amoverview.8.txt
docs/amplot.8.txt
docs/amrecover.8.txt
docs/amreport.8.txt
docs/amrestore.8.txt
docs/amrmtape.8.txt
docs/amstatus.8.txt
docs/amtape.8.txt
docs/amtapetype.8.txt
docs/amtoc.8.txt
docs/amverify.8.txt
docs/amverifyrun.8.txt
docs/chgscsi.txt
docs/dumperapi.txt
docs/eventapi.txt
docs/exclude.txt
docs/faq.txt
docs/historical.txt
docs/howto-afs.txt
docs/howto-auth.txt [new file with mode: 0644]
docs/howto-cygwin.txt
docs/howto-filedriver.txt
docs/howto-wrapper.txt
docs/howtos.txt
docs/index.txt
docs/indexing.txt
docs/install.txt
docs/internals.txt
docs/introduction.txt
docs/ix01.txt
docs/kerberos.txt
docs/labelprinting.txt
docs/links.txt
docs/manpages.txt
docs/multitape.txt
docs/portusage.txt
docs/pr01.txt
docs/pr02.txt
docs/pr03.txt
docs/pr04.txt
docs/rait.txt
docs/restore.txt
docs/samba.txt
docs/security-api.txt
docs/security.txt
docs/strategy-api.txt
docs/systemnotes.txt
docs/tapechangers.txt
docs/tapesnchangers.txt
docs/tapetypes.txt
docs/technical.txt
docs/topten.txt
docs/upgrade.txt
docs/using.txt
docs/various.txt
docs/vtape-api.txt
docs/whatwasnew.txt
docs/wishlist.txt
docs/y2k.txt
docs/zftape.txt
dumper-src/Makefile.in
example/Makefile.am
example/Makefile.in
example/amanda-client.conf.in [new file with mode: 0644]
example/amanda.conf.in
example/chg-mcutil.conf
man/Makefile.am
man/Makefile.in
man/amadmin.8
man/amaespipe.8
man/amanda-client.conf.5 [new file with mode: 0644]
man/amanda.8
man/amanda.conf.5
man/amcheck.8
man/amcleanup.8
man/amcrypt-ossl-asym.8 [new file with mode: 0644]
man/amcrypt-ossl.8 [new file with mode: 0644]
man/amcrypt.8
man/amdump.8
man/amfetchdump.8
man/amflush.8
man/amgetconf.8
man/amlabel.8
man/amrecover.8
man/amreport.8
man/amrestore.8
man/amtapetype.8
man/entities/global.entities
man/entities/xinclude.dtd
man/xml-source/amadmin.8.xml
man/xml-source/amaespipe.8.xml
man/xml-source/amanda-client.conf.5.xml [new file with mode: 0644]
man/xml-source/amanda.8.xml
man/xml-source/amanda.conf.5.xml
man/xml-source/amcheck.8.xml
man/xml-source/amcleanup.8.xml
man/xml-source/amcrypt-ossl-asym.8.xml [new file with mode: 0644]
man/xml-source/amcrypt-ossl.8.xml [new file with mode: 0644]
man/xml-source/amcrypt.8.xml
man/xml-source/amdump.8.xml
man/xml-source/amfetchdump.8.xml
man/xml-source/amflush.8.xml
man/xml-source/amgetconf.8.xml
man/xml-source/amlabel.8.xml
man/xml-source/amrecover.8.xml
man/xml-source/amreport.8.xml
man/xml-source/amrestore.8.xml
man/xml-source/amtapetype.8.xml
oldrecover-src/Makefile.am [new file with mode: 0644]
oldrecover-src/Makefile.in [new file with mode: 0644]
oldrecover-src/amrecover.c [new file with mode: 0644]
oldrecover-src/amrecover.h [new file with mode: 0644]
oldrecover-src/display_commands.c [new file with mode: 0644]
oldrecover-src/extract_list.c [new file with mode: 0644]
oldrecover-src/help.c [new file with mode: 0644]
oldrecover-src/set_commands.c [new file with mode: 0644]
oldrecover-src/uparse.c [new file with mode: 0644]
oldrecover-src/uparse.h [new file with mode: 0644]
oldrecover-src/uparse.y [new file with mode: 0644]
oldrecover-src/uscan.c [new file with mode: 0644]
oldrecover-src/uscan.l [new file with mode: 0644]
recover-src/Makefile.am
recover-src/Makefile.in
recover-src/amrecover.c
recover-src/amrecover.h
recover-src/display_commands.c
recover-src/extract_list.c
recover-src/help.c
recover-src/set_commands.c
recover-src/uparse.c
recover-src/uparse.h
recover-src/uparse.y
recover-src/uscan.c
recover-src/uscan.l
regex-src/Makefile
regex-src/cclass.h
regex-src/cname.h
regex-src/debug.c
regex-src/engine.c
regex-src/main.c
regex-src/mkh
regex-src/regcomp.c
regex-src/regerror.c
regex-src/regex2.h
regex-src/regexec.c
regex-src/regfree.c
regex-src/split.c
regex-src/utils.h
restore-src/Makefile.am
restore-src/Makefile.in
restore-src/amfetchdump.c
restore-src/amidxtaped.c
restore-src/amrestore.c
restore-src/restore.c
restore-src/restore.h
server-src/Makefile.am
server-src/Makefile.in
server-src/amadmin.c
server-src/amaespipe.sh.in
server-src/amcheck.c
server-src/amcheckdb.sh.in
server-src/amcleanup.sh.in
server-src/amcleanupdisk.c
server-src/amcrypt-ossl-asym.sh.in [new file with mode: 0644]
server-src/amcrypt-ossl.sh.in [new file with mode: 0644]
server-src/amcrypt.sh.in
server-src/amdump.sh.in
server-src/amflush.c
server-src/amfreetapes.sh.in
server-src/amindex.c
server-src/amindex.h
server-src/amindexd.c
server-src/amlabel.c
server-src/amlogroll.c
server-src/amoverview.pl.in
server-src/amrmtape.sh.in
server-src/amstatus.pl.in
server-src/amtape.c
server-src/amtrmidx.c
server-src/amtrmlog.c
server-src/amverify.sh.in
server-src/amverifyrun.sh.in
server-src/changer.c
server-src/changer.h
server-src/chunker.c
server-src/conffile.c
server-src/conffile.h
server-src/disk_history.c
server-src/disk_history.h
server-src/diskfile.c
server-src/diskfile.h
server-src/driver.c
server-src/driverio.c
server-src/driverio.h
server-src/dumper.c
server-src/find.c
server-src/find.h
server-src/getconf.c
server-src/holding.c
server-src/holding.h
server-src/infofile.c
server-src/infofile.h
server-src/list_dir.c
server-src/list_dir.h
server-src/logfile.c
server-src/logfile.h
server-src/planner.c
server-src/reporter.c
server-src/server_util.c
server-src/server_util.h
server-src/tapefile.c
server-src/tapefile.h
server-src/taper.c
server-src/taperscan.c
server-src/taperscan.h
tape-src/Makefile.am
tape-src/Makefile.in
tape-src/amdd.c
tape-src/ammt.c
tape-src/output-file.c
tape-src/output-file.h
tape-src/output-null.c
tape-src/output-null.h
tape-src/output-rait.c
tape-src/output-rait.h
tape-src/output-tape.c
tape-src/output-tape.h
tape-src/tapeio.c
tape-src/tapeio.h
tape-src/tapetype.c

index 5948c18bfad8593862329e92118c67122b7d89d9..c0c98200c8345ff42674f6bf31f0c68bc1c44bcd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-2006-05-28  Jean-Louis Martineau <martineau@zmanda.com>
+2006-09-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * Amanda 2.5.1 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.1).
+       * NEWS: Change in amanda-2.5.1
+
+2006-08-30  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/dumper.c: Typo in error message.
+
+2006-08-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/selfcheck.c: Print error message to stdout before
+                                 calling error().
+
+2006-08-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/dumper.c (log_msgout): Seek to begining of file.
+
+2006-08-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/reporter.c: Report if a dump was successfully retried.
+
+2006-08-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amstatus.pl.in: Correct size for retried dump.
+
+2006-08-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/runtar.c: Check that strcmp(argv[3], "--create") == 0.
+
+2006-08-24  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/statfs.c (scale): Macro replaced by a function.
+
+2006-08-24  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/chunker.c: Use STREAM_BUFSIZE for stream_accept.
+       * server-src/taper.c: Use STREAM_BUFSIZE for stream_accept.
+
+2006-08-24  Maitreyee Karmarkar <maitreyee.zmanda.com>
+       * man/xml-source/amcheck.8.xml: amcheck xml man page change 
+
+2006-08-23  Kevin Till <ktill@zmanda.com>
+       *  server-src/driver.c: fix typo
+
+2006-08-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driver.c (dumper_result): Decrement pendings_aborts.
+       * server-src/driver.c (handle_dumper_result): Don't send duper result
+         to chunker if we aborted it.
+       * server-src/driverio.c (dumper_cmd, chunker_cmd): Don't close the fd
+         on ABORT.
+       * server-src/dumper.c: Accept ABORT command.
+
+2006-08-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/restore.c (restore): Set bytes_read to the return value
+         of read_file_header.
+
+2006-08-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * tape-src/output-tape.c: Works if EOVERFLOW is not defined.
+
+2006-08-21  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c, common-src/rsh-security.c,
+         common-src/ssh-security.c, restore-src/restore.c,
+         server-src/changer.c, server-src/dumper.c: Fix sentinel warning.
+
+2006-08-21  Jean-Louis Martineau <martineau@zmanda.com>
+       * example/amanda.conf.in: Typo.
+
+2006-08-21  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driverio.c: Fix bogus "(unsigned long)-1".
+
+2006-08-21  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driver.c (start_some_dumps): Remove bogus free_assignedhd.
+
+2006-08-21  Maitreyee Karmarkar <maitreyee.zmanda.com>
+       * server-src/amcheck.c: Check specific clients
+       * man/amcheck.8: add the multiple client check format
+
+2006-08-18  Ian Turner <ian@zmanda.com>
+       * tape-src/amtapetype.c: Don't crash on exit
+
+2006-08-17  Paddy Sreenivasan <paddy@zmanda.com>
+        * server-src/driverio.c:
+        * server-src/changer.c:
+        * restore-src/amfetchdump.c:
+        * recover-src/extract_list.c:
+        * oldrecover-src/extract_list.c:
+        * common-src/util.c:
+        * common-src/stream.c:
+        * common-src/file.c:
+        * common-src/dgram.c: Fix warnings
+
+2006-08-17  Kevin Till <ktill@zmanda.com>
+       * common-src/stream.c: Loop 5 times (ntries > 5) on select error
+
+2006-08-14  Paddy Sreenivasan <paddy@zmanda.com>
+        * client-src/sendsize.c: Fix warning
+        * server-src/reporter.c: Fix warnings
+
+2006-07-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * Amanda 2.5.1b2 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.1b2).
+
+2006-07-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driver.c (find_diskspace): Make sure size > 0.
+
+2006-07-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/planner.c: Don't check new disk.
+
+2006-07-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/planner.c: Always log if full size estimate is larger
+                               than the available tape space.
+
+2006-07-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/planner.c: Always log if the latest full dump will be
+                               overwritten soon.
+
+2006-07-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/clock.c (timesub): Don't make a negative time.
+
+2006-07-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amanda.conf.5.xml: Tell which file are loaded.
+       * man/xml-source/amanda-client.conf.5.xml: Ditto.
+
+2006-07-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * NEWS: for 2.5.1b2.
+
+2006-07-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.h (CONFTYPE_HOLDING): New conftype.
+       * common-src/util.c (conf_init_holding, conf_set_holding,
+                            get_conftype_hold): New fonction.
+       * example/amanda.conf.in: Example of new holdingdisk value.
+       * man/xml-source/amanda.8.xml: Example.
+       * man/xml-source/amanda.conf.5.xml: Document it.
+       * server-src/amadmin.c (disklist_one): Print holdingdisk value.
+       * server-src/conffile.c: Parse new CONF_HOLDING type.
+       * server-src/conffile.h (dumptype_get_to_holdingdisk): Change macro.
+       * server-src/diskfile.c (parse_diskline): dumptype_get_to_holdingdisk.
+       * server-src/driver.c: Use new CONFTYPE_HOLDING value.
+
+2006-07-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/selfcheck.c: Fix bug found by coverity.
+       * common-src/debug.c: Fix bug found by coverity.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amflush.c: Typo.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amflush.c: Correct test for driver_stream.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c: Default CLN_AMANDATES to /etc/amandates.
+       * common-src/util.c (conf_init_size): Type is CONFTYPE_SIZE.
+       * server-src/conffile.c (getconf_taperalgo): New function.
+       * server-src/conffile.h (getconf_taperalgo): Prototype.
+       * server-src/driver.c: Use getconf_taperalgo.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c (client_getconf_boolean): New function.
+       * client-src/clientconf.h (client_getconf_boolean): Prototype.
+       * server-src/conffile.c (getconf_boolean): New function.
+       * server-src/conffile.h (getconf_boolean): Prototype.
+       * restore-src/amidxtaped.c: Use getconf_boolean.
+       * server-src/amflush.c: Use getconf_boolean.
+       * server-src/planner.c: Use getconf_boolean.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/getconf.c: Don't print BUGGY.
+       * changer-src/chg-chio.pl.in: Don't parse BUGGY.
+       * changer-src/chg-iomega.pl.in: Don't parse BUGGY.
+       * changer-src/chg-zd-mtx.sh.in: Don't parse BUGGY.
+       * man/xml-source/amgetconf.8.xml: Don't parse BUGGY.
+       * server-src/amverifyrun.sh.in: Don't parse BUGGY.
+       * server-src/amverify.sh.in: Don't parse BUGGY.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/restore.c: Cleanup.
+       * restore-src/amrestore.c: Don't fsf if the last read return 0.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/selfcheck.c: Fix bug found by klocwork.
+       * common-src/rsh-security.c: Fix bug found by klocwork.
+       * common-src/ssh-security.c: Fix bug found by klocwork.
+       * server-src/planner.c: Fix bug found by klocwork.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * tape-src/output-tape.c (tape_tape_open): mt is declared inside #ifdef.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amcheck.c: Fix quoting.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c: client_getconf* validate the type.
+       * common-src/util.c (get_conftype_*): New function.
+       * common-src/util.h (get_conftype_*): Prototype.
+       * server-src/conffile.c: getconf* validate the type.
+       * server-src/conffile.h: Use get_conftype_* function.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c: New AMANDATES client config option.
+       * client-src/clientconf.h: New AMANDATES client config option.
+       * client-src/amandates.c: Use AMANDATES.
+       * client-src/amandates.h: Use AMANDATES.
+       * client-src/selfcheck.c: Use AMANDATES.
+       * client-src/sendbackup-gnutar.c: Use AMANDATES.
+       * client-src/sendsize.c:: Use AMANDATES.
+       * common-src/util.h : New CONF_AMANDATES.
+       * man/xml-source/amanda-client.conf.5.xml: Document it.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c: New GNUTAR_LIST_DIR client config option.
+       * client-src/clientconf.h: New GNUTAR_LIST_DIR client config option.
+       * client-src/selfcheck.c: Use GNUTAR_LIST_DIR.
+       * client-src/sendbackup-gnutar.c: Use GNUTAR_LIST_DIR.
+       * client-src/sendsize.c: Use GNUTAR_LIST_DIR.
+       * common-src/util.h: New CONF_GNUTAR_LIST_DIR.
+       * man/xml-source/amanda-client.conf.5.xml: Document it.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/calcsize.c, client-src/killpgrp.c,
+         client-src/rundump.c, client-src/runtar.c,
+         client-src/selfcheck.c, client-src/sendbackup.c,
+         client-src/sendsize.c, common-src/amanda.h,
+         common-src/debug.c, oldrecover-src/amrecover.c,
+         recover-src/amrecover.c, restore-src/amfetchdump.c,
+         restore-src/amidxtaped.c, server-src/amadmin.c,
+         server-src/amcheck.c, server-src/amcleanupdisk.c,
+         server-src/amflush.c, server-src/amindexd.c,
+         server-src/amlabel.c, server-src/amlogroll.c,
+         server-src/amtape.c, server-src/amtrmidx.c,
+         server-src/amtrmlog.c, server-src/chunker.c,
+         server-src/driver.c, server-src/dumper.c,
+         server-src/getconf.c, server-src/planner.c,
+         server-src/reporter.c, server-src/taper.c: dbrename ot the config dir.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amanda.h: Define DBG_SUBDIR_SERVER, DBG_SUBDIR_CLIENT
+                              and DBG_SUBDIR_CLIENT.
+       * amandad-src/amandad.c, changer-src/chg-scsi.c,
+         changer-src/chg-scsi-chio.c, client-src/calcsize.c,
+         client-src/killpgrp.c, client-src/rundump.c, client-src/runtar.c,
+         client-src/selfcheck.c, client-src/sendbackup.c,
+         client-src/sendsize.c,
+         oldrecover-src/amrecover.c, recover-src/amrecover.c,
+         restore-src/amfetchdump.c, restore-src/amidxtaped.c,
+         restore-src/amrestore.c, server-src/amadmin.c,
+         server-src/amcheck.c, server-src/amcleanupdisk.c,
+         server-src/amflush.c, server-src/amindexd.c,
+         server-src/amlabel.c, server-src/amlogroll.c,
+         server-src/amtape.c, server-src/amtrmidx.c,
+         server-src/amtrmlog.c, server-src/chunker.c,
+         server-src/diskfile.c, server-src/driver.c,
+         server-src/dumper.c, server-src/getconf.c,
+         server-src/infofile.c, server-src/planner.c,
+         server-src/reporter.c (dbopen): Use DBG_SUBDIR_SERVER,
+                                        DBG_SUBDIR_CLIENT or DBG_SUBDIR_CLIENT.
+
+2006-07-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/calcsize.c: Get config on argument.
+       * client-src/killpgrp.c: Get config on argument.
+       * client-src/rundump.c: Get config on argument.
+       * client-src/runtar.c: Get config on argument.
+       * client-src/sendbackup.c: Call program with config as argument.
+       * client-src/sendbackup-dump.c: Call program with config as argument.
+       * client-src/sendbackup-gnutar.c: Call program with config as argument.
+       * client-src/sendbackup.h: Add global g_options.
+       * client-src/sendsize.c: Call program with config as argument.
+
+2006-07-23  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/sendbackup-gnutar.c: Fix bug found by splint.
+       * client-src/sendsize.c: Fix bug found by splint.
+
+2006-07-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taper.c: Fix amfree(mem_splitbuf).
+
+2006-07-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/diskfile.c, server-src/taper.c: Fix memory leak found
+                                                    by coverity.
+
+2006-07-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taper.c: Fix split_buffer allocation problem.
+
+2006-07-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/selfcheck.c, common-src/security-util.c,
+         restore-src/restore.c, server-src/diskfile.c: Fix memory leak found
+                                                       by coverity.
+
+2006-07-20  Jean-Louis Martineau <martineau@zmanda.com>
+       * changer-src/chg-scsi.c, changer-src/scsi-changer-driver.c,
+         client-src/amandates.c, client-src/calcsize.c,
+         client-src/selfcheck.c, client-src/sendbackup.c,
+         client-src/sendsize.c, common-src/security-util.c,
+         recover-src/extract_list.c, restore-src/restore.c,
+         server-src/amindexd.c, server-src/diskfile.c,
+         server-src/driver.c, server-src/reporter.c,
+         server-src/tapefile.c, server-src/taper.c: Fix memory leak found
+                                                    by coverity.
+
+2006-07-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/selfcheck.c : Read client config file.
+       * client-src/sendbackup.c: Read client config file.
+       * client-src/sendsize.c  : Read client config file.
+
+2006-07-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.h (g_option_t): Add 'char *config';
+       * amandad-src/amandad_util.c (parse_g_options): Parse 'config='.
+       * common-src/amfeatures.h (fe_req_options_config): New amfeature.
+       * common-src/amfeatures.c (am_init_feature_set):
+                                                   set fe_req_options_config.
+       * server-src/amcheck.c: Send 'config=' in global options.
+       * server-src/dumper.c: Send 'config=' in global options.
+       * server-src/planner.c: Send 'config=' in global options.
+
+2006-07-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c: Call dbopen("amandad").
+       * changer-src/chg-scsi.c: Call dbopen("server").
+       * changer-src/chg-scsi-chio.c: Call dbopen("server").
+       * client-src/calcsize.c: Call dbopen("client").
+       * client-src/getfsent.c: Call dbopen(NULL).
+       * client-src/killpgrp.c: Call dbopen("client").
+       * client-src/rundump.c: Call dbopen("client").
+       * client-src/runstar.c: Call dbopen("client").
+       * client-src/runtar.c: Call dbopen("client").
+       * client-src/selfcheck.c: Call dbopen("client").
+       * client-src/sendbackup.c: Call dbopen("client").
+       * client-src/sendsize.c: Call dbopen("client").
+       * common-src/amanda.h (dbopen, debug_open): Take a 'char * subdir'
+                                                   argument.
+       * common-src/bsd-security.c: Call dbopen(NULL).
+       * common-src/debug.c (debug_open): Call debug_setup_1(subdir)
+       * common-src/debug.c (debug_setup_1): Take a subdir argument,
+                                             add it to dbgdir.
+       * common-src/file.c: Call dbopen(NULL).
+       * common-src/statfs.c: Call dbopen(NULL).
+       * common-src/token.c: Call dbopen(NULL).
+       * oldrecover-src/amrecover.c: Call dbopen("client").
+       * recover-src/amrecover.c: Call dbopen("client").
+       * restore-src/amfetchdump.c: Call dbopen("server").
+       * restore-src/amidxtaped.c: Call dbopen("server").
+       * restore-src/amrestore.c: Call dbopen("server").
+       * server-src/amadmin.c: Call dbopen("server").
+       * server-src/amcheck.c: Call dbopen("server").
+       * server-src/amcleanupdisk.c: Call dbopen("server").
+       * server-src/amflush.c: Call dbopen("server").
+       * server-src/amindexd.c: Call dbopen("server").
+       * server-src/amlabel.c: Call dbopen("server").
+       * server-src/amlogroll.c: Call dbopen("server").
+       * server-src/amtape.c: Call dbopen("server").
+       * server-src/amtrmidx.c: Call dbopen("server").
+       * server-src/amtrmlog.c: Call dbopen("server").
+       * server-src/chunker.c: Call dbopen("server").
+       * server-src/diskfile.c: Call dbopen("server").
+       * server-src/driver.c: Call dbopen("server").
+       * server-src/dumper.c: Call dbopen("server").
+       * server-src/getconf.c: Call dbopen("server").
+       * server-src/infofile.c: Call dbopen("server").
+       * server-src/planner.c: Call dbopen("server").
+       * server-src/reporter.c: Call dbopen("server").
+       * server-src/taper.c: Call dbopen("server").
+
+2006-07-17  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/chunker.c: Fix rt computation.
+       * server-src/dumper.c: Fix dumptime computation.
+       * server-src/taper.c: Fix rt computation.
+
+2006-07-17  Jean-Louis Martineau <martineau@zmanda.com>
+       * NEWS: Klocwork defects fixed.
+       * NEWS: Coverity defect fixed.
+
+2006-07-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * Makefile.am (pkgdata_DATA): add ReleaseNotes.
+
+2006-07-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * Amanda 2.5.1b1 released.
+       * configure.in: Remove -Werror.
+
+2006-07-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/sendsize.c: Use read/write to copy tar snapshot file.
+       * client-src/sendbackup-gnutar.c: Ditto.
+
+2006-07-13  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/stream.c (stream_accept): Loop 5 times on select error.
+
+2006-07-13  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/dumper.c: The datafd is not scheduled at start,
+                              add test for it.
+       * common-src/stream.c (tcpm_recv_token): Set error_msg.
+       
+2006-07-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c (free_new_argv): Move out of
+                                            #ifndef HAVE_LIBREADLINE.
+
+2006-07-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amadmin.c (tape): Report the number of new tapes instead
+                                      of "a new tape" for each tapes.
+       * server-src/reporter.c (output_tapeinfo): Ditto.
+
+2006-07-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taperscan.c (changer_taper_scan): Report error from
+                                                      changer_find.
+
+2006-07-11  John Franks jrfranks@zmanda.com
+       * configure.in: Fix multiple definition of readline during cygwin
+         compile.
+
+2006-07-11  Paddy Sreenivasan <paddy@zmanda.com>
+       * common-src/pipespawn.c : Fixed compiler warning
+
+2006-07-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amtapetype.8.xml: No default value for -e.
+
+2006-07-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c: Don't conftoken_ungetc(ch) if ch == EOF.
+       * server-src/reporter.c: Check tp == NULL.
+
+2006-07-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * tape-src/tapetype.c: Make -e an needed argument.
+       * man/xml-source/amtapetype.8.xml: Update man page.
+
+2006-07-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * changer-src/chg-zd-mtx.sh.in: Remove .conf from changerfile.
+
+2006-07-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/extract_list.c (check_file_overwrite): Renamed from
+                                                         check_file_overwite.
+       * recover-src/extract_list.c (check_file_overwrite): Do the path check
+         in the correct order (from left ro right).
+
+2006-07-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/file.c (debug_agets): Remove call to dbprintf.
+
+2006-07-10  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/extract_list.c (add_to_unlink_list, do_unlink_list,
+                     free_unlink_list): New function to manage unlink_list.
+       * recover-src/extract_list.c (check_file_overwite): Check all
+         component of an EXTRACT_LIST_ITEM, if a component is not a
+         directory, add it to the unlink_list.
+       * recover-src/extract_list.c (extract_files): Call do_unlink_list and
+         free_unlink_list, rename buf to cwd.
+
+2006-07-10  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/pipespawn.c (pipespawnv_passwd): Add prototype.
+       * common-src/pipespawn.c (pipespawn, pipespawn): Remove 2 NULL
+          parameters to the pipespawnv_passwd call.
+       * common-src/pipespawn.c (pipespawnv_passwd): Remove passwdvar and
+          passwdfd parameters, add passwdvar and local variable.
+          Don't use memcpy to set passwdfd.
+       * common-src/pipespawn.h (pipespawnv_passwd): Remove prototype.
+
+2006-07-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c (stream_read_sync_callback): Remove bogus
+         call of callback.
+
+2006-07-07  Kevin Till  <ktill@zmanda.com>
+       * common-src/bsd-security.c: use STREAM_BUFSIZE instead of -1
+       * common-src/bsdtcp-security.c: ditto
+       * common-src/krb4-security.c: ditto 
+       * common-src/security-util.c: ditto
+       * restore-src/amidxtaped.c: ditto
+
+2006-07-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c (get_conftoken): Remove duplicate conftoken_ungetc.
+
+2006-07-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c: Validate and report big packet size.
+
+2006-07-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * oldrecover-src/Makefile.am: Typo.
+
+2006-07-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/sendsize.c: Typo.
+
+2006-07-06  John Franks        <jrfranks@zmanda.com>
+       * common-src/genversion.c:
+               Remove reference to error().  This causes a compile
+               error on cygwin.
+
+2006-07-06  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 128, 170, 182, 470, 517
+       * changer-src/chg-scsi.c: Validate drivenum, check count_file.
+       * client-src/sendsize.c: Validate level.
+       * oldrecover-src/amrecover.c: Use tm.
+       * recover-src/amrecover.c: Use tm.
+       * server-src/infofile.c (delete_txinfofile): Use local variable.
+
+2006-07-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taper.c: Check for cur_filename.
+       * tape-src/output-file.c: Use vstrextend.
+       * tape-src/tapeio.c: Check for r.
+
+2006-07-06  Jean-Louis Martineau <martineau@zmanda.com>
+       Fix splint warning
+       * oldrecover-src/extract_list.c (clean_tape_list): Cleanup for splint.
+       * recover-src/extract_list.c (clean_tape_list): Cleanup for splint.
+       * server-src/amindexd.c: Add a /*@i@*/.
+       * server-src/conffile.c: Cast to off_t for conf_init_am64.
+       * server-src/driver.c: Cast to unsigned to print pid_t.
+       * server-src/find.c (strip_failed_chunks): Cleanup for splint.
+
+2006-07-06  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 114
+       * server-src/amindexd.c: Free their_feature_string.
+       Klocwork bug 130
+       * restore-src/amrestore.c: Test maximum value for rst_flags->blocksize.
+       Klocwork bug 294
+       * common-src/genversion.c: Check NULL result of malloc.
+       Klocwork bug 294
+       * client-src/selfcheck.c: Check NULL result of fdopen.
+       Klocwork bug 539, 542
+       * oldrecover-src/extract_list.c: Fix pfn2->next = fn2.
+       * recover-src/extract_list.c   : Ditto
+       Klocwork bug 268, 272, 543, 544
+       * oldrecover-src/extract_list.c: Check for cmd != NULL.
+       * recover-src/extract_list.c   : Ditto
+       Klocwork bug 510
+       * restore-src/amidxtaped.c: Check for argv != NULL.
+       Klocwork bug 435
+       * changer-src/scsi-linux.c: Make buffer one larger.
+       Klocwork bug 520
+       * changer-src/scsi-changer-driver.c (OpenDevice): Validate parameters.
+       Klocwork bug 182
+       * changer-src/chg-scsi.c (clean_tape): Check usagetime != NULL.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 551
+       * regex-src/regcomp.c (allocset): Check for p->g->sets
+                                               and p->g->setbits
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 169, 170, 181
+       * changer-src/chg-scsi.c: Validate input.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 282
+       * common-src/file.c (rmpdir): Check for p == NULL.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 524
+       * common-src/dgram.c (dgram_send_addr): Set addr_save earlier.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 495
+       * server-src/taper.c (file_reader_side): Maximum value for
+                                                fallback_splitsize.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 532
+       * recover-src/display_commands.c: Check for cmd != NULL.
+       * oldrecover-src/display_commands.c: Ditto
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 410
+       * restore-src/restore.c (restore): Check for tmp_filename.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 234
+       * server-src/driver.c: Check for h and activehd >= 0.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 338 and 390
+       * server-src/reporter.c (handle_partial, handle_strange): Check result
+         of handle_success.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 558
+       * client-src/selfcheck.c (check_options, check_disk): Check for
+                                                             calcprog == NULL
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 521
+       * client-src/clientconf.c (add_client_conf): Check result of realloc.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 447 and 449
+       * restore-src/restore.c: Check for valid sendbackup request.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 407
+       * restore-src/restore.c (restore): Set statinfo.st_size.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 189
+       * common-src/file.c (sanitise_filename): Never return NULL.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/Makefile.am:    Remove tape-src and libamtape.
+       * client-src/Makefile.am:     Remove tape-src and libamtape.
+       * man/Makefile.am:            Cleanup.
+       * oldrecover-src/Makefile.am: Remove tape-src and libamtape.
+       * recover-src/Makefile.am:    Remove tape-src and libamtape.
+       
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 236
+       * server-src/driver.c (handle_dumper_result): Check for
+                                                     dumper->ev_read != NULL.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 553
+       * restore-src/restore.c (search_a_tape): Check for desired_tape == NULL.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 556 and 557
+       * common-src/security-util.c (bsd_recv_security_ok): Check result of
+         strtok, check service == NULL.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 161
+       * client-src/calcsize.c (calc_load_file): Return NULL if fopen fail.
+       * client-src/calcsize.c (main):  check NULL result from calc_load_file.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 84
+       * server-src/amflush.c (main): Check return of lookup_disk.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 62, 85, 459, 463, 466, 469, 555, 559
+       * common-src/security-util.c: Check result of fdopen.
+       * client-src/sendsize.c     : Ditto.
+       * server-src/amcheck.c      : Ditto.
+       * server-src/amflush.c      : Ditto.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 159, 375, 377, 379, 508, 509, 513, 519
+       * common-src/bsd-security.c:    Replace malloc by alloc.
+       * common-src/bsdudp-security.c: Ditto
+       * common-src/genversion.c:      Ditto
+       * recover-src/amrecover.c:      Ditto
+       * restore-src/amidxtaped.c:     Ditto
+       * server-src/reporter.c:        Ditto
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 562 and 475
+       * recover-src/set_commands.c (cd_dir): Check result of rindex.
+       * oldrecover-src/set_commands.c (cd_dir): ditto.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 552
+       * restore-src/restore.c (load_manual_tape): Alloc space for cur_tapedev.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 406
+       * restore-src/restore.c (restore): Check for final_filename.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 318
+       * server-src/list_dir.c (add_dir_list_item): Check for cur_list->next.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 17, 32
+       * server-src/amadmin.c (disklist_one): Check localtime return NULL.
+       * server-src/amadmin.c (info_one)    : Ditto.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 2, 83, 128, 384, 478, 504, 505, 506, 517, 566, 567
+       * server-src/amadmin.c (seqdatestr): Check localtime return NULL.
+       * common-src/util.c (construct_datestamp, construct_timestamp,
+                            conf_print):         Ditto.
+       * oldrecover-src/amrecover.c (main):      Ditto.
+       * oldrecover-src/uscan.l (ll_parse_date): Ditto.
+       * recover-src/amrecover.c (main):         Ditto.
+       * recover-src/uscan.l (ll_parse_date):    Ditto.
+       * server-src/amflush.c (main):            Ditto.
+       * server-src/reporter.c (handle_success): Ditto.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 470
+       * client-src/sendsize.c (add_diskest): Check for level value.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 372
+       * server-src/reporter.c (nicedate): Check month value.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 20
+       * server-src/amadmin.c (tape): Limit nb_days to 10000.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       Klocwork bug 21
+       * server-src/amadmin.c (balance): Test 'later' after it is set.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/alloc.c (internal_vstralloc): Don't return NULL.
+
+2006-07-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/infofile.c (open_txinfofile): Use local variable.
+
+2006-06-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/restore.c (label_of_current_slot): Close the tapefd if
+                                                        the label mismatch.
+
+2006-06-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/find.c (strip_failed_chunks):
+         - Get a **output_find as parameter.
+         - Check the label before remove a valid chunk.
+         - Memory management fix.
+
+2006-06-28  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c: Improve message for .amandahosts.
+
+2006-06-27  Ian Turner <ian@zmanda.com>
+       * common-src/fileheader.c: Fix a bug where spanned dumps would 
+         always fail.
+
+2006-06-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amcheck.c: Fix test for holdingdisk negative size.
+
+2006-06-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * configure.in: Don't set DEFAULT_TAPE_DEVICE if it is not set.
+       * client-src/clientconf.c: Work DEFAULT_TAPE_DEVICE not set.
+       * common-src/genversion.c: Work DEFAULT_TAPE_DEVICE not set.
+       * recover-src/amrecover.c: Work DEFAULT_TAPE_DEVICE not set.
+       * server-src/getconf.c:    Work DEFAULT_TAPE_DEVICE not set.
+
+2006-06-27  Jean-Louis Martineau <martineau@zmanda.com>
+       Patch by Paul Bijnens
+       * server-src/amcheck.c: Check for access(hdp->diskdir, X_OK).
+
+2006-06-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/conffile.c (getconf_byname): Check for kt->keyword != NULL.
+       * client-src/clientconf.c (client_getconf_byname): Ditto
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/extract_list.c: check_file_overwite.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/extract_list.c: Do the cleanup of the extract list
+                                     at the extraction time
+       * oldrecover-src/extract_list.c: Ditto.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * NEWS: Add new features.
+       * ReleasesNotes: New files.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * docs/Makefile.am (pkgdata_DATA): Add amaespipe.8.txt amcrypt.8.txt
+         amcrypt-asym-ossl.8.txt amcrypt-ossl.8.txt amfetchdump.8.txt
+       * docs/amaespipe.8.txt: New file.
+       * docs/amcrypt.8.txt: New file.
+       * docs/amcrypt-asym-ossl.8.txt: New file.
+       * docs/amcrypt-ossl.8.txt: New file.
+       * docs/amfetchdump.8.txt: New file.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * docs/Makefile.am (pkgdata_DATA): Add howto-auth.txt.
+       * docs/howto-auth: Documentation on auth.
+       * docs/*.txt: Update from xml-docs
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amanda.conf.5.xml: Add notes about bsdudp and bsdtcp.
+       * man/xml-source/amanda-client.conf.5.xml: Ditto.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/extract_list.c (is_empty_dir): New function.
+       * recover-src/extract_list.c: Print a warning if cwd is not empty.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amadmin.c: Allow 'p' and 'P' in --sort argument.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amadmin.c: Print errstr returned by match_disklist.
+       * server-src/amcheck.c: Print errstr returned by match_disklist.
+       * server-src/amflush.c: Print errstr returned by match_disklist.
+       * server-src/diskfile.c (match_disklist): Return an error str.
+       * server-src/diskfile.h (match_disklist): New prototype.
+       * server-src/planner.c: Print errstr returned by match_disklist.
+       * server-src/reporter.c: Accept host/disk as arguments.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amindexd.c (uncompress_file): Set LC_ALL=C before
+                                                  executing sort.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driver.c (wait_children, kill_children): New function.
+       * server-src/driver.c (wait_for_children): Use wait_children and
+                                                  kill_children.
+       * server-src/driver.c (main): Use wait_children.
+       * server-src/driverio.c (taper_cmd, chunker_cmd): Close socket on QUIT
+                                                         or ABORT command.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amfeatures.c (am_init_feature_set): Set
+         fe_amrecover_feedme_tape.
+       * common-src/amfeatures.h (fe_amrecover_feedme_tape): New amfeatures.
+       * common-src/fileheader.c (print_header): Fix.
+       * recover-src/extract_list.c: Use fe_amrecover_feedme_tape.
+       * restore-src/amfetchdump.c: Print error if get_lock == 0.
+       * restore-src/amidxtaped.c: Call send_message if get_lock == 0.
+       * restore-src/restore.c: Split search_tapes in 5 functions.
+       * restore-src/restore.h (send_message): prototype.
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amfetchdump.8.xml: Document -O and new -o.
+       * restore-src/amfetchdump.c: Replace -o by -O
+
+2006-06-22  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c (parse_client_conf): Fix segmentation fault.
+       * server-src/conffile.c (parse_server_conf): Fix segmentation fault.
+
+2006-06-21  Kevin Till <ktill@zmanda.com>
+        * changer-src/chg-juke.sh.in
+        * changer-src/chg-manual.sh.in
+        * changer-src/chg-mcutil.sh.in
+        * changer-src/chg-multi.sh.in
+        * changer-src/chg-mtx.sh.in
+        * changer-src/chg-rait.sh.in
+        * changer-src/chg-disk.sh.in
+        * changer-src/chg-zd-mtx.sh.in
+        * changer-src/chg-null.sh.in
+        * changer-src/chg-chs.sh.in
+        * client-src/patch-system.sh.in
+        * amplot/amplot.sh.in
+        * server-src/amcrypt-ossl.sh.in
+        * server-src/amrmtape.sh.in
+        * server-src/amcleanup.sh.in
+        * server-src/amverifyrun.sh.in
+        * server-src/amaespipe.sh.in
+        * server-src/amdump.sh.in
+        * server-src/amcrypt.sh.in
+        * server-src/amcrypt-ossl-asym.sh.in
+        * server-src/amcheckdb.sh.in
+        * server-src/amfreetapes.sh.in
+        * server-src/amverify.sh.in
+         change /bin/sh to @SHELL@ for configure to pick up the correct
+         shell. Sourceforge bug 1466655
+       * man/xml-source/amcrypt-ossl-asym.8.xml: it's backup-privkey.pem
+
+2006-06-20  Kevin Till <ktill@zmanda.com>
+        * common-src/security-util.c: ignore EINTR in net_writev
+         patch by Jean-Louis Martineau.
+
+2006-06-20  John Franks <jrfranks@zmanda.com>
+       * server-src/conffile.c:
+               Remove Duplicate keyword table entries and alphabetize
+               to make future duplicates easier to spot...
+
+       * server-src/taper.c:
+               Fix compiler warnings when no mmap function is present.
+
+2006-06-20  John Franks <jrfranks@zmanda.com>
+       * server-src/diskfile.c:
+               Default boolean values without parameters to yes if
+               no value is present in configuration file.  This
+               maintains backward compatibility and is logical since
+               a value such as "index" reads as an assertion of fact.
+
+2006-06-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * docs/wishlist.txt: Remove features done in 2.5.0/2.5.1
+
+2006-06-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amanda.conf.5.xml: amrecover_check_label and
+                                           amrecover_do_fsf default to yes.
+       * server-src/conffile (init_dumptype_defaults): DUMPTYPE_INDEX set to 1.
+       * server-src/diskfile.c (parse_diskline): index set from
+                                                 dumptype_get_index.
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amstatus.pl.in: Match quotes in DONE line.
+
+2006-06-16  Kevin Till <ktill@zmanda.com>
+        * example/amanda-client.conf.in:
+         correct DEFAULT_TAPE_SERVER/DEFAULT_SERVER
+       * server-src/amcrypt-ossl-asym.sh.in:
+          set RANDFILE for openssl to place entropy file.
+        * server-src/amcrypt-ossl.sh.in: ditto
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c   : Use strcasecmp to compare auth.
+       * client-src/selfcheck.c  : Ditto
+       * client-src/sendbackup.c : Ditto
+       * restore-src/amidxtaped.c: Ditto
+       * server-src/amindexd.c   : Ditto
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amindexd.c (reply, lreply, fast_lreply): Correct use
+         of arglist_start and arglist_end..
+       * server-src/amindexd.c (lreply_backend): Remove function.
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/bsd-security.c (stream_read_callback): Send error to the
+                                                           callback.
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/extract_list.c: Typo.
+       * restore-src/restore.c: Typo.
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c: Allow include.
+       * client-src/clientconf.c (read_confline): Don't crash.
+       * server-src/conffile.c (read_confline): Don't crash.
+       * recover-src/amrecover.c: Exit if error in conf file.
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/arglist.h: Typo.
+       * recover-src/extract_list.c: handle MESSAGE from amidxtaped.
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amfeatures.c (am_init_feature_set): Set
+                                                        fe_amrecover_message.
+       * common-src/amfeatures.h (am_feature_e): Add fe_amrecover_message.
+       * common-src/arglist.h (printf_arglist_function3): Prototype.
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/restore.c (send_message): New function that send message
+                                               to stderr and/or amrecover.
+       * restore-src/restore.c: Call send_message on some error path.
+
+2006-06-16  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/event.c (event_loop_wait, event_wait): Take an
+                                        event_handle_t * as parameter.
+       * common-src/event.h: New prototype.
+       * common-src/bsd-security.c: Call event_wait(bs->ev_read).
+       * common-src/krb4-security.c: Call event_wait(ks->ev_read).
+       * common-src/krb5-security.c: Call event_wait(ks->ev_read).
+       * common-src/security-util.c: Call event_wait(ss->ev_read).
+
+2006-06-15  Kevin Till <ktill@zmanda.com>
+        * man/xml-source/amcrypt-ossl-asym.8.xml: it's .am_passphrase
+       * server-src/amcrypt-ossl-asym.sh.in: export PATH
+        * server-src/amcrypt-ossl.sh.in: export PATH
+
+
+2006-06-15  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amcheck.c: -w doesn't change the test selection.
+       * man/xml-source/amcheck.8.xml
+
+2006-06-15  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/planner.c: Log empty disklist and no DLE selected.
+
+2006-06-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/bsd-security.c: Use %u to print in_port_t data.
+       * common-src/bsdudp-security.c: Ditto.
+
+2006-06-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * changer-src/chg-disk.sh.in: Return the number of slot in output of
+                                     the -info command.
+       * changer-src/chg-zd-mtx.sh.in: Ditto.
+
+2006-06-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * changer-src/chg-zd-mtx.sh.in: Accept changerfile that already
+                                       have the .conf suffix.
+
+2006-06-13  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c (s_ackwait): Resend the REP on receive of a
+                                            duplicate REQ.
+
+2006-06-13  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c (bsd_recv_security_ok): Set error only
+         if we get an error.
+
+2006-06-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driver.c: usetimestamps is a warning.
+
+2006-06-12  Kevin Till <ktill@zmanda.com>
+        * common-src/security-util.c: if host is 127.0.0.1 and either
+          localhost or localhost.domain is in .amandahost, hostmatch passes.
+        * common-src/security-util.h: update check_user_amandahosts prototype
+
+2006-06-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c (process_writenetfd): Close the pipe if the
+                                                     security_stream is closed.
+       * recover-src/extract_list.c: Improve message if we don't get thei
+                                     FEATURE line from amidxtaped.
+
+2006-06-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/amrecover.c: Read amanda-client.conf and
+                                  <conf>/amanda-client.conf.
+
+2006-06-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c, common-src/tapelist.c,
+         restore-src/restore.c, server-src/amcheck.c, server-src/amindexd.c,
+         server-src/amtape.c, server-src/changer.c, server-src/driver.c,
+         server-src/planner.c, server-src/taper.c,
+         server-src/taperscan.c: Fix memory leak.
+
+2006-06-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/restore.c: Fix Adding at end of list.
+
+2006-06-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taper.c (syncpipe_putstr): Don't crash if str is NULL.
+
+2006-06-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/holding.c (pick_datestamp): Fix reading user input.
+
+2006-06-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/amrecover.c (sigint_handler): Call send_command only if
+                                                   amindexd is alive.
+
+2006-06-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c (connect_port): ETIMEDOUT is a fatal error.
+
+2006-06-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/stream.c (stream_client_internal): Get errno set
+                                                       correctly.
+       * server-src/driver.c (handle_chunker_result): Don't assert(0) on
+                             receive of a TRYAGAIN from a chunker, but set
+                             chunker->result.
+       * server-src/dumper.c: Try gethostbyname("localhost") before calling
+                              stream_client and log appropriate message.
+
+2006-06-09  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amcheck.c: Report ERROR if gethostbyname("localhost")
+                               doesn't succeed.
+
+2006-06-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c (add_client_conf): New function to map
+                                                    normal option to their
+                                                    -o equivalent.
+       * client-src/clientconf.h (add_client_conf): Prototype.
+       * man/xml-source/amrecover.8.xml: Document -o.
+       * recover-src/amrecover.c: Also read <config>/amanda-client.conf
+
+2006-06-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/diskfile.c (parse_diskline): Only return 0 or -1.
+
+2006-06-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.h (g_option_t): Add auth.
+       * amandad-src/amandad_util.c (init_g_options): Set auth to NULL.
+       * amandad-src/amandad_util.c (parse_g_options): Parse auth.
+       * amandad-src/amandad_util.c (free_g_options): Free auth.
+       * client-src/sendbackup.c: Get amandad_auth from command line and
+                                  compare with REQ packet.
+       * common-src/amfeatures.h (fe_amindexd_options_hostname,
+                                  fe_amindexd_options_features,
+                                  fe_amindexd_options_auth,
+                                  fe_amidxtaped_options_hostname,
+                                  fe_amidxtaped_options_features,
+                                  fe_amidxtaped_options_auth): New amfeatures.
+       * common-src/amfeatures.c (am_init_feature_set): Set new amfeatures.
+       * recover-src/amrecover.c: Send auth in OPTIONS of req packet.
+       * recover-src/extract_list.c: Send auth in OPTIONS of req packet.
+       * restore-src/amidxtaped.c: Parse amandad_auth from command line.
+                                   Get auth from OPTIONS line.
+                                   Compare them.
+       * server-src/amindexd.c: Parse amandad_auth from command line.
+                                Get auth from OPTIONS line.
+                                Compare them.
+
+2006-06-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c(connect_port): Return -2 on ECONNREFUSED error
+                                          from connect.
+
+2006-06-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c: exec the service with the auth as parameter.
+       * amandad-src/amandad.c(writebuf): Do no close fd.
+       * client-src/selfcheck.c: Read the auth for the command line and
+                                 compare with the option string.
+       * client-src/selfcheck.c(main): Do no close 0,1,2 fd.
+
+2006-06-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amanda.8.xml(CONFIGURATION OVERWRITE): New section.
+       * man/xml-source/amadmin.8.xml,   man/xml-source/amcheck.8.xml,
+         man/xml-source/amdump.8.xml,    man/xml-source/amflush.8.xml,
+         man/xml-source/amgetconf.8.xml, man/xml-source/amlabel.8.xml,
+         man/xml-source/amreport.8.xml,
+         man/xml-source/amrestore.8.xml: Add -o option.
+
+2006-06-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c(get_conftoken): Merge from zmanda.
+
+2006-06-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c(get_conftoken): Remove a conftoken_ungetc.
+
+2006-06-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/bsd-security.c (stream_read_callback): Merge with zmanda.
+
+2006-06-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c(process_writenetfd): Call security_stream_read
+                                                    only if size > 0.
+
+2006-06-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/conffile.c (lookup_interface): Fix merge error.
+
+2006-06-07  John Franks <jrfranks@zmanda.com>
+       * common-src/amanda.h:
+               Fix isnormal() replacement macro to indirectly
+               check if a floating point value is != 0.0.
+               This prevents compiler warnings.
+
+2006-06-07  John Franks <jrfranks@zmanda.com>
+       * common-src/util.c
+               Put in "/* NOTREACHED */" comments after error() calls.
+       * server-src/diskfile.c
+               Change disktype index default to yes for backward compatibility.
+
+2006-06-06  John Franks <jrfranks@zmanda.com>
+       * amandad-src/amandad.c common-src/bsd-security.c:
+               Correct fix for infinite amandad loop.
+
+2006-06-06  John Franks <jrfranks@zmanda.com>
+       * common-src/stream.c common-src/util.c:
+               Lint clean again.
+       * server-src/conffile.c:
+               Remove replicated line
+
+2006-06-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c (conftoken_ungetc): Return the character.
+       * common-src/util.c (get_conftoken): Merge to allow escape character.
+       * common-src/util.c (read_block): Allow STRING as IDENT.
+       * server-src/conffile.c (getconf_long, getconf_size): New function.
+       * server-src/conffile.c: Cleanup after Merge.
+
+2006-06-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amadmin.c, server-src/amcheck.c, server-src/amflush.c,
+         server-src/amlabel.c, server-src/amlogroll.c, server-src/amtrmidx.c,
+         server-src/amtrmlog.c, server-src/getconf.c,
+         server-src/reporter.c: Usage -o
+       * server-src/amflush.c, server-src/amlogroll.c, server-src/amtrmidx.c,
+         server-src/amtrmlog.c, server-src/chunker.c, server-src/driver.c,
+         server-src/dumper.c, server-src/getconf.c, server-src/planner.c,
+         server-src/reporter.c,
+         server-src/taper.c: Add call to report_bad_conf_arg.
+       * server-src/conffile.c(get_comprate, get_compress): Parse CONF_END.
+
+2006-06-06  John Franks <jrfranks@zmanda.com>
+       * configure.in:
+               Increase checking level from 1 to 2 for SUN lint.
+       * client-src/amandates.c client-src/clientconf.c
+         common-src/security-util.c recover-src/amrecover.c
+         recover-src/extract_list.c regex-src/regcomp.c server-src/amcheck.c
+         server-src/amlabel.c server-src/chunker.c server-src/conffile.c
+         server-src/conffile.h server-src/diskfile.c server-src/diskfile.h
+         server-src/driver.c server-src/holding.c server-src/reporter.c
+         server-src/tapefile.c server-src/taper.c tape-src/amdd.c:
+               Lint clean again.
+       * common-src/util.h common-src/util.c:
+               Lint clean again.
+               Add missing conftype size.
+       * common-src/bsd-security.c
+               Fix infinte loop which consumes all /tmp space and 1/2
+               the CPU time when EOF is reached on socket.
+
+2006-06-05  Paddy Sreenivasan <paddy@zmanda.com>
+        * common-src/util.c: Fix warning
+
+2006-06-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/amfetchdump.c, server-src/amcheck.c,
+         server-src/amcheckdb.sh.in, server-src/amcleanup.sh.in,
+         server-src/amdump.sh.in, server-src/amflush.c,
+         server-src/amlabel.c, server-src/amlogroll.c,
+         server-src/amtrmidx.c, server-src/amtrmlog.c,
+         server-src/chunker.c, server-src/conffile.c,
+         server-src/diskfile.c, server-src/driver.c,
+         server-src/driverio.c, server-src/dumper.c,
+         server-src/getconf.c, server-src/planner.c,
+         server-src/reporter.c, server-src/taper.c,
+         server-src/taperscan.c: Allow -o options and some memory fix.
+       * server-src/conffile.c(lookup_dumptype, lookup_tapetype,
+         lookup_interface): Use strcasecmp.
+
+2006-06-02  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/stream.c (stream_client_internal): Use connect_portrange.
+       * common-src/util.c (connect_portrange): First, try to connect with a
+                                                port already used.
+       * common-src/util.c (connect_port): Try to connect with a specific port.
+       * common-src/util.h: Cleanup.
+
+2006-06-02  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/reporter.c: Remove empty if.
+
+2006-06-02  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/util.c (read_block): Don't read CONF_NL aftre the '{'.
+       * server-src/conffile.c(get_holdingdisk, get_tapetype, get_interface):
+         Read a CONF_NL after the call to read_block.
+       * server-src/conffile.c(read_dumptype): Read a CONF_NL if we are not
+                                               called from diskfile.
+       * server-src/diskfile.c: Don't loop on empty line after read_dumptype.
+
+2006-06-01  Kevin Till  <ktill@zmanda.com>
+        * server-src/amcrypt-ossl.sh.in: symmetric encrypt script using openSSL.
+          Thanks to Ben Slusky.
+        * server-src/amcrypt-ossl-asym.sh.in: public-ley encrypt script using openSSL.
+        * man/xml-source/amcrypt-ossl.8.xml: man page
+        * man/xml-source/amcrypt-ossl-asym.8.xml: man page
+        * configure.in: ditto
+        * man/Makefile.am: ditto
+        * man/entities/global.entities: ditto
+        * server-src/Makefile.am: ditto
+
+2006-06-01  John Franks <jfranks@zmanda.com>
+       Eliminate Cygwin compile warnings.
+       * client-src/getfsent.c:  Quiet unused parameter warnings.
+       * client-src/selfcheck.c: Quiet unused parameter warnings.
+       * common-src/security-util.h: Make hostname const char *.
+
+2006-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amcheck.c: holdingdisk_get_disksize() return an off_t.
+       * server-src/find.c: result should be ssize_t.
+
+2006-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amanda.h: Remove am64_t.
+       * client-src/clientconf.c, client-src/clientconf.h, common-src/util.c,
+         common-src/util.h, server-src/conffile.c, server-src/conffile.h:
+         Second pass of config cleanup, add function to parse -o argument.
+       * recover-src/amrecover.c: -o command argument.
+       * restore-src/restore.c: Use off_t instead of am64_t.
+       * server-src/amadmin.c: New config subcommand. -o command argument.
+       * server-src/amlabel.c: Fix memory leak.
+       * server-src/diskfile.c: Fix memory leak.
+       * server-src/diskfile.h: Rename no_hold to to_holdingdisk.
+       * server-src/driver.c: Many.
+       * server-src/planner.c: am64_t to off_t.
+
+2006-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       This is the first pass of a general rewrite of configuration file
+       parsing, It will now use array to store all options.
+
+       * client-src/clientconf.c:
+       * client-src/clientconf.h:
+       * server-src/conffile.c:
+       * server-src/conffile.h:
+       * common-src/util.c: Many new functions.
+       * common-src/util.h:
+
+       * restore-src/amidxtaped.c, server-src/amcheck.c,
+         server-src/amcleanupdisk.c, server-src/amlabel.c,
+         server-src/diskfile.c, server-src/driver.c, server-src/driverio.c,
+         server-src/find.c, server-src/holding.c, server-src/planner.c,
+         server-src/reporter.c,
+         server-src/taper.c: Use new macro to get configuration option.
+
+2006-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c, client-src/amandates.c, client-src/noop.c,
+         client-src/selfcheck.c, client-src/sendsize.c,
+         common-src/bsd-security.c, common-src/bsdtcp-security.c,
+         common-src/bsdudp-security.c, common-src/fileheader.c,
+         common-src/rsh-security.c, common-src/security-util.c,
+         common-src/security-util.h, common-src/ssh-security.c,
+         recover-src/extract_list.c, server-src/amcheck.c,
+         server-src/amindexd.c, server-src/amlogroll.c,
+         server-src/diskfile.c, server-src/driver.c, server-src/dumper.c,
+         server-src/find.c, server-src/logfile.c, server-src/planner.c,
+         server-src/reporter.c,
+         server-src/tapefile.c: Fix memory and fd leak.
+
+2006-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/find.c (search_holding_disk): Take the datestamp from the
+         file, not the directory name, otherwise usetimestamps=no doesn't
+         work.
+
+2006-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/stream.c (stream_server): New priv parameter if we want
+                                              a reserved port. Don't try to
+                                              get a reserved port if priv==0.
+       * common-src/stream.h (stream_server): New prototype.
+       * common-src/bsd-security.c: Call stream_server with priv==0.
+       * common-src/krb4-security.c: Call stream_server with priv==1.
+       * common-src/security-util.c: Call stream_server with priv==0.
+       * restore-src/amidxtaped.c: Call stream_server with priv==0.
+       * server-src/chunker.c: Call stream_server with priv==0.
+       * server-src/taper.c: Call stream_server with priv==0.
+
+2006-06-01  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/diskfile.c: Return -1 if open of diskfile failed.
+       * server-src/driver.c: Change message if didn't get a DATE line.
+       * server-src/reporter.c: Ignore faillure in reading amanda.conf
+                                disklist and tapelist.
+
+2006-05-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amanda.8.xml: Documents service in .amandahosts.
+
+2006-05-29  Jean-Louis Martineau <martineau@zmanda.com>
+       Previous patch doesn't work because 'make -j2' will use fd 3.
+       * amandad-src/Makefile.am: Use a temporary file for output of
+                                  'make listlibsrc'.
+       * changer-src/Makefile.am: Ditto.
+       * client-src/Makefile.am: Ditto.
+       * common-src/Makefile.am: Ditto.
+       * oldrecover-src/Makefile.am: Ditto.
+       * recover-src/Makefile.am: Ditto.
+       * restore-src/Makefile.am: Ditto.
+       * server-src/Makefile.am: Ditto.
+       * tape-src/Makefile.am: Ditto.
+
+2006-05-29  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/Makefile.am: 'make listlibsrc' send it's ouput to fd 3.
+       * changer-src/Makefile.am: Ditto.
+       * client-src/Makefile.am: Ditto.
+       * common-src/Makefile.am: Ditto.
+       * oldrecover-src/Makefile.am: Ditto.
+       * recover-src/Makefile.am: Ditto.
+       * restore-src/Makefile.am: Ditto.
+       * server-src/Makefile.am: Ditto.
+       * tape-src/Makefile.am: Ditto.
+
+2006-05-28  Paddy Sreenivasan <paddy@zmanda.com>
+        * tape-src/tapeio.c : Fixed warnings
+        * tape-src/output-rait.c : Fixed warnings
+        * tape-src/output-null.c : Fixed warnings
+        * tape-src/output-file.c : Fiexed warnings
+        * recover-src/amrecover.c: Fixed warnings
+        * recover-src/extract_list.c : Fixed warnings
+        * server-src/amadmin.c : Fixed warnings
+        * server-src/driver.c : Fixed warnings
+        * server-src/infofile.c : Fixed warnings
+
+2006-05-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/conffile.c (read_dumptype): Parse SSH_KEYS.
+
+2006-05-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c (udp_inithandle): Remove bad merge.
+       * server-src/amindexd.c: Improve error message.
+       * server-src/planner.c: Add a space in output.
+
+2006-05-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/conffile.c: Set dpcur.no_hold correctly,
+                                Fix for conffile program.
+
+2006-05-26  Jean-Louis Martineau <martineau@zmanda.com>
+       Allow many services to share the same tcp connection for
+       bsdtcp/ssh/rsh.
+       Add a security_close_connection to the security-api.
+       * amandad-src/amandad.c (wait_30s, exit_on_qlength): New variable to
+                                       control auth specific behaviour.
+       * common-src/bsd-security.c: Add sec_close_connection_none.
+       * common-src/bsdudp-security.c: Add sec_close_connection_none.
+       * common-src/krb4-security.c: Add sec_close_connection_none.
+       * common-src/krb5-security.c: Add sec_close_connection_none.
+       * common-src/security.h (security_close_connection): Prototype.
+       * common-src/security-util.h (sec_close_connection_none,
+                                     tcpm_close_connection): Prototype.
+       * common-src/security-util.h (struct tcp_conn): Add toclose.
+       * common-src/security-util.h (struct sec_stream): Add closed_by_me and
+                                                         closed_by_network.
+       * common-src/security-util.c (sec_close_connection_none,
+                                     tcpm_close_connection): New function.
+       * common-src/security-util.c: Handle many services on one connection.
+       * common-src/bsdtcp-security.c: Handle many services on one connection.
+       * common-src/rsh-security.c: Handle many services on one connection.
+       * common-src/ssh-security.c: Handle many services on one connection.
+       * recover-src/amrecover.c: Add call security_close_connection.
+       * recover-src/extract_list.c: Add call security_close_connection.
+       * server-src/amcheck.c: Add call security_close_connection.
+       * server-src/dumper.c: Add call security_close_connection.
+
+2006-05-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c (bsd_prefix_packet): We need the username
+         of the getuid() user.
+
+2006-05-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/fileheader.c: Parse datestamp on F_TAPEEND.
+       * restore-src/amrestore.c: Set read_result to the result of
+                                  read_file_header.
+       * restore-src/restore.c (read_file_header): Return a ssize_t.
+                       Rename bytes_read by read_result.
+                       Set read_result to the result of read_file_header.
+       * restore-src/restore.h (read_file_header): New prototype.
+
+2006-05-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taperscan.c: Replace bogus newvstralloc by vstrextend.
+
+2006-05-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/getfsent.c (print_entry): Add prototype.
+       * common-src/token.c (main): Shut up compiler warning.
+       * server-src/infofile.c (dump_rec, dump_db): Add prototype.
+
+2006-05-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c, common-src/bsd-security.c,
+         common-src/bsdtcp-security.c, common-src/bsdudp-security.c,
+         common-src/event.c, common-src/krb5-security.c,
+         common-src/protocol.c, common-src/rsh-security.c,
+         common-src/security-util.c, common-src/ssh-security.c,
+         common-src/util.c, server-src/driver.c: comment debugging.
+
+2006-05-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security-util.c: typo.
+       * server-src/amcheck.c: Make sure all check are done.
+
+2006-05-25  Jean-Louis Martineau <martineau@zmanda.com>
+       Fix for program not compiled by default.
+       make bsdsecurity still not compile.
+       * common-src/bsd-security.c(bind_portrange): prototype change.
+       * common-src/Makefile.am (STANDARD_COMMON_STUFF_NOT_FILE): Add match.o.
+       * server-src/conffile.c: Many typo.
+       * tape-src/tapeio.c: Use OFF_T_FMT and SSIZE_T_FMT when needed, typo.
+       
+2006-05-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/fileheader.c (validate_datestamp): Works for 8 characters
+                                                       datestamp.
+       * common-src/security-util.c (tcpm_send_token): netlength must be
+                                                       uint32_t.
+       * common-src/security-util.c (bsd_prefix_packet): Fix typo.
+       * common-src/util.c (get_time): Don't do computation for starttime.
+       * server-src/conffile.c (read_dumptype): Do computation for starttime.
+
+2006-05-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/krb5-security.c (krb5_sendpkt, krb5_stream_read_sync,
+                                     recv_token): Return ssize_t.
+       * common-src/krb5-security.c (krb5_accept, krb5_stream_accept,i
+                                     krb5_stream_auth): Shut up compiler.
+       * tape-src/output-file.c: Use SSIZE_MAX instead of SSIZE_T_MAX.
+
+2006-05-25  Jean-Louis Martineau <martineau@zmanda.com>
+       * configure.in(AM_INIT_AUTOMAKE): Fix.
+
+2006-05-25  John Franks <jrfranks@zmanda.com>
+       Pass user CFLAGS correctly to machine generated code and do not
+       enforce code quality checks on them.
+       * configure.in:
+         Put compiler code check flags into existing, but previously
+          unused, AM_CFLAGS for Makefiles to pick up.  CFLAGS should
+         now only contain mandatory flags.
+
+       * recover-src/Makefile.am  oldrecover-src/Makefile.am:
+         Use CFLAGS for compiling C code generated from uparse.y and uscan.l
+
+2006-05-24  John Franks <jrfranks@zmanda.com>
+       Add support for binary path names on disk and in configuration files.
+           (Allow spaces in filenames.)
+
+       Allow quoted strings for disklist entries.
+
+       Lint clean code using sun lint, splint and strict GCC warnings. 
+       Type / size clean, dead code removal, portibility checks, etc.
+       Many checks are still turned off.  See configure.in for lint flags used.
+
+       Increase debug output in /tmp/amanda/*debug files.
+
+       Set SO_REUSEADDR on sockets help avoid running out of ports.
+
+       * configure.in:
+               Added lint program discovery with specific targets for SUN lint and splint.
+               Check each compiler option to see if GCC supports it.
+               Enable more code quality warnings.
+               Change missing xsltproc to warning rather than error.
+               Define _GNU_SOURCES to build flags.
+               Make size_t and time_t printf format macros.
+               Check for isnormal() availability.
+               Don't install man pages if they are not built.
+               Fix man pages to not attempt build or install if
+                       --without-built-manpages is set.
+
+       * Makefile.am amandad-src/Makefile.am changer-src/Makefile.am
+         client-src/Makefile.am common-src/Makefile.am
+         oldrecover-src/Makefile.am recover-src/Makefile.am
+         restore-src/Makefile.am server-src/Makefile.am tape-src/Makefile.am:
+               Add lint target.
+
+       * common-src/amanda.h common-src/dgram.c common-src/stream.c
+         common-src/util.c:
+               Keep checking for ports on all bind errors.
+               Delay and retry a few times if all ports are busy.
+               Retry bind failures after all methods fail.
+               increase bind checking timeout to 30 minutes.
+
+       * client-src/amandad.c
+               Issue wait when any child exits.  (Get rid of defunct processes)
+               Stat() index file before using system command.
+                 (shell is not reporting failure if index is not present)
+
+       * recover-src/extract_list.c:
+         Fix problem of 'add *' not adding directories.
+         Fix problem of freeing pointer not obtained through malloc.
+         Touch up file addition to actually use the file names
+            retrieved when adding a directory and not the directory itself.
+
+       * server-src/taper.c
+               Strenghten error recovery for broken syncpipes and writer errors.
+
+       * changer-src/chg-scsi-chio.c client-src/amandates.c
+         client-src/client_util.c client-src/findpass.c client-src/getfsent.c
+         client-src/selfcheck.c client-src/sendbackup-gnutar.c
+         client-src/sendbackup-star.c client-src/sendbackup.c
+         client-src/sendsize.c common-src/bsd-security.c common-src/file.c
+         common-src/krb5-security.c server-src/amcheck.c server-src/amindexd.c
+         server-src/diskfile.c server-src/driver.c server-src/dumper.c
+         server-src/holding.c server-src/infofile.c server-src/logfile.c
+         server-src/tapefile.c:
+               allow empty lines in input streams.
+
+       * recover-src/uparse.y
+               print message when input is garbage.
+
+       * server-src/getconf.c:
+               Define HOSTNAME_INSTANCE if it was not already defined
+               for Kerberos.
+
+       * configure.in: Make readline warning less specific.  Readline is
+         used by all input from terminal now.
+
+2006-05-24  Kevin Till <ktill@@zmanda.com>
+       * client-src/sendbackup.c: ignore SIGINT
+       * common-src/ssh-security.c: add to total only when n > 0
+       * common-src/ssh-security.c: add ssh to error,
+         retry writev when EINTR, EAGAIN is seen
+         to STDOUT. exit when options is chosen in template mode.
+       * server-src/driver.c: make sure timestamp is not null
+       * amanda/configure.in: remove template.d/amanda.conf which is a dup 
+         of amanda-harddisk.conf
+       * example/Makefile.am: add template.d/README
+       * amanda-harddisk.conf.in: set tapedev
+       * recover-src/amrecover.c: aclose socket before exit.
+       * recover-src/extract_list.c: ditto
+       * amanda_enterprise.spec: remove template.d/amanda.conf, add template.d/README
+         in the failure cases. <> user input field.
+       * server-src/amcheck.c: no quoted text is a warning
+       * server-src/driver.c: no need to amfree qname
+         argument. Search mtx in PATH too.
+       * example/template.d/advanced.conf.in: fix comment for autoflush
+       * example/template.d/advanced.conf.in: add usetimestamps
+       * server-src/diskfile.c: to catch unsupported compress-encryption
+         combination and abort amdump gracefully.
+       * man/xml-source/amanda.conf.5.xml: fix syntax, add 
+         dumptype references.  
+       * man/xml-source/amanda.8.xml: fix syntax
+       * configure.in:                 ditto
+       * man/Makefile.am:              ditto
+       * example/amanda.conf.in:       tidy up
+        * man/xml-source/amaespipe.8.xml: add uuencode as requirement
+        * man/xml-source/amcrypt.8.xml:   add uuencode as requirement
+        * server-src/amcheck.c: catch dumptype misconfiguration
+        * server-src/diskfile.c: ditto
+        * server-src/driverio.c: ditto
+        * server-src/planner.c:  ditto
+        * server-src/conffile.c: check includefile before calling
+          read_conffile_recursively
+       * example/amanda.conf.in:       add public-key encryption dumptype example
+       * man/xml-source/amanda.8.xml:  fix some formatting     
+       * server-src/planner.c: adjust setuid() calling sequences so that ssh can work
+       * server-src/dumper.c:  ditto
+       * configure.in:              add LOW_TCPPORTRANGE for amrecover
+       * common-src/stream.c:       use LOW_TCPPORTRANGE
+       * server-src/amdump.sh.in:   check if config is supplied
+       * man/xml-source/amrestore.8.xml: add notes on "-f" option
+
+2006-05-24  Ian Turner <ian@zmanda.com>
+       * configure.in: Properly document --without-xsltproc as itself, 
+         and not the (nonexistant) option --without-built-manpages.
+
+2006-05-16  John Franks <jrfranks@zmanda.com>
+       * amandad-src/amandad.c client-src/clientconf.c common-src/bsd-security.c
+         common-src/bsdudp-security.c common-src/dgram.c common-src/krb4-security.c
+         common-src/krb5-security.c common-src/match.c common-src/packet.c
+         common-src/security-util.c common-src/security-util.h
+         common-src/security.h common-src/util.c oldrecover-src/Makefile.am
+         oldrecover-src/set_commands.c recover-src/amrecover.c
+         recover-src/extract_list.c server-src/conffile.c server-src/driver.c
+         server-src/dumper.c server-src/planner.c server-src/reporter.c:
+               Minimal changes to get tree to compile along with some more
+               debugging output.
+
+2006-05-15  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amadmin.c (disklist_one): print spindle.
+
+2006-05-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * commmon-src/bsd-security.c: Typo.
+
+2006-05-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/Makefile.am (noinst_HEADERS): Add security-util.h.
+
+2006-05-12  Jean-Louis Martineau <martineau@zmanda.com>
+       Build a big tok_t enum for server and client config.
+       * client-src/clientconf.c: Move many things to util.c.
+       * client-src/clientconf.h: Remove extern variable.
+       * common-src/util.c: Add common part of clientconf.c and conffile.c
+       * common-src/util.h: Prototype.
+       * server-src/conffile.c: Move many things to util.c.
+       * server-src/diskfile.c(disk_parserror): Rename from parserror.
+       * server-src/taper.c: Make many variable static.
+
+2006-05-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/restore.c: Fix use of possibly NULL input.
+
+2006-05-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/ssh-security.c (ssh_connect): Retrieve ssh_keys from
+                                                  configuration.
+       * server-src/amadmin.c(disklist_one): Print ssh_keys.
+       * server-src/conffile.c(SSH_KEYS): Parse new dumptype option.
+       * server-src/conffile.h(dumptype_t): Add ssh_keys.
+       * server-src/diskfile.c(parse_diskline): Copy new field.
+       * server-src/diskfile.h(disk_t) Add ssh_keys.
+       * server-src/driverio.c(dumper_cmd): Send dp->ssh_keys in a PORT_DUMP
+                                            command to the dumper.
+       * server-src/dumper.c: Parse ssh_keys in a PORT_DUMP command.
+       * server-src/dumper.c(dumper_get_security_conf): Return the ssh_keys.
+       * server-src/server_util.c(amhost_get_security_conf): Return the
+                                                             ssh_keys.
+
+2006-05-12  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c: Set allow_many_services to 0 if auth=bsdtcp.
+       * common-src/bsd-security.c: Use security-util.c.
+       * common-src/bsdtcp-security.c: New security-api.
+       * common-src/bsdudp-security.c: New secutity-api.
+       * common-src/krb4-security.c: Use security-util.c.
+       * common-src/krb5-security.c: Use security-util.c.
+       * common-src/Makefile.am (libamanda_la_SOURCES): Add bsdtcp-security.c,
+                                                            bsdtcp-security.c
+                                                        and security-util.c.
+       * common-src/protocol.c: Debuging cleanup.
+       * common-src/rsh-security.c Use security-util.c.
+       * common-src/security.c: Use bsdtcp_security_driver
+                                and bsdudp_security_driver.
+       * common-src/security.h(accept): New prototype.
+       * common-src/security-util.c: Many common function for security-api.
+       * common-src/security-util.h: many prototype for security-api.
+       * common-src/ssh-security.c Use security-util.c.
+       * common-src/stream.c (stream_client_internal): Call connect_portrange.
+       * common-src/util.c (make_socket): Make a socket.
+       * common-src/util.c (connect_portrange): Make a socket, bind it and
+                                                connect.
+       * common-src/util.h (connect_portrange): Prototype.
+       * configure.in: new --with-bsdtcp-security and --with-bsdudp-security.
+
+2006-05-10  Jean-Louis Martineau <martineau@zmanda.com>
+       Patch by <amanda@inventivetechnology.at>
+       * man/xml-source/amrecover.8.xml: Document listhost command.
+
+2006-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       Patch by <amanda@inventivetechnology.at>
+       * server-src/amindexd.c: new LISTHOST command.
+       * recover-src/set_commands.c (list_host): New function.
+       * recover-src/amrecover.h (list_host): Prototype.
+       * recover-src/help.c (list_host): Print help.
+       * recover-src/uscan.l: Parse listhost command.
+       * recover-src/uparse.y: LISTHOST command.
+       * oldrecover-src/set_commands.c (list_host): New function.
+       * oldrecover-src/amrecover.h (list_host): Prototype.
+       * oldrecover-src/help.c (list_host): Print help.
+       * oldrecover-src/uscan.l: Parse listhost command.
+       * oldrecover-src/uparse.y: LISTHOST command.
+
+2006-05-08  Ian Turner <ian@zmanda.com>
+       * server-src/amcheck.c: Make it an error when the expected new 
+         tape cannot be found. Thanks to Paul Bijnens
+         <paul.bijnens@xplanation.com> for the patch and to Jason L 
+         Tibbitts III <tibbs@math.uh.edu> for noticing this problem.
+
+2006-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * driverio.h (shed_s): Add est_nsize, est_csize, degr_nsize, degr_csize
+                              for nativa and compressed estimate size.
+       * planner.c: Send the native and compressed estimate size to the driver.
+       * driver.c: log with L_STATS the estimate of a successful dump.
+       * reporter.c: Parse the L_STATS.
+       * reporter.c(generate_bad_estimate): New function that will put in the
+                                            NOTES section all bad estimate.
+
+2006-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * configure.in (AC_CONFIG_FILES): Add oldrecover-src/Makefile.
+       * Makefile.am (RECOVER_SUBDIRS): Add oldrecover-src.
+       * oldrecover-src/amrecover.c: Copy of old recover-src/amrecover.c
+       * oldrecover-src/amrecover.h: Copy of old recover-src/amrecover.h
+       * oldrecover-src/display_commands.c: Copy of old
+                                            recover-src/display_commands.c
+       * oldrecover-src/extract_list.c: Copy of old recover-src/extract_list.c
+       * oldrecover-src/help.c: Copy of old recover-src/help.c
+       * oldrecover-src/Makefile.am: Copy of old recover-src/Makefile.am
+       * oldrecover-src/set_commands.c: Copy of old recover-src/set_commands.c
+       * oldrecover-src/uparse.y: Copy of old recover-src/uparse.y
+       * oldrecover-src/uscan.l: Copy of old recover-src/uscan.l
+       * recover-src/amrecover.c: Works with security-api.
+       * recover-src/amrecover.h: Works with security-api.
+       * recover-src/extract_list.c: Works with security-api.
+
+2006-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c: Fixup.
+
+2006-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/packet.h: pkt_t.body is now a char*.
+       * common-src/packet.c (pkt_init): Return an alloced pkt.body.
+       * common-src/packet.c (pkt_cat): Increade pkt.body size if needed.
+       * common-src/protocol.c: Free allocated pkt.body.
+       * common-src/dgram.c (dgram_cat): Return int.
+       * common-src/dgram.h (dgram_cat): New prototype.
+       * common-src/krb5-security.c: Work with dynamicaly allocated packet
+                                     body.
+       * common-src/rsh-security.c: Work with dynamicaly allocated packet
+                                    body.
+       * common-src/ssh-security.c: Work with dynamicaly allocated packet
+                                    body.
+       * amandad-src/amandad.c: Work with dynamicaly allocated packet body.
+       * server-src/amcheck.c: Don't limit packet size.
+       * server-src/planner.c: Don't limit packet size.
+
+2006-05-08  Jean-Louis Martineau <martineau@zmanda.com>
        * amandad-src/amandad.c (service_new): Apply the correct patch.
 
-2006-05-28  Jean-Louis Martineau <martineau@zmanda.com>
-       * Amanda 2.5.0p2 released.
-       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.0p2).
-       * NEWS: Changes in release 2.5.0p2.
+2006-05-08  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taper.c: Fix compiler warning.
+       * common-src/match.c: Many function get const parameters.
+       * common-src/amanda.h: Prototype change.
 
 2006-05-07  Jean-Louis Martineau <martineau@zmanda.com>
-       * amandad-src/amandad.c (service_new): Make sure that the 3 data[] fd
-         are not in the range DATA_FD_OFFSET to
+       * amandad-src/amandad.c (service_new): Make sur that the 3 data_read[]
+         and the 3 data_write[] fd are not in the range DATA_FD_OFFSET to
          DATA_FD_OFFSET+DATA_FD_COUNT-1.
 
+2006-05-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/tapelist.c (append_to_tapelist): Remove bad amfree.
+
+2006-05-05  Nikhil Bandiwadekar <nikhil@zmanda.com>
+        * server-src/conffile.c: fix to correctly handle am64 datatype
+
 2006-05-04  Jean-Louis Martineau <martineau@zmanda.com>
        * server-src/taper.c: Write the slot number in the
-                             'taper: wrote label' line.
+                             'taper: wrote label' line.
        * server-src/amverifyrun.sh.in: Parse that line.
 
 2006-05-02  Jean-Louis Martineau <martineau@zmanda.com>
        * amstatus.pl.in: Limit characters for hostname in setup_estimate line.
 
-2006-04-28  Jean-Louis Martineau <martineau@zmanda.com>
-       * Amanda 2.5.0p1 released.
-       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.0p1).
-       * NEWS: Changes in release 2.5.0p1.
+2006-04-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/rsh-security.c: Pass "amdump amindexd amidxtaped" option
+                                    to amandad.
+       * common-src/ssh-security.c: Ditto.
+
+2006-04-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c: Accept a list of services on the command line.
+
+2006-04-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/tapelist.c (append_to_tapelist): Fix memory leak.
+
+2006-04-27  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c: Fix memory leak.
+       * amandad-src/amandad.h (free_g_options): Prototype.
+       * amandad-src/amandad_util.c (free_g_options): New function to free a
+                                                      g_option_t.
+       * server-src/amcleanupdisk.c: Fix memory leak.
+       * server-src/reporter.c: Fix memory leak.
+       * server-src/tapefile.c: Fix memory leak.
+       * server-src/taperscan.c: Put message in error_message.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amcheck.c (start_server_check): Memory leak.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/Makefile.am (noinst_HEADERS): Add amandad.h.
+       * client-src/Makefile.am (noinst_HEADERS): Add clientconf.h.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amanda-client.conf.5.xml: New file.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amanda.h (check_user_ruserok, check_user_amandahosts):
+         Remove prototype.
+       * common-src/bsd-security.c: Pass the service name across check_user*
+         function and validate it from the .amandahosts file.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/amidxtaped.c: Can be launched by amandad.
+       * server-src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/amandad-src
+       * server-src/Makefile.am (amidxtaped__LDADD): Link with libamandad.
+       * restore-src/restore.c: Fix indentation.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amindexd.c: Can be launched by amandad
+       * server-src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/amandad-src
+       * server-src/Makefile.am (amindexd_LDADD): Link with libamandad.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * amandad-src/amandad.c: New file.
+       * amandad-src/amandad.h: New file.
+       * amandad-src/amandad_util.c: New file, add function init_g_options
+                                     parse_g_options.
+       * amandad-src/Makefile.am: New file.
+       * client-src/amandad.c: Removed file.
+       * client-src/amandad.h: Removed file.
+       * client-src/client_util.c (init_g_options, parse_g_options): Remove.
+       * client-src/client_util.h (init_g_options, parse_g_options): Remove.
+       * client-src/Makefile.am (INCLUDES): -I$(top_srcdir)/amandad-src
+       * client-src/Makefile.am (libexec_PROGRAMS): Remove amandad.
+       * client-src/Makefile.am (LDADD): Add
+                                 ../amandad-src/libamandad.$(LIB_EXTENSION).
+       * client-src/selfcheck.c: #include "amandad.h".
+       * client-src/sendsize.c: #include "amandad.h".
+       * configure.in (AC_CONFIG_FILES): amandad-src/Makefile.
+       * Makefile.am (SUBDIRS): amandad-src.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * docs/security-api.txt: Document security_read_sync.
+       * common-src/security.h: Typo.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/amandad.c (service_new): Pass the "amandad" argument to
+                                             the service.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/bsd-security.c: Allow to run many services on the same
+                                    client. Cleanup.
+       * common-src/rsh-security.c: Ditto.
+       * common-src/ssh-security.c: Ditto.
 
-2006-04-24  Ian Turner <ian@zmanda.com>
-       * server-src/changer.c: Don't crash if we go to taperscan "Plan B".
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/security.h (security_stream_read_sync): Prototype.
+       * common-src/bsd-security.c (bsd_stream_read_sync): New function.
+       * common-src/krb4-security.c (krb4_stream_read_sync): New function.
+       * common-src/krb5-security.c (krb5_stream_read_sync): New function.
+       * common-src/rsh-security.c (rsh_stream_read_sync): New function.
+       * common-src/ssh-security.c (ssh_stream_read_sync): New function.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/amandad.c: Open pipe in both direction to the services.
+       * client-src/sendbackup.c: Deal with the newer pipe.
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/clientconf.c: New file to read the client configuration
+                                  file.
+       * client-src/clientconf.h: Header.
+       * client-src/Makefile.am: Link clientconf into libamclient.
+       * configure.in (AC_CONFIG_FILES): example/amanda-client.conf.
+       * docs/amanda-client.conf.5.txt: New documentation.
+       * docs/Makefile.am (pkgdata_DATA): amanda-client.conf.5.txt.
+       * example/amanda-client.conf.in: exemple.
+       * example/Makefile.am  (noinst_DATA): amanda-client.conf.
+       * man/entities/global.entities: amclientconf.
+       * man/Makefile.am (COMMON_MAN5_PAGES): amanda-client.conf.5.
+       * man/xml-source/amanda.8.xml (SEE ALSO): amanda-client.conf(5).
+       * man/xml-source/amanda.conf.5.xml (SEE ALSO): amanda-client.conf(5).
+       * man/xml-source/amrecover.8.xml (SEE ALSO): amanda-client.conf(5).
+
+2006-04-26  K. K. George<kkg@zmanda.com>
+       * server-src/reporter.c: Fix to untaint the mailto parameter.
+       * server-src/amcheck.c: Fix to untaint the mailto parameter
+        * changer-src/chg-scsi.c: Fix to untaint the mailto parameter.
+        * changer-src/chg-scsi-chio.c: Fix to untaint the mailto parameter.
+        * common-src/util.h: Added function to check if the mailto 
+          parameter is untainted
+        * common-src/util.c: Added function to check if the mailto 
+          parameter is untainted
+
+2006-04-26  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/event.c(event_wait): New function.
+       * common-src/event.h(event_wait): prototype.
+       * docs/eventapi.txt: Document event_wait.
 
 2006-04-24  Jean-Louis Martineau <martineau@zmanda.com>
        * server-src/planner.c: Fix divide by zero if runtapes==0.
 
+2006-04-24  K. K. George<kkg@zmanda.com>
+        * server-src/reporter.c: Fix to make the mailto parameter in
+          amanda.conf optional. Added two more commandline options
+          -i & -Maddress.
+        * server-src/amcheck.c: Fix to make the mailto parameter in
+          amanda.conf optional.
+        * man/xml-source/amreport.8.xml: Modified to document the
+          -i & -Maddress commandline parameters
+        * docs/amreport.8.txt: Modified to document the
+          -i & -Maddress commandline parameters
+        * changer-src/chg-scsi.c: Fix to make the mailto parameter in
+          amanda.conf optional.
+        * changer-src/chg-scsi-chio.c: Fix to make the mailto parameter in
+          amanda.conf optional.
+
 2006-04-23  Jean-Louis Martineau <martineau@zmanda.com>
        * server-src/driver.c (handle_chunker_result): make sure that
                                                       est_size > act-size.
 
-2006-04-23  Jean-Louis Martineau <martineau@zmanda.com>
-       * server-src/chunker.c: Read the START command to set the datestamp.
-       * server-src/driver.c: Send a START command to the chunker.
-       * server-src/driverio.c (chunker_cmd): Add the START command.
-       * server-src/server_util.c (cmdstr): Add the START command.
-       * server-src/server_util.h (cmd_t): Add the START command.
+2006-04-21  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/changer.c (changer_command): Make sure fd[0] != 1.
+
+2006-04-19  Jean-Louis Martineau <martineau@zmanda.com>
+       * restore-src/amidxtaped.c: Cleanup.
+
+2006-04-19  Ian Turner <ian@zmanda.com>
+       * tape-src/output-tape.c: Do a more thourough check to ensure 
+         that we actually got a tape device, before proceeding to use 
+         it.
+
+2006-04-18  Ian Turner <ian@zmanda.com>
+       * changer-src/chg-disk.sh.in: Check that the virtual device is a 
+         directory with proper permissions.
+       * server-src/changer.c: Do the right thing (failure) if there is 
+         a problem with the changer.
+
+2006-04-18  Ian Turner <ian@zmanda.com>
+       * recover-src/uscan.l: Accept setdate of the form
+         yyyy-MM-dd-hh-mm in addition to yyyy-MM-dd-hh-mm-ss.
+       * man/xml-source/amrecover.8.xml: Document this change.
+
+2006-04-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/help.c: Document setdate YYYY-MM-DD-HH-MM-SS format.
+       * man/xml-source/amrecover.8.xml: Ditto.
+
+2006-04-14  Jean-Louis Martineau <martineau@zmanda.com>
+       * client-src/amandad.c: Use %p to printf pointer.
 
 2006-04-14  Jean-Louis Martineau <martineau@zmanda.com>
        * server-src/amtape.c: Add update command.
 
+2006-04-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taper.c: log_add(L_WARNING) the output of taper_scan if
+                              no valid tape are found.
+
+2006-04-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amcheck.c: Call taper_scan with
+               (..., FILE_taperscan_output_callback,outf) arguments.
+       * server-src/amtape.c:  Call taper_scan with
+               (..., FILE_taperscan_output_callback,stderr) arguments.
+       * server-src/taper.c:   Call taper_scan with
+               (..., CHAR_taperscan_output_callback, &error_msg) arguments.
+       * server-src/taperscan.h(FILE_taperscan_output_callback,
+                                CHAR_taperscan_output_callback): Protoype.
+       * server-src/taperscan.h(taper_scan): New protoype, remove
+         error_message arg, add taperscan_output_callback and data arg.
+       * server-src/taperscan.c(FILE_taperscan_output_callback): Callback
+         that print the msg to it's arg, which is FILE*.
+       * server-src/taperscan.c(CHAR_taperscan_output_callback): Callback
+         that append the msg to it's arg, which is char*.
+       * server-src/taperscan.c(taper_scan): Fix for new arguments.
+       * server-src/taperscan.c(changer_taper_scan): Fix for new arguments.
+
+2006-04-11  Jean-Louis Martineau <martineau@zmanda.com>
+       * man/xml-source/amanda.conf.5.xml: Document amandad_path and
+                                           client_username dumptype option.
+
 2006-04-11  Jean-Louis Martineau <martineau@zmanda.com>
        * common-src/krb4-security.c: Increase timeout to 60 seconds.
        * common-src/rsh-security.c: Increase timeout to 60 seconds.
        * common-src/ssh-security.c: Increase timeout to 60 seconds.
 
+2006-04-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/conffile.c: New configuration option usetimestamps.
+       * server-src/conffile.h: New configuration option usetimestamps.
+       * example/amanda.conf.in: Document new usetimestamps options.
+       * man/xml-source/amanda.conf.5.xml: Document new usetimestamps options.
+       * server-src/amflush.c: Use datestamp or timestamp depending of
+                               usetimesstamps.
+       * server-src/planner.c: Use datestamp or timestamp depending of
+                               usetimesstamps.
+       * server-src/driver.c: Log an ERROR if many run a day and
+                              usetimestamps us set to no.
+
+2006-04-07  Ian Turner <ian@zmanda.com>
+       * server-src/changer.c: Don't crash if we go to taperscan "Plan 
+         B".
+
+2006-04-07  Ian Turner <ian@zmanda.com>
+       * server-src/changer.c: Only print changer debug messages if 
+         there was a problem.
+
+2006-04-07  Ian Turner <ian@zmanda.com>
+       * recover-src/amrecover.c: Print a more helpful command if mount
+         point autodetection fails.
+       * recover-src/display_commands.c: Print a more helpful message
+         if the user tries to ls without having setdisk earlier.
+
+2006-04-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amadmin.c: Fix use of datestamp as int.
+       * server-src/find.c: Ditto.
+       * server-src/reporter.c: Ditto.
+       * server-src/tapefile.c: Ditto.
+
+2006-04-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/Makefile.am: Fix dependency between genversion and
+                                 versuff.o.
+
+2006-04-07  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/amrecover.c: Change initialization of server_name and
+                                  tape_server_name.
+
 2006-04-07  Jean-Louis Martineau <martineau@zmanda.com>
        * restore-src/amrestore.c: reset count_error to 0 on a restore.
 
+2006-04-06  Kevin Till <ktill@zmanda.com>
+       * server-src/Makefile.am: always install planner/dumper setuid-root
+       * server-src/amcheck.c:   check planner/dumper for setuid-root
+       * server-src/dumper.c:    drop privilege asap. Switch between bsd 
+         and ssh auth is now possible with the same installation.
+       * server-src/planner.c:   ditto
+
+2006-04-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/taperscan.c (changer_taper_scan): Pass a pointer to the
+         changer_loadslot call.
+
+2006-04-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/tapefile.c (lookup_last_reusable_tape): Fix a datestamp
+         test with an int.
+
+2006-04-06  Ian Turner <vectro@vectro.org>
+       * recover-src/amrecover.c (main): Check AMANDA_SERVER and 
+         AMANDA_TAPE_SERVER environment variables before falling back 
+         to compiled-in defaults. Document this new behavior. Thanks to 
+         Malcolm Locke <malc@hoodee.co.uk> for the idea and patch.
+
+2006-04-06  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/reporter.c (handle_chunk): CHUNK line always have the
+         datestamp.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/krb5-security.c: Fix for krb5_connect call in
+          open_callback.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/driver.c (start_some_dumps): Recover correctly if the
+         chunker reply with something that is not a PORT command.
+       * server-src/driver.c (dump_to_tape): remove duplicate free_serial.
+       * server-src/driverio.c: Improve debugging.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/tapelist.c(unmarshal_tapelist_str): Fix
+         "value computed is not used" compiler warning.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/bsd-security.c (bsd_connect): New datap argument.
+       * common-src/krb4-security.c (krb4_connect): New datap argument.
+       * common-src/krb5-security.c (krb5_connect): New datap argument.
+       * common-src/rsh-security.c (rsh_connect): New datap argument,
+                retrieve amanda_path and client_username from configuration.
+       * common-src/ssh-security.c (ssh_connect): New datap argument,
+               retrieve amanda_path and client_username from configuration.
+       * common-src/protocol.c: Pass new datap argument to security_connect.
+       * common-src/security.h(connect): New prototype.
+       * common-src/security.h(security_connect): Add datap to macro.
+       * server-src/amadmin.c(disklist_one): Print amandad_path and
+                                             client_username.
+       * server-src/conffile.c(AMANDAD_PATH, CLIENT_USERNAME): Parse new
+                               dumptype option.
+       * server-src/conffile.h(dumptype_t): Add amandad_path and
+                                            client_username.
+       * server-src/diskfile.c(parse_diskline): Copy new field.
+       * server-src/diskfile.h(disk_t) Add amandad_path and client_username.
+       * server-src/driverio.c(dumper_cmd): Send dp->amandad_path and
+         dp->client_username in a PORT_DUMP command to the dumper.
+       * server-src/dumper.c: Parse amandad_path and client_username in a
+                              PORT_DUMP command.
+       * server-src/dumper.c(dumper_get_security_conf): New function to return
+                               configuration option to the security-api.
+       * server-src/dumper.c: Use dumper_get_security_conf for the callback
+                              to protocol_sendreq.
+       * server-src/planner.c Use amhost_get_security_conf for the callback
+                              to protocol_sendreq.
+       * server-src/amcheck.c: Use amhost_get_security_conf for the callback
+                               to protocol_sendreq.
+       * server-src/server_util.c(amhost_get_security_conf): New function to
+                       return configuration option to the security-api,
+                       it expect an am_host_t arg.
+       * server-src/server_util.h(amhost_get_security_conf): Prototype.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amstatus.pl.in: Remove duplicate instruction.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amindexd.c: Remove all code that set str_buffer_size,
+                                rename str_buffer_size to reply_buffer_size,
+                                rename buf to reply_buffer,
+       * server-src/amindexd.c(reply, lreply_backend): Increase reply_buffer
+                                                       size if required.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * common-src/amfeatures.h: Add fe_amrecover_timestamp amfeature.
+       * common-src/amfeatures.c (am_init_feature_set):
+                                                Add fe_amrecover_timestamp.
+       * server-src/amindexd.c(opaque_ls_one): New function.
+       * server-src/amindexd.c(disk_history_list,opaque_ls_one): Send only a
+         datestamp if client doesn't have fe_amrecover_timestamp.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * recover-src/uscan.l: Parse "setdate YYYY-MM-DD-HH-MM-SS".
+       * server-src/amindexd.c (cmp_date): New function to cmp datestamp with
+                                           timestamp, use it where needed.
+       * server-src/amindexd.c (amindexd_nicedate): Fix for timestamp.
+       * server-src/amtrmidx.c: Fix for timestamp.
+       * server-src/disk_history.h (DUMP_ITEM): Increase size of date.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amflush.c: Send DATE line to driver, use timestamp.
+       * server-src/amindex.c (getindexfname): Increase datebuf size.
+       * server-src/amtrmlog.c: Fix bug with date_keep computation if
+                                dumpcycle is INF.
+       * server-src/amtrmlog.c: rotate timestamped log file.
+       * server-src/chunker.c: Receive START cmd, use timestamp.
+       * server-src/driver.c: Receive DATE line, send START cmd to chunker,
+                              use timestamp.
+       * server-src/driverio.c (startup_dump_processes): Send START cmd to
+                                                         dumper.
+       * server-src/driverio.c (dumper_cmd, chunker_cmd): Send START command.
+       * server-src/driverio.h (startup_dump_processes): Prototype change,
+                                                         need the timestamp.
+       * server-src/dumper.c: Receive START cmd, use timestamp.
+       * server-src/find.c (find_nicedate): Fix for timestamp.
+       * server-src/planner.c: Send DATE line to driver, use timestamp.
+       * server-src/server_util.c (cmdstr): Add START.
+       * server-src/server_util.h (cmd_t): Add START.
+       * server-src/taper.c: Get timestamp from TAPER_START command.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * server-src/amindexd.c (amindexd_nicedate): New function.
+       * server-src/find.h (struct find_result_s): Remove datestamp and
+                datestamp_aux field, only timestamp will be used.
+       * restore-src/amfetchdump.c: Convert datestamp to 'char *'.
+       * restore-src/restore.c: Convert datestamp to 'char *'.
+       * server-src/amindexd.c: Convert datestamp to 'char *'.
+       * server-src/amlabel.c: Convert datestamp to 'char *'.
+       * server-src/amtrmidx.c: Convert datestamp to 'char *'.
+       * server-src/find.c: Convert datestamp to 'char *'.
+       * server-src/reporter.c: Convert datestamp to 'char *'.
+       * server-src/tapefile.c: Convert datestamp to 'char *'.
+       * server-src/tapefile.h: Convert datestamp to 'char *'.
+       * server-src/taper.c: Convert datestamp to 'char *'.
+
+2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.1b1).
+
 2006-04-05  Jean-Louis Martineau <martineau@zmanda.com>
        * server-src/driver.c: Change expression to remove overflow.
 
        * restore-src/restore.c: Fix errors found using Coverity tools.
 
 2006-03-09  Jean-Louis Martineau <martineau@zmanda.com>
-       * server-src/holding.c: Fix John fix.
+       * server-src/holding.c: Fix errors found using Coverity tools.
 
 2006-03-09  Jean-Louis Martineau <martineau@zmanda.com>
        * server-src/driverio.c: Fix errors found using Coverity tools.
-       * server-src/planner.c: Fix John fix.
+       * server-src/planner.c: Fix errors found using Coverity tools.
 
 2006-03-09  John Franks <jrfranks@zmanda.com>
        * changer-src/chg-scsi.c:        Fix errors found using Coverity tools.
          syntax, in favor of xx/-1.
 
 2005-12-29  John Franks <jrfranks@zmanda.com>
-       * Index: recover-src/display_commands.c
+       * recover-src/display_commands.c
          Fix list deletion which did not update list root with NULL pointer.
          Make free_dir_item() a non-recursive function to prevent stack bloat.
          Fix list insertion code which inserts item in list initializes entry.
-       * Index: recover-src/extract_list.c
+       * recover-src/extract_list.c
          Fix to initialize lditem before using it...
          Prevent multiple frees of cmd string.
          Do not free err which is only initialized with static string pointers.
          Fix typo which caused newstralloc() to free the wrong memory.
-       * Index: server-src/amindexd.c
+       * server-src/amindexd.c
          Fix Compiler warning of unused variable.
-       * Index: server-src/taperscan.c
+       * server-src/taperscan.c
          Fix Compiler warning of bogus format specifier.
   
 2005-12-29  Kevin Till<ktill@zmanda.com>
index 9ebd7062a56828e0e9ca92e4c5f146cd1840f91e..fe62a56d193c1d20819bdbfa793ef45b4dde49f4 100644 (file)
@@ -19,7 +19,7 @@ if WANT_RESTORE
 RESTORE_SUBDIRS = restore-src
 endif
 if WANT_RECOVER
-RECOVER_SUBDIRS = recover-src
+RECOVER_SUBDIRS = recover-src oldrecover-src
 endif
 if WANT_AMPLOT
 PLOT_SUBDIRS = amplot
@@ -28,6 +28,7 @@ endif
 SUBDIRS = \
        config \
        common-src \
+       amandad-src \
        $(TAPE_SUBDIRS) \
        $(CLIENT_SUBDIRS) \
        $(SERVER_SUBDIRS) \
@@ -37,6 +38,7 @@ SUBDIRS = \
        man docs example
 
 pkgdata_DATA = \
+       ReleaseNotes                    \
        COPYRIGHT                       \
        COPYRIGHT-APACHE                \
        COPYRIGHT-REGEX
@@ -107,6 +109,18 @@ $(CONFIG_STATUS): $(SNAPSHOT_STAMP)
 SNAPSHOT:
        : SNAPSHOT file was removed, will reconfigure...
 
+lint:
+       (cd amandad-src; make lint)
+       (cd changer-src; make lint)
+       (cd client-src; make lint)
+       (cd common-src; make lint)
+       (cd oldrecover-src; make lint)
+       (cd recover-src; make lint)
+       (cd regex-src; make lint)
+       (cd restore-src; make lint)
+       (cd server-src; make lint)
+       (cd tape-src; make lint)
+
 ## Do not release the *.test.c sources.  They get built on the fly and
 ## would contain a path from the distribution machine, which will just
 ## confuse the target user.
index cfabcdcbc7f1feea5d258f51a47647b62abc4d2e..488e39f77b8b53694fdd87f9e15ab02a9361d452 100644 (file)
@@ -70,9 +70,9 @@ pkgdataDATA_INSTALL = $(INSTALL_DATA)
 DATA = $(pkgdata_DATA)
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = config common-src tape-src client-src dumper-src \
-       server-src changer-src restore-src recover-src amplot man docs \
-       example
+DIST_SUBDIRS = config common-src amandad-src tape-src client-src \
+       dumper-src server-src changer-src restore-src recover-src \
+       oldrecover-src amplot man docs example
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -91,11 +91,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -103,6 +106,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -292,12 +297,13 @@ ACINCLUDE_M4_DEPS = $(ACINCLUDE_M4I) $(LIBTOOL_M4I)
 @WANT_TAPE_TRUE@TAPE_SUBDIRS = tape-src
 @WANT_SERVER_TRUE@SERVER_SUBDIRS = server-src changer-src
 @WANT_RESTORE_TRUE@RESTORE_SUBDIRS = restore-src
-@WANT_RECOVER_TRUE@RECOVER_SUBDIRS = recover-src
+@WANT_RECOVER_TRUE@RECOVER_SUBDIRS = recover-src oldrecover-src
 @WANT_AMPLOT_TRUE@PLOT_SUBDIRS = amplot
 # order is significant, don't change it arbitrarily
 SUBDIRS = \
        config \
        common-src \
+       amandad-src \
        $(TAPE_SUBDIRS) \
        $(CLIENT_SUBDIRS) \
        $(SERVER_SUBDIRS) \
@@ -307,6 +313,7 @@ SUBDIRS = \
        man docs example
 
 pkgdata_DATA = \
+       ReleaseNotes                    \
        COPYRIGHT                       \
        COPYRIGHT-APACHE                \
        COPYRIGHT-REGEX
@@ -817,6 +824,18 @@ $(CONFIG_STATUS): $(SNAPSHOT_STAMP)
 SNAPSHOT:
        : SNAPSHOT file was removed, will reconfigure...
 
+lint:
+       (cd amandad-src; make lint)
+       (cd changer-src; make lint)
+       (cd client-src; make lint)
+       (cd common-src; make lint)
+       (cd oldrecover-src; make lint)
+       (cd recover-src; make lint)
+       (cd regex-src; make lint)
+       (cd restore-src; make lint)
+       (cd server-src; make lint)
+       (cd tape-src; make lint)
+
 dist-hook:
        find $(distdir)/. -name '*.test.c' -exec rm {} \;
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/NEWS b/NEWS
index db2f5074363083bc6a8d658f8ec5aaf52bd3b2d0..27a49f0fb42640b5682d5544de62659283143c39 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,13 +1,53 @@
+Changes in release 2.5.1
+
+   * Defects found by Coverity scan and Klocwork K7 analysis tools fixed.
+   * Works with GNU tar 1.15.91 - work with new gtar state file format.
+   * Open SSL encryption support
+   * Two new authentication methods: bsdtcp, bsdudp.
+   * Unlimited number of DLEs on a client with bsdtcp, rsh and ssh
+     authentication methods.
+   * Recovery process amrecover uses Secure API. amoldrecover command
+     (same syntax and functionality as amrecover command) is provided for
+     compatibility with old Amanda releases. amoldrecover command uses old
+     amidxtaped/amindexd protocol.
+   * Amanda debug files are separated into client/server/amandad and
+     are also classified based on Amanda configuration name.
+
+   * Amanda command changes
+         o amfetchdump -o is replaced by -O.
+         o amcheck -w option does all tests including the tape writable test.
+           Use amcheck -t -w to do only the tape writable test.
+         o -o command option to override Amanda configuration. See amanda man
+           page for details.
+         o amgetconf command doesn't write the BUGGY message when a entry
+           is not found in the configuration file.
+
+   * Amanda configuration file changes
+         o amanda.conf changes
+               + amrecover_do_fsf in amanda.conf defaults to yes
+               + amrecover_check_label in amanda.conf defaults to yes
+               + usetimestamps in amanda.conf to support multiple
+                 backup runs in a calendar day.
+               + holdingdisk in amanda.conf supports new values:
+                 NEVER, AUTO, REQUIRED.
+               + amandad_path, client_username and ssh_keys in
+                 amanda.conf for ssh/rsh authentication.
+         o New amanda client configuration file - amanda-client.conf.
+           Different client configuration file can be used for each Amanda
+           configuration.
+               + gnutar_list-dir and amandates can be specified in
+                 Amanda client configuration file - amanda-client.conf
+         o .amandahosts format changes to allow use of secure API for recovery.
+         o Amanda service entries in xinetd configuration has changed. 
+
+
 Changes in release 2.5.0p2
 
-* Fix major bug in amandad.
-* amverifyeun works.
-* amstatus works with ':' in diskname.
+* listhost subcommand in amrecover
 
 Changes in release 2.5.0p1
 
 * Add the 'amtape update' command.
-* Many small bug fix.
 
 Changes in release 2.5.0
 
diff --git a/ReleaseNotes b/ReleaseNotes
new file mode 100644 (file)
index 0000000..664194b
--- /dev/null
@@ -0,0 +1,48 @@
+               Release Notes for amanda-2.5.1
+
+
+usetimestamps
+
+  This new feature will record all dump with timestamp instead of datestamp,
+  it will allow to do many dump in a day and recover easily anyone of them.
+
+  If you use this features, you will not be able to downgrade to 2.5.0 or
+  earlier.
+
+  see the usetimestamps section of 'man amanda.conf'
+
+
+bsdudp/bsdtcp
+
+  These are 2 new auth, they still use bsd authentification like bsd, but
+  use less port.
+
+  bsdudp is like bsd, it use udp for connecting to client but it will use
+  only one tcp port for all data stream.
+
+  bsdtcp use tcp to connect the to client and it's the only network
+  connection use.  It doesn't have the udp packet size limit, so you can
+  have an unlimited number of DLE for a single host.
+
+amrecover use the security-api
+
+  amrecover now use the security-api, You don't need to configure an
+  amindexd and an amidxtaped services in your xinetd.
+  amindexd and amidxtaped will be launched by amandad like any other services.
+  You must do modification to your xinetd configuration and .amandahosts toi
+  allow connection to amindexd and amidxtaped.
+
+new format of xinetd.d/amanda
+
+  amandad get in arguments the list of services it can launch, you must add
+  theses services in the server_args options.
+
+new format of .amandahosts
+
+  You must append to each line the services this client can launch, the
+  default is "amdump"
+
+
+See the AUTHORIZATION section of the amanda man page and the
+docs/howto-auth.txt
+
diff --git a/amandad-src/Makefile.am b/amandad-src/Makefile.am
new file mode 100644 (file)
index 0000000..3411292
--- /dev/null
@@ -0,0 +1,59 @@
+# Makefile for Amanda client programs.
+
+INCLUDES =     -I$(top_builddir)/common-src \
+               -I$(top_srcdir)/common-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
+lib_LTLIBRARIES =       libamandad.la
+LIB_EXTENSION = la
+
+libexec_PROGRAMS =     amandad
+
+if WANT_RUNTIME_PSEUDO_RELOC
+AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+endif
+
+libamandad_la_SOURCES= amandad_util.c
+libamandad_la_LDFLAGS = -release $(VERSION)
+
+noinst_HEADERS  = amandad.h
+
+###
+# Because libamanda includes routines (e.g. regex) provided by some system
+# libraries, and because of the way libtool sets up the command line, we
+# need to list libamanda twice here, first to override the system library
+# routines, and second to pick up any references in the other libraries.
+###
+
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamandad.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+install-exec-hook:
+       @list="$(libexec_PROGRAMS) $(libexec_SCRIPTS)"; \
+       for p in $$list; do \
+               pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed '$(transform)'`; \
+               echo chown $(BINARY_OWNER) $$pa; \
+               chown $(BINARY_OWNER) $$pa; \
+               echo chgrp $(SETUID_GROUP) $$pa; \
+               chgrp $(SETUID_GROUP) $$pa; \
+       done
+
+lint:
+       @ for p in $(libexec_PROGRAMS); do                                      \
+               f="$$p.c $(libamandad_la_SOURCES)";                             \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               (cd ../server-src; make listlibsrc);                            \
+               f="$$f "`cat ../server-src/listlibsrc.output`;                  \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+
diff --git a/amandad-src/Makefile.in b/amandad-src/Makefile.in
new file mode 100644 (file)
index 0000000..80fd348
--- /dev/null
@@ -0,0 +1,655 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for Amanda client programs.
+
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+libexec_PROGRAMS = amandad$(EXEEXT)
+subdir = amandad-src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libamandad_la_LIBADD =
+am_libamandad_la_OBJECTS = amandad_util.lo
+libamandad_la_OBJECTS = $(am_libamandad_la_OBJECTS)
+libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(libexec_PROGRAMS)
+amandad_SOURCES = amandad.c
+amandad_OBJECTS = amandad.$(OBJEXT)
+amandad_LDADD = $(LDADD)
+amandad_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamandad.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libamandad_la_SOURCES) amandad.c
+DIST_SOURCES = $(libamandad_la_SOURCES) amandad.c
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMANDA_DBGDIR = @AMANDA_DBGDIR@
+AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
+AMANDA_TMPDIR = @AMANDA_TMPDIR@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
+CAT = @CAT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHIO = @CHIO@
+CHS = @CHS@
+CLIENT_LOGIN = @CLIENT_LOGIN@
+CLIENT_SCRIPTS_OPT = @CLIENT_SCRIPTS_OPT@
+COMPRESS = @COMPRESS@
+CONFIGURE_COMMAND = @CONFIGURE_COMMAND@
+CONFIG_DIR = @CONFIG_DIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DB_EXT = @DB_EXT@
+DD = @DD@
+DEFAULT_CHANGER_DEVICE = @DEFAULT_CHANGER_DEVICE@
+DEFAULT_CONFIG = @DEFAULT_CONFIG@
+DEFAULT_RAW_TAPE_DEVICE = @DEFAULT_RAW_TAPE_DEVICE@
+DEFAULT_SERVER = @DEFAULT_SERVER@
+DEFAULT_TAPE_DEVICE = @DEFAULT_TAPE_DEVICE@
+DEFAULT_TAPE_SERVER = @DEFAULT_TAPE_SERVER@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOC_BUILD_DATE = @DOC_BUILD_DATE@
+DUMP = @DUMP@
+DUMPER_DIR = @DUMPER_DIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GETCONF = @GETCONF@
+GNUPLOT = @GNUPLOT@
+GNUTAR = @GNUTAR@
+GNUTAR_LISTED_INCREMENTAL_DIR = @GNUTAR_LISTED_INCREMENTAL_DIR@
+GNUTAR_LISTED_INCREMENTAL_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+HAVE_XSLTPROC_FALSE = @HAVE_XSLTPROC_FALSE@
+HAVE_XSLTPROC_TRUE = @HAVE_XSLTPROC_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LL_FMT = @LL_FMT@
+LN_S = @LN_S@
+LTALLOCA = @LTALLOCA@
+LTLIBOBJS = @LTLIBOBJS@
+MAILER = @MAILER@
+MAKEINFO = @MAKEINFO@
+MAXTAPEBLOCKSIZE = @MAXTAPEBLOCKSIZE@
+MCUTIL = @MCUTIL@
+MT = @MT@
+MTX = @MTX@
+MT_FILE_FLAG = @MT_FILE_FLAG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCAT = @PCAT@
+PERL = @PERL@
+PRINT = @PRINT@
+RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
+RESTORE = @RESTORE@
+SAMBA_CLIENT = @SAMBA_CLIENT@
+SERVICE_SUFFIX = @SERVICE_SUFFIX@
+SETUID_GROUP = @SETUID_GROUP@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNAPSHOT_STAMP = @SNAPSHOT_STAMP@
+STRIP = @STRIP@
+USE_VERSION_SUFFIXES = @USE_VERSION_SUFFIXES@
+VDUMP = @VDUMP@
+VERSION = @VERSION@
+VERSION_COMMENT = @VERSION_COMMENT@
+VERSION_MAJOR = @VERSION_MAJOR@
+VERSION_MINOR = @VERSION_MINOR@
+VERSION_PATCH = @VERSION_PATCH@
+VERSION_SUFFIX = @VERSION_SUFFIX@
+VRESTORE = @VRESTORE@
+VXDUMP = @VXDUMP@
+VXRESTORE = @VXRESTORE@
+WANT_AMPLOT_FALSE = @WANT_AMPLOT_FALSE@
+WANT_AMPLOT_TRUE = @WANT_AMPLOT_TRUE@
+WANT_CHG_SCSI_FALSE = @WANT_CHG_SCSI_FALSE@
+WANT_CHG_SCSI_TRUE = @WANT_CHG_SCSI_TRUE@
+WANT_CHIO_SCSI_FALSE = @WANT_CHIO_SCSI_FALSE@
+WANT_CHIO_SCSI_TRUE = @WANT_CHIO_SCSI_TRUE@
+WANT_CLIENT_FALSE = @WANT_CLIENT_FALSE@
+WANT_CLIENT_TRUE = @WANT_CLIENT_TRUE@
+WANT_RECOVER_FALSE = @WANT_RECOVER_FALSE@
+WANT_RECOVER_TRUE = @WANT_RECOVER_TRUE@
+WANT_RESTORE_FALSE = @WANT_RESTORE_FALSE@
+WANT_RESTORE_TRUE = @WANT_RESTORE_TRUE@
+WANT_RUNTIME_PSEUDO_RELOC_FALSE = @WANT_RUNTIME_PSEUDO_RELOC_FALSE@
+WANT_RUNTIME_PSEUDO_RELOC_TRUE = @WANT_RUNTIME_PSEUDO_RELOC_TRUE@
+WANT_SAMBA_FALSE = @WANT_SAMBA_FALSE@
+WANT_SAMBA_TRUE = @WANT_SAMBA_TRUE@
+WANT_SERVER_FALSE = @WANT_SERVER_FALSE@
+WANT_SERVER_TRUE = @WANT_SERVER_TRUE@
+WANT_SETUID_CLIENT_FALSE = @WANT_SETUID_CLIENT_FALSE@
+WANT_SETUID_CLIENT_TRUE = @WANT_SETUID_CLIENT_TRUE@
+WANT_SSH_SECURITY_FALSE = @WANT_SSH_SECURITY_FALSE@
+WANT_SSH_SECURITY_TRUE = @WANT_SSH_SECURITY_TRUE@
+WANT_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+ac_c = @ac_c@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_n = @ac_n@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+INCLUDES = -I$(top_builddir)/common-src \
+               -I$(top_srcdir)/common-src
+
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
+lib_LTLIBRARIES = libamandad.la
+LIB_EXTENSION = la
+@WANT_RUNTIME_PSEUDO_RELOC_TRUE@AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+libamandad_la_SOURCES = amandad_util.c
+libamandad_la_LDFLAGS = -release $(VERSION)
+noinst_HEADERS = amandad.h
+
+###
+# Because libamanda includes routines (e.g. regex) provided by some system
+# libraries, and because of the way libtool sets up the command line, we
+# need to list libamanda twice here, first to override the system library
+# routines, and second to pick up any references in the other libraries.
+###
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamandad.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  amandad-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  amandad-src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           f=$(am__strip_dir) \
+           echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+           $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+         else :; fi; \
+       done
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         p=$(am__strip_dir) \
+         echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+         $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test "$$dir" != "$$p" || dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
+libamandad.la: $(libamandad_la_OBJECTS) $(libamandad_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(libamandad_la_LDFLAGS) $(libamandad_la_OBJECTS) $(libamandad_la_LIBADD) $(LIBS)
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       test -z "$(libexecdir)" || $(mkdir_p) "$(DESTDIR)$(libexecdir)"
+       @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+            || test -f $$p1 \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(libexecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(libexecdir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(libexecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(libexecdir)/$$f" || exit 1; \
+         else :; fi; \
+       done
+
+uninstall-libexecPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+         echo " rm -f '$(DESTDIR)$(libexecdir)/$$f'"; \
+         rm -f "$(DESTDIR)$(libexecdir)/$$f"; \
+       done
+
+clean-libexecPROGRAMS:
+       @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+amandad$(EXEEXT): $(amandad_OBJECTS) $(amandad_DEPENDENCIES) 
+       @rm -f amandad$(EXEEXT)
+       $(LINK) $(amandad_LDFLAGS) $(amandad_OBJECTS) $(amandad_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amandad.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amandad_util.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)"; do \
+         test -z "$$dir" || $(mkdir_p) "$$dir"; \
+       done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libexecPROGRAMS \
+       clean-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-libLTLIBRARIES install-libexecPROGRAMS
+       @$(NORMAL_INSTALL)
+       $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \
+       uninstall-libexecPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libLTLIBRARIES clean-libexecPROGRAMS clean-libtool ctags \
+       distclean distclean-compile distclean-generic \
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-exec-hook \
+       install-info install-info-am install-libLTLIBRARIES \
+       install-libexecPROGRAMS install-man install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags uninstall uninstall-am uninstall-info-am \
+       uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS
+
+
+install-exec-hook:
+       @list="$(libexec_PROGRAMS) $(libexec_SCRIPTS)"; \
+       for p in $$list; do \
+               pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed '$(transform)'`; \
+               echo chown $(BINARY_OWNER) $$pa; \
+               chown $(BINARY_OWNER) $$pa; \
+               echo chgrp $(SETUID_GROUP) $$pa; \
+               chgrp $(SETUID_GROUP) $$pa; \
+       done
+
+lint:
+       @ for p in $(libexec_PROGRAMS); do                                      \
+               f="$$p.c $(libamandad_la_SOURCES)";                             \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               (cd ../server-src; make listlibsrc);                            \
+               f="$$f "`cat ../server-src/listlibsrc.output`;                  \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/amandad-src/amandad.c b/amandad-src/amandad.c
new file mode 100644 (file)
index 0000000..772cd39
--- /dev/null
@@ -0,0 +1,1649 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1999 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+
+/*
+ * $Id: amandad.c,v 1.18 2006/08/21 20:17:09 martinea Exp $
+ *
+ * handle client-host side of Amanda network communications, including
+ * security checks, execution of the proper service, and acking the
+ * master side
+ */
+
+/*#define      AMANDAD_DEBUG*/
+
+#include "amanda.h"
+#include "amandad.h"
+#include "clock.h"
+#include "event.h"
+#include "amfeatures.h"
+#include "packet.h"
+#include "version.h"
+#include "queue.h"
+#include "security.h"
+#include "stream.h"
+#include "util.h"
+
+#define        REP_TIMEOUT     (6*60*60)       /* secs for service to reply */
+#define        ACK_TIMEOUT     10              /* XXX should be configurable */
+#define        MAX_REP_RETRIES 5
+
+/*
+ * These are the actions for entering the state machine
+ */
+typedef enum { A_START, A_RECVPKT, A_RECVREP, A_PENDING, A_FINISH, A_CONTINUE,
+    A_SENDNAK, A_TIMEOUT } action_t;
+
+/*
+ * This is a state in the state machine.  It is a function pointer to
+ * the function that actually implements the state.
+ */
+struct active_service;
+typedef action_t (*state_t)(struct active_service *, action_t, pkt_t *);
+
+/*
+ * This structure describes an active running service.
+ *
+ * An active service is something running that we have received
+ * a request for.  This structure holds info on that service, including
+ * file descriptors for data, etc, as well as the security handle
+ * for communications with the amanda server.
+ */
+struct active_service {
+    char *cmd;                         /* name of command we ran */
+    char *arguments;                   /* arguments we sent it */
+    security_handle_t *security_handle;        /* remote server */
+    state_t state;                     /* how far this has progressed */
+    pid_t pid;                         /* pid of subprocess */
+    int send_partial_reply;            /* send PREP packet */
+    int reqfd;                         /* pipe to write requests */
+    int repfd;                         /* pipe to read replies */
+    event_handle_t *ev_repfd;          /* read event handle for repfd */
+    event_handle_t *ev_reptimeout;     /* timeout for rep data */
+    pkt_t rep_pkt;                     /* rep packet we're sending out */
+    char *repbuf;                      /* buffer to read the rep into */
+    size_t bufsize;                    /* length of repbuf */
+    size_t repbufsize;                 /* length of repbuf */
+    int repretry;                      /* times we'll retry sending the rep */
+    /*
+     * General user streams to the process, and their equivalent
+     * network streams.
+     */
+    struct datafd_handle {
+       int fd_read;                    /* pipe to child process */
+       int fd_write;                   /* pipe to child process */
+       event_handle_t *ev_read;        /* it's read event handle */
+       event_handle_t *ev_write;       /* it's write event handle */
+       security_stream_t *netfd;       /* stream to amanda server */
+       struct active_service *as;      /* pointer back to our enclosure */
+    } data[DATA_FD_COUNT];
+    char databuf[NETWORK_BLOCK_BYTES]; /* buffer to relay netfd data in */
+    TAILQ_ENTRY(active_service) tq;    /* queue handle */
+};
+
+/* 
+ * Here are the services that we allow.
+ */
+static struct services {
+    char *name;
+    int  active;
+} services[] = {
+    { "noop", 1 },
+    { "sendsize", 1 },
+    { "sendbackup", 1 },
+    { "selfcheck", 1 },
+    { "amindexd", 0 },
+    { "amidxtaped", 0 }
+};
+#define        NSERVICES       (int)(sizeof(services) / sizeof(services[0]))
+
+/*
+ * Queue of outstanding requests that we are running.
+ */
+static struct {
+    TAILQ_HEAD(, active_service) tailq;
+    int qlength;
+} serviceq = {
+    TAILQ_HEAD_INITIALIZER(serviceq.tailq), 0
+};
+
+/*
+ * Data for dbmalloc to check for memory leaks
+ */
+#ifdef USE_DBMALLOC
+static struct {
+    struct {
+       unsigned long size, hist;
+    } start, end;
+} dbmalloc_info;
+#endif
+
+static int wait_30s = 1;
+static int exit_on_qlength = 1;
+static char *auth = NULL;
+
+int main(int argc, char **argv);
+
+static int allocstream(struct active_service *, int);
+static void exit_check(void *);
+static void protocol_accept(security_handle_t *, pkt_t *);
+static void state_machine(struct active_service *, action_t, pkt_t *);
+
+static action_t s_sendack(struct active_service *, action_t, pkt_t *);
+static action_t s_repwait(struct active_service *, action_t, pkt_t *);
+static action_t s_processrep(struct active_service *, action_t, pkt_t *);
+static action_t s_sendrep(struct active_service *, action_t, pkt_t *);
+static action_t s_ackwait(struct active_service *, action_t, pkt_t *);
+
+static void repfd_recv(void *);
+static void timeout_repfd(void *);
+static void protocol_recv(void *, pkt_t *, security_status_t);
+static void process_readnetfd(void *);
+static void process_writenetfd(void *, void *, ssize_t);
+static struct active_service *service_new(security_handle_t *,
+    const char *, const char *);
+static void service_delete(struct active_service *);
+static int writebuf(struct active_service *, const void *, size_t);
+static ssize_t do_sendpkt(security_handle_t *handle, pkt_t *pkt);
+
+static void child_signal(int signal);
+
+#ifdef AMANDAD_DEBUG
+static const char *state2str(state_t);
+static const char *action2str(action_t);
+#endif
+
+/*
+ * Harvests defunct processes...
+ */
+
+static void
+child_signal(
+    int                signal)
+{
+    pid_t      rp;
+
+    (void)signal;      /* Quite compiler warning */
+    /*
+     * Reap and child status and promptly ignore since we don't care...
+     */
+    do {
+       rp = waitpid(-1, NULL, WNOHANG);
+    } while (rp > 0);
+}
+
+int
+main(
+    int                argc,
+    char **    argv)
+{
+    int i, j;
+    int have_services;
+    int in, out;
+    const security_driver_t *secdrv;
+    int no_exit = 0;
+    struct sigaction act, oact;
+    char *pgm = "amandad";             /* in case argv[0] is not set */
+#if defined(AMANDAD_DEBUG) && defined(USE_REUSEADDR)
+    const int on = 1;
+    int r;
+#endif
+
+    safe_fd(-1, 0);
+    safe_cd();
+
+    /*
+     * When called via inetd, it is not uncommon to forget to put the
+     * argv[0] value on the config line.  On some systems (e.g. Solaris)
+     * this causes argv and/or argv[0] to be NULL, so we have to be
+     * careful getting our name.
+     */
+    if ((argv == NULL) || (argv[0] == NULL)) {
+           pgm = "amandad";            /* in case argv[0] is not set */
+    } else {
+           pgm = basename(argv[0]);    /* Strip of leading path get debug name */
+    }
+    set_pname(pgm);
+    dbopen(DBG_SUBDIR_AMANDAD);
+
+    if(argv == NULL) {
+       error("argv == NULL\n");
+       /*NOTREACHED*/
+    }
+
+    /* Don't die when child closes pipe */
+    signal(SIGPIPE, SIG_IGN);
+
+    /* Tell me when a child exits or dies... */
+    act.sa_handler = child_signal;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = 0;
+    if(sigaction(SIGCHLD, &act, &oact) != 0) {
+       error("error setting SIGCHLD handler: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+
+#ifdef USE_DBMALLOC
+    dbmalloc_info.start.size = malloc_inuse(&dbmalloc_info.start.hist);
+#endif
+
+    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
+
+#ifdef FORCE_USERID
+    /* we'd rather not run as root */
+    if (geteuid() == 0) {
+       if(client_uid == (uid_t) -1) {
+           error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+           /*NOTREACHED*/
+       }
+       initgroups(CLIENT_LOGIN, client_gid);
+       setgid(client_gid);
+       setegid(client_gid);
+       seteuid(client_uid);
+    }
+#endif /* FORCE_USERID */
+
+    /*
+     * ad-hoc argument parsing
+     *
+     * We accept       -auth=[authentication type]
+     *                 -no-exit
+#ifdef AMANDAD_DEBUG
+     *                 -tcp=[port]
+     *                 -udp=[port]
+#endif
+     * We also add a list of services that amandad can launch
+     */
+    secdrv = NULL;
+    in = 0; out = 1;           /* default to stdin/stdout */
+    have_services = 0;
+    for (i = 1; i < argc; i++) {
+       /*
+        * accept -krb4 as an alias for -auth=krb4 (for compatibility)
+        */
+       if (strcmp(argv[i], "-krb4") == 0) {
+           argv[i] = "-auth=krb4";
+           /* FALLTHROUGH */
+           auth = "krb4";
+       }
+
+       /*
+        * Get a driver for a security type specified after -auth=
+        */
+       else if (strncmp(argv[i], "-auth=", strlen("-auth=")) == 0) {
+           argv[i] += strlen("-auth=");
+           secdrv = security_getdriver(argv[i]);
+           auth = argv[i];
+           if (secdrv == NULL) {
+               error("no driver for security type '%s'\n", argv[i]);
+                /*NOTREACHED*/
+           }
+           continue;
+       }
+
+       /*
+        * If -no-exit is specified, always run even after requests have
+        * been satisfied.
+        */
+       else if (strcmp(argv[i], "-no-exit") == 0) {
+           no_exit = 1;
+           continue;
+       }
+
+#ifdef AMANDAD_DEBUG
+       /*
+        * Allow us to directly bind to a udp port for debugging.
+        * This may only apply to some security types.
+        */
+       else if (strncmp(argv[i], "-udp=", strlen("-udp=")) == 0) {
+           struct sockaddr_in sin;
+
+           argv[i] += strlen("-udp=");
+           in = out = socket(AF_INET, SOCK_DGRAM, 0);
+           if (in < 0) {
+               error("can't create dgram socket: %s\n", strerror(errno));
+               /*NOTREACHED*/
+           }
+#ifdef USE_REUSEADDR
+           r = setsockopt(in, SOL_SOCKET, SO_REUSEADDR,
+               (void *)&on, (socklen_t)sizeof(on));
+           if (r < 0) {
+               dbprintf(("%s: amandad: setsockopt(SO_REUSEADDR) failed: %s\n",
+                         debug_prefix(NULL),
+                         strerror(errno)));
+           }
+#endif
+
+           sin.sin_family = (sa_family_t)AF_INET;
+           sin.sin_addr.s_addr = INADDR_ANY;
+           sin.sin_port = (in_port_t)htons((in_port_t)atoi(argv[i]));
+           if (bind(in, (struct sockaddr *)&sin, (socklen_t)sizeof(sin)) < 0) {
+               error("can't bind to port %d: %s\n", atoi(argv[i]),
+                   strerror(errno));
+               /*NOTREACHED*/
+           }
+       }
+       /*
+        * Ditto for tcp ports.
+        */
+       else if (strncmp(argv[i], "-tcp=", strlen("-tcp=")) == 0) {
+           struct sockaddr_in sin;
+           int sock;
+           socklen_t n;
+
+           argv[i] += strlen("-tcp=");
+           sock = socket(AF_INET, SOCK_STREAM, 0);
+           if (sock < 0) {
+               error("can't create tcp socket: %s\n", strerror(errno));
+               /*NOTREACHED*/
+           }
+           n = 1;
+#ifdef USE_REUSEADDR
+           r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+               (void *)&on, (socklen_t)sizeof(on));
+           if (r < 0) {
+               dbprintf(("%s: amandad: setsockopt(SO_REUSEADDR) failed: %s\n",
+                         debug_prefix(NULL),
+                         strerror(errno)));
+           }
+#endif
+           setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+               (void *)&n, (socklen_t)sizeof(n));
+           sin.sin_family = (sa_family_t)AF_INET;
+           sin.sin_addr.s_addr = INADDR_ANY;
+           sin.sin_port = (in_port_t)htons((in_port_t)atoi(argv[i]));
+           if (bind(sock, (struct sockaddr *)&sin, (socklen_t)sizeof(sin)) < 0) {
+               error("can't bind to port %d: %s\n", atoi(argv[i]),
+                   strerror(errno));
+               /*NOTREACHED*/
+           }
+           listen(sock, 10);
+           n = (socklen_t)sizeof(sin);
+           in = out = accept(sock, (struct sockaddr *)&sin, &n);
+       }
+#endif
+       /*
+        * It must be a service name
+        */
+       else {
+           /* clear all services */
+           if(!have_services) {
+               for (j = 0; j < (int)NSERVICES; j++)
+                   services[j].active = 0;
+           }
+           have_services = 1;
+
+           if(strcmp(argv[i],"amdump") == 0) {
+               services[0].active = 1;
+               services[1].active = 1;
+               services[2].active = 1;
+               services[3].active = 1;
+           }
+           else {
+               for (j = 0; j < (int)NSERVICES; j++)
+                   if (strcmp(services[j].name, argv[i]) == 0)
+                       break;
+               if (j == (int)NSERVICES) {
+                   dbprintf(("%s: %s: invalid service\n",
+                             debug_prefix_time(NULL), argv[i]));
+                   exit(1);
+               }
+               services[j].active = 1;
+           }
+       }
+    }
+
+    /*
+     * If no security type specified, use BSD
+     */
+    if (secdrv == NULL) {
+       secdrv = security_getdriver("BSD");
+       auth = "bsd";
+       if (secdrv == NULL) {
+           error("no driver for default security type 'BSD'\n");
+           /*NOTREACHED*/
+       }
+    }
+
+    if(strcasecmp(auth, "rsh") == 0 ||
+       strcasecmp(auth, "ssh") == 0 ||
+       strcasecmp(auth, "bsdtcp") == 0) {
+       wait_30s = 0;
+       exit_on_qlength = 1;
+    }
+
+    /* initialize */
+
+    startclock();
+
+    dbprintf(("%s: version %s\n", get_pname(), version()));
+    for (i = 0; version_info[i] != NULL; i++) {
+       dbprintf(("%s: %s", debug_prefix(NULL), version_info[i]));
+    }
+
+    if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) {
+       dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n",
+                 debug_prefix(NULL)));
+    }
+
+    /*
+     * Schedule to call protocol_accept() when new security handles
+     * are created on stdin.
+     */
+    security_accept(secdrv, in, out, protocol_accept);
+
+    /*
+     * Schedule an event that will try to exit every 30 seconds if there
+     * are no requests outstanding.
+     */
+    if(wait_30s)
+       (void)event_register((event_id_t)30, EV_TIME, exit_check, &no_exit);
+
+    /*
+     * Call event_loop() with an arg of 0, telling it to block until all
+     * events are completed.
+     */
+    event_loop(0);
+
+    close(in);
+    close(out);
+    dbclose();
+    return(0);
+}
+
+/*
+ * This runs periodically and checks to see if we have any active services
+ * still running.  If we don't, then we quit.
+ */
+static void
+exit_check(
+    void *     cookie)
+{
+    int no_exit;
+
+    assert(cookie != NULL);
+    no_exit = *(int *)cookie;
+
+    /*
+     * If things are still running, then don't exit.
+     */
+    if (serviceq.qlength > 0)
+       return;
+
+    /*
+     * If the caller asked us to never exit, then we're done
+     */
+    if (no_exit)
+       return;
+
+#ifdef USE_DBMALLOC
+    dbmalloc_info.end.size = malloc_inuse(&dbmalloc_info.end.hist);
+
+    if (dbmalloc_info.start.size != dbmalloc_info.end.size) {
+       malloc_list(dbfd(), dbmalloc_info.start.hist,
+           dbmalloc_info.end.hist);
+    }
+#endif
+
+    dbclose();
+    exit(0);
+}
+
+/*
+ * Handles new incoming protocol handles.  This is a callback for
+ * security_accept(), which gets called when new handles are detected.
+ */
+static void
+protocol_accept(
+    security_handle_t *        handle,
+    pkt_t *            pkt)
+{
+    pkt_t pkt_out;
+    struct active_service *as;
+    char *pktbody, *tok, *service, *arguments;
+    char *service_path = NULL;
+    int i;
+
+    pkt_out.body = NULL;
+
+    /*
+     * If handle is NULL, then the connection is closed.
+     */
+    if(handle == NULL) {
+       return;
+    }
+
+    /*
+     * If pkt is NULL, then there was a problem with the new connection.
+     */
+    if (pkt == NULL) {
+       dbprintf(("%s: accept error: %s\n",
+           debug_prefix_time(NULL), security_geterror(handle)));
+       pkt_init(&pkt_out, P_NAK, "ERROR %s\n", security_geterror(handle));
+       do_sendpkt(handle, &pkt_out);
+       amfree(pkt_out.body);
+       security_close(handle);
+       return;
+    }
+
+    dbprintf(("%s: accept recv %s pkt:\n<<<<<\n%s>>>>>\n",
+       debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+
+    /*
+     * If this is not a REQ packet, just forget about it.
+     */
+    if (pkt->type != P_REQ) {
+       dbprintf(("%s: received unexpected %s packet:\n<<<<<\n%s>>>>>\n\n",
+           debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+       security_close(handle);
+       return;
+    }
+
+    pktbody = service = arguments = NULL;
+    as = NULL;
+
+    /*
+     * Parse out the service and arguments
+     */
+
+    pktbody = stralloc(pkt->body);
+
+    tok = strtok(pktbody, " ");
+    if (tok == NULL)
+       goto badreq;
+    if (strcmp(tok, "SERVICE") != 0)
+       goto badreq;
+
+    tok = strtok(NULL, " \n");
+    if (tok == NULL)
+       goto badreq;
+    service = stralloc(tok);
+
+    /* we call everything else 'arguments' */
+    tok = strtok(NULL, "");
+    if (tok == NULL)
+       goto badreq;
+    arguments = stralloc(tok);
+
+    /* see if it's one we allow */
+    for (i = 0; i < (int)NSERVICES; i++)
+       if (services[i].active == 1 && strcmp(services[i].name, service) == 0)
+           break;
+    if (i == (int)NSERVICES) {
+       dbprintf(("%s: %s: invalid service\n",
+           debug_prefix_time(NULL), service));
+       pkt_init(&pkt_out, P_NAK, "ERROR %s: invalid service\n", service);
+       goto send_pkt_out;
+    }
+
+    service_path = vstralloc(libexecdir, "/", service, versionsuffix(), NULL);
+    if (access(service_path, X_OK) < 0) {
+       dbprintf(("%s: can't execute %s: %s\n",
+           debug_prefix_time(NULL), service_path, strerror(errno)));
+           pkt_init(&pkt_out, P_NAK,
+                    "ERROR execute access to \"%s\" denied\n",
+                    service_path);
+       goto send_pkt_out;
+    }
+
+    /* see if its already running */
+    for (as = TAILQ_FIRST(&serviceq.tailq); as != NULL;
+       as = TAILQ_NEXT(as, tq)) {
+           if (strcmp(as->cmd, service_path) == 0 &&
+               strcmp(as->arguments, arguments) == 0) {
+                   dbprintf(("%s: %s %s: already running, acking req\n",
+                       debug_prefix_time(NULL), service, arguments));
+                   pkt_init(&pkt_out, P_ACK, "");
+                   goto send_pkt_out_no_delete;
+           }
+    }
+
+    /*
+     * create a new service instance, and send the arguments down
+     * the request pipe.
+     */
+    dbprintf(("%s: creating new service: %s\n%s\n",
+       debug_prefix_time(NULL), service, arguments));
+    as = service_new(handle, service_path, arguments);
+    if (writebuf(as, arguments, strlen(arguments)) < 0) {
+       const char *errmsg = strerror(errno);
+       dbprintf(("%s: error sending arguments to %s: %s\n",
+           debug_prefix_time(NULL), service, errmsg));
+       pkt_init(&pkt_out, P_NAK, "ERROR error writing arguments to %s: %s\n",
+           service, errmsg);
+       goto send_pkt_out;
+    }
+    aclose(as->reqfd);
+
+    amfree(pktbody);
+    amfree(service);
+    amfree(service_path);
+    amfree(arguments);
+
+    /*
+     * Move to the sendack state, and start up the state
+     * machine.
+     */
+    as->state = s_sendack;
+    state_machine(as, A_START, NULL);
+    return;
+
+badreq:
+    pkt_init(&pkt_out, P_NAK, "ERROR invalid REQ\n");
+    dbprintf(("%s: received invalid %s packet:\n<<<<<\n%s>>>>>\n\n",
+       debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+
+send_pkt_out:
+    if(as)
+       service_delete(as);
+send_pkt_out_no_delete:
+    amfree(pktbody);
+    amfree(service_path);
+    amfree(service);
+    amfree(arguments);
+    do_sendpkt(handle, &pkt_out);
+    security_close(handle);
+    amfree(pkt_out.body);
+}
+
+/*
+ * Handles incoming protocol packets.  Routes responses to the proper
+ * running service.
+ */
+static void
+state_machine(
+    struct active_service *    as,
+    action_t                   action,
+    pkt_t *                    pkt)
+{
+    action_t retaction;
+    state_t curstate;
+    pkt_t nak;
+
+#ifdef AMANDAD_DEBUG
+    dbprintf(("%s: state_machine: %p entering\n",
+       debug_prefix_time(NULL), as));
+#endif
+    for (;;) {
+       curstate = as->state;
+#ifdef AMANDAD_DEBUG
+       dbprintf(("%s: state_machine: %p curstate=%s action=%s\n",
+           debug_prefix_time(NULL), as,
+           state2str(curstate), action2str(action)));
+#endif
+       retaction = (*curstate)(as, action, pkt);
+#ifdef AMANDAD_DEBUG
+       dbprintf(("%s: state_machine: %p curstate=%s returned %s (nextstate=%s)\n",
+           debug_prefix_time(NULL),
+           as, state2str(curstate), action2str(retaction),
+           state2str(as->state)));
+#endif
+
+       switch (retaction) {
+       /*
+        * State has queued up and is now blocking on input.
+        */
+       case A_PENDING:
+#ifdef AMANDAD_DEBUG
+           dbprintf(("%s: state_machine: %p leaving (A_PENDING)\n",
+               debug_prefix_time(NULL), as));
+#endif
+           return;
+
+       /*
+        * service has switched states.  Loop.
+        */
+       case A_CONTINUE:
+           break;
+
+       /*
+        * state has determined that the packet it received was bogus.
+        * Send a nak, and return.
+        */
+       case A_SENDNAK:
+           dbprintf(("%s: received unexpected %s packet\n",
+               debug_prefix_time(NULL), pkt_type2str(pkt->type)));
+           dbprintf(("<<<<<\n%s----\n\n", pkt->body));
+           pkt_init(&nak, P_NAK, "ERROR unexpected packet type %s\n",
+               pkt_type2str(pkt->type));
+           do_sendpkt(as->security_handle, &nak);
+           amfree(nak.body);
+#ifdef AMANDAD_DEBUG
+           dbprintf(("%s: state_machine: %p leaving (A_SENDNAK)\n",
+               debug_prefix_time(NULL), as));
+#endif
+           return;
+
+       /*
+        * Service is done.  Remove it and finish.
+        */
+       case A_FINISH:
+           service_delete(as);
+#ifdef AMANDAD_DEBUG
+           dbprintf(("%s: state_machine: %p leaving (A_FINISH)\n",
+               debug_prefix_time(NULL), as));
+#endif
+           return;
+
+       default:
+           assert(0);
+           break;
+       }
+    }
+    /*NOTREACHED*/
+}
+
+/*
+ * This state just sends an ack.  After that, we move to the repwait
+ * state to wait for REP data to arrive from the subprocess.
+ */
+static action_t
+s_sendack(
+    struct active_service *    as,
+    action_t                   action,
+    pkt_t *                    pkt)
+{
+    pkt_t ack;
+
+    (void)action;      /* Quiet unused parameter warning */
+    (void)pkt;         /* Quiet unused parameter warning */
+
+    pkt_init(&ack, P_ACK, "");
+    if (do_sendpkt(as->security_handle, &ack) < 0) {
+       dbprintf(("%s: error sending ACK: %s\n",
+           debug_prefix_time(NULL), security_geterror(as->security_handle)));
+       amfree(ack.body);
+       return (A_FINISH);
+    }
+    amfree(ack.body);
+
+    /*
+     * move to the repwait state
+     * Setup a listener for data on the reply fd, but also
+     * listen for packets over the wire, as the server may
+     * poll us if we take a long time.
+     * Setup a timeout that will fire if it takes too long to
+     * receive rep data.
+     */
+    as->state = s_repwait;
+    as->ev_repfd = event_register((event_id_t)as->repfd, EV_READFD, repfd_recv, as);
+    as->ev_reptimeout = event_register(REP_TIMEOUT, EV_TIME,
+       timeout_repfd, as);
+    security_recvpkt(as->security_handle, protocol_recv, as, -1);
+    return (A_PENDING);
+}
+
+/*
+ * This is the repwait state.  We have responded to the initial REQ with
+ * an ACK, and we are now waiting for the process we spawned to pass us 
+ * data to send in a REP.
+ */
+static action_t
+s_repwait(
+    struct active_service *    as,
+    action_t                   action,
+    pkt_t *                    pkt)
+{
+    ssize_t n;
+    char *repbuf_temp;
+
+    /*
+     * We normally shouldn't receive any packets while waiting
+     * for our REP data, but in some cases we do.
+     */
+    if (action == A_RECVPKT) {
+       assert(pkt != NULL);
+       /*
+        * Another req for something that's running.  Just send an ACK
+        * and go back and wait for more data.
+        */
+       if (pkt->type == P_REQ) {
+           dbprintf(("%s: received dup P_REQ packet, ACKing it\n",
+               debug_prefix_time(NULL)));
+           amfree(as->rep_pkt.body);
+           pkt_init(&as->rep_pkt, P_ACK, "");
+           do_sendpkt(as->security_handle, &as->rep_pkt);
+           return (A_PENDING);
+       }
+       /* something unexpected.  Nak it */
+       return (A_SENDNAK);
+    }
+
+    if (action == A_TIMEOUT) {
+       amfree(as->rep_pkt.body);
+       pkt_init(&as->rep_pkt, P_NAK, "ERROR timeout on reply pipe\n");
+       dbprintf(("%s: %s timed out waiting for REP data\n",
+           debug_prefix_time(NULL), as->cmd));
+       do_sendpkt(as->security_handle, &as->rep_pkt);
+       return (A_FINISH);
+    }
+
+    assert(action == A_RECVREP);
+    if(as->bufsize == 0) {
+       as->bufsize = NETWORK_BLOCK_BYTES;
+       as->repbuf = alloc(as->bufsize);
+    }
+
+    do {
+       n = read(as->repfd, as->repbuf + as->repbufsize,
+                as->bufsize - as->repbufsize - 1);
+    } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
+    if (n < 0) {
+       const char *errstr = strerror(errno);
+       dbprintf(("%s: read error on reply pipe: %s\n",
+                 debug_prefix_time(NULL), errstr));
+       amfree(as->rep_pkt.body);
+       pkt_init(&as->rep_pkt, P_NAK, "ERROR read error on reply pipe: %s\n",
+                errstr);
+       do_sendpkt(as->security_handle, &as->rep_pkt);
+       return (A_FINISH);
+    }
+    /*
+     * If we got some data, go back and wait for more, or EOF.  Nul terminate
+     * the buffer first.
+     */
+    as->repbuf[n + as->repbufsize] = '\0';
+    if (n > 0) {
+       as->repbufsize += n;
+       if(as->repbufsize >= (as->bufsize - 1)) {
+           as->bufsize *= 2;
+           repbuf_temp = alloc(as->bufsize);
+           memcpy(repbuf_temp, as->repbuf, as->repbufsize + 1);
+           amfree(as->repbuf);
+           as->repbuf = repbuf_temp;
+       }
+       else if(as->send_partial_reply) {
+           amfree(as->rep_pkt.body);
+           pkt_init(&as->rep_pkt, P_PREP, "%s", as->repbuf);
+           do_sendpkt(as->security_handle, &as->rep_pkt);
+           amfree(as->rep_pkt.body);
+           pkt_init(&as->rep_pkt, P_REP, "");
+       }
+       return (A_PENDING);
+    }
+
+    /*
+     * If we got 0, then we hit EOF.  Process the data and release
+     * the timeout.
+     */
+    assert(n == 0);
+
+    assert(as->ev_repfd != NULL);
+    event_release(as->ev_repfd);
+    as->ev_repfd = NULL;
+
+    assert(as->ev_reptimeout != NULL);
+    event_release(as->ev_reptimeout);
+    as->ev_reptimeout = NULL;
+
+    as->state = s_processrep;
+    aclose(as->repfd);
+    return (A_CONTINUE);
+}
+
+/*
+ * After we have read in all of the rep data, we process it and send
+ * it out as a REP packet.
+ */
+static action_t
+s_processrep(
+    struct active_service *    as,
+    action_t                   action,
+    pkt_t *                    pkt)
+{
+    char *tok, *repbuf;
+
+    (void)action;      /* Quiet unused parameter warning */
+    (void)pkt;         /* Quiet unused parameter warning */
+
+    /*
+     * Copy the rep lines into the outgoing packet.
+     *
+     * If this line is a CONNECT, translate it
+     * Format is "CONNECT <tag> <handle> <tag> <handle> etc...
+     * Example:
+     *
+     *  CONNECT DATA 4 MESG 5 INDEX 6
+     *
+     * The tags are arbitrary.  The handles are in the DATA_FD pool.
+     * We need to map these to security streams and pass them back
+     * to the amanda server.  If the handle is -1, then we don't map.
+     */
+    repbuf = stralloc(as->repbuf);
+    amfree(as->rep_pkt.body);
+    pkt_init(&as->rep_pkt, P_REP, "");
+    tok = strtok(repbuf, " ");
+    if (tok == NULL)
+       goto error;
+    if (strcmp(tok, "CONNECT") == 0) {
+       char *line, *nextbuf;
+
+       /* Save the entire line */
+       line = strtok(NULL, "\n");
+       /* Save the buf following the line */
+       nextbuf = strtok(NULL, "");
+
+       if (line == NULL || nextbuf == NULL)
+           goto error;
+
+       pkt_cat(&as->rep_pkt, "CONNECT");
+
+       /* loop over the id/handle pairs */
+       for (;;) {
+           /* id */
+           tok = strtok(line, " ");
+           line = NULL;        /* keep working from line */
+           if (tok == NULL)
+               break;
+           pkt_cat(&as->rep_pkt, " %s", tok);
+
+           /* handle */
+           tok = strtok(NULL, " \n");
+           if (tok == NULL)
+               goto error;
+           /* convert the handle into something the server can process */
+           pkt_cat(&as->rep_pkt, " %d", allocstream(as, atoi(tok)));
+       }
+       pkt_cat(&as->rep_pkt, "\n%s", nextbuf);
+    } else {
+error:
+       pkt_cat(&as->rep_pkt, "%s", as->repbuf);
+    }
+
+    /*
+     * We've setup our REP packet in as->rep_pkt.  Now move to the transmission
+     * state.
+     */
+    as->state = s_sendrep;
+    as->repretry = MAX_REP_RETRIES;
+    amfree(repbuf);
+    return (A_CONTINUE);
+}
+
+/*
+ * This is the state where we send the REP we just collected from our child.
+ */
+static action_t
+s_sendrep(
+    struct active_service *    as,
+    action_t                   action,
+    pkt_t *                    pkt)
+{
+    (void)action;      /* Quiet unused parameter warning */
+    (void)pkt;         /* Quiet unused parameter warning */
+
+    /*
+     * Transmit it and move to the ack state.
+     */
+    do_sendpkt(as->security_handle, &as->rep_pkt);
+    security_recvpkt(as->security_handle, protocol_recv, as, ACK_TIMEOUT);
+    as->state = s_ackwait;
+    return (A_PENDING);
+}
+
+/*
+ * This is the state in which we wait for the server to ACK the REP
+ * we just sent it.
+ */
+static action_t
+s_ackwait(
+    struct active_service *    as,
+    action_t                   action,
+    pkt_t *                    pkt)
+{
+    struct datafd_handle *dh;
+    int npipes;
+
+    /*
+     * If we got a timeout, try again, but eventually give up.
+     */
+    if (action == A_TIMEOUT) {
+       if (--as->repretry > 0) {
+           as->state = s_sendrep;
+           return (A_CONTINUE);
+       }
+       dbprintf(("%s: timeout waiting for ACK for our REP\n",
+           debug_prefix_time(NULL)));
+       return (A_FINISH);
+    }
+#ifdef AMANDAD_DEBUG
+    dbprintf(("%s: received ACK, now opening streams\n",
+       debug_prefix_time(NULL)));
+#endif
+
+    assert(action == A_RECVPKT);
+
+    if (pkt->type == P_REQ) {
+       dbprintf(("%s: received dup P_REQ packet, resending REP\n",
+                 debug_prefix_time(NULL)));
+       as->state = s_sendrep;
+       return (A_CONTINUE);
+    }
+
+    if (pkt->type != P_ACK)
+       return (A_SENDNAK);
+
+    /*
+     * Got the ack, now open the pipes
+     */
+    for (dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
+       if (dh->netfd == NULL)
+           continue;
+       if (security_stream_accept(dh->netfd) < 0) {
+           dbprintf(("%s: stream %d accept failed: %s\n",
+               debug_prefix_time(NULL),
+               dh - &as->data[0], security_geterror(as->security_handle)));
+           security_stream_close(dh->netfd);
+           dh->netfd = NULL;
+       }
+       /* setup an event for reads from it */
+       dh->ev_read = event_register((event_id_t)dh->fd_read, EV_READFD,
+                                    process_readnetfd, dh);
+
+       security_stream_read(dh->netfd, process_writenetfd, dh);
+
+    }
+
+    /*
+     * Pipes are open, so auth them.  Count them at the same time.
+     */
+    for (npipes = 0, dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
+       if (dh->netfd == NULL)
+           continue;
+       if (security_stream_auth(dh->netfd) < 0) {
+           security_stream_close(dh->netfd);
+           dh->netfd = NULL;
+           event_release(dh->ev_read);
+           event_release(dh->ev_write);
+           dh->ev_read = NULL;
+           dh->ev_write = NULL;
+       } else {
+           npipes++;
+       }
+    }
+
+    /*
+     * If no pipes are open, then we're done.  Otherwise, just start running.
+     * The event handlers on all of the pipes will take it from here.
+     */
+#ifdef AMANDAD_DEBUG
+    dbprintf(("%s: at end of s_ackwait, npipes is %d\n",
+       debug_prefix_time(NULL), npipes));
+#endif
+    if (npipes == 0)
+       return (A_FINISH);
+    else {
+       security_close(as->security_handle);
+       as->security_handle = NULL;
+       return (A_PENDING);
+    }
+}
+
+/*
+ * Called when a repfd has received data
+ */
+static void
+repfd_recv(
+    void *     cookie)
+{
+    struct active_service *as = cookie;
+
+    assert(as != NULL);
+    assert(as->ev_repfd != NULL);
+
+    state_machine(as, A_RECVREP, NULL);
+}
+
+/*
+ * Called when a repfd has timed out
+ */
+static void
+timeout_repfd(
+    void *     cookie)
+{
+    struct active_service *as = cookie;
+
+    assert(as != NULL);
+    assert(as->ev_reptimeout != NULL);
+
+    state_machine(as, A_TIMEOUT, NULL);
+}
+
+/*
+ * Called when a handle has received data
+ */
+static void
+protocol_recv(
+    void *             cookie,
+    pkt_t *            pkt,
+    security_status_t  status)
+{
+    struct active_service *as = cookie;
+
+    assert(as != NULL);
+
+    switch (status) {
+    case S_OK:
+       dbprintf(("%s: received %s pkt:\n<<<<<\n%s>>>>>\n",
+           debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+       state_machine(as, A_RECVPKT, pkt);
+       break;
+    case S_TIMEOUT:
+       dbprintf(("%s: timeout\n", debug_prefix_time(NULL)));
+       state_machine(as, A_TIMEOUT, NULL);
+       break;
+    case S_ERROR:
+       dbprintf(("%s: receive error: %s\n",
+           debug_prefix_time(NULL), security_geterror(as->security_handle)));
+       break;
+    }
+}
+
+/*
+ * This is a generic relay function that just reads data from one of
+ * the process's pipes and passes it up the equivalent security_stream_t
+ */
+static void
+process_readnetfd(
+    void *     cookie)
+{
+    pkt_t nak;
+    struct datafd_handle *dh = cookie;
+    struct active_service *as = dh->as;
+    ssize_t n;
+
+    nak.body = NULL;
+
+    do {
+       n = read(dh->fd_read, as->databuf, SIZEOF(as->databuf));
+    } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
+
+    /*
+     * Process has died.
+     */
+    if (n < 0) {
+       pkt_init(&nak, P_NAK, "A ERROR data descriptor %d broken: %s\n",
+           dh->fd_read, strerror(errno));
+       goto sendnak;
+    }
+    /*
+     * Process has closed the pipe.  Just remove this event handler.
+     * If all pipes are closed, shut down this service.
+     */
+    if (n == 0) {
+       event_release(dh->ev_read);
+       dh->ev_read = NULL;
+       if(dh->ev_write == NULL) {
+           security_stream_close(dh->netfd);
+           dh->netfd = NULL;
+       }
+       for (dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
+           if (dh->netfd != NULL)
+               return;
+       }
+       service_delete(as);
+       return;
+    }
+    if (security_stream_write(dh->netfd, as->databuf, (size_t)n) < 0) {
+       /* stream has croaked */
+       pkt_init(&nak, P_NAK, "ERROR write error on stream %d: %s\n",
+           security_stream_id(dh->netfd),
+           security_stream_geterror(dh->netfd));
+       goto sendnak;
+    }
+    return;
+
+sendnak:
+    do_sendpkt(as->security_handle, &nak);
+    service_delete(as);
+    amfree(nak.body);
+}
+
+/*
+ * This is a generic relay function that just read data from one of
+ * the security_stream_t and passes it up the equivalent process's pipes
+ */
+static void
+process_writenetfd(
+    void *     cookie,
+    void *     buf,
+    ssize_t    size)
+{
+    struct datafd_handle *dh;
+
+    assert(cookie != NULL);
+    dh = cookie;
+
+    if (dh->fd_write <= 0) {
+       dbprintf(("%s: process_writenetfd: dh->fd_write <= 0\n",
+           debug_prefix_time(NULL)));
+    } else if (size > 0) {
+       fullwrite(dh->fd_write, buf, (size_t)size);
+       security_stream_read(dh->netfd, process_writenetfd, dh);
+    }
+    else {
+       aclose(dh->fd_write);
+    }
+}
+
+
+/*
+ * Convert a local stream handle (DATA_FD...) into something that
+ * can be sent to the amanda server.
+ *
+ * Returns a number that should be sent to the server in the REP packet.
+ */
+static int
+allocstream(
+    struct active_service *    as,
+    int                                handle)
+{
+    struct datafd_handle *dh;
+
+    /* if the handle is -1, then we don't bother */
+    if (handle < 0)
+       return (-1);
+
+    /* make sure the handle's kosher */
+    if (handle < DATA_FD_OFFSET || handle >= DATA_FD_OFFSET + DATA_FD_COUNT)
+       return (-1);
+
+    /* get a pointer into our handle array */
+    dh = &as->data[handle - DATA_FD_OFFSET];
+
+    /* make sure we're not already using the net handle */
+    if (dh->netfd != NULL)
+       return (-1);
+
+    /* allocate a stream from the security layer and return */
+    dh->netfd = security_stream_server(as->security_handle);
+    if (dh->netfd == NULL) {
+       dbprintf(("%s: couldn't open stream to server: %s\n",
+           debug_prefix_time(NULL), security_geterror(as->security_handle)));
+       return (-1);
+    }
+
+    /*
+     * convert the stream into a numeric id that can be sent to the
+     * remote end.
+     */
+    return (security_stream_id(dh->netfd));
+}
+
+/*
+ * Create a new service instance
+ */
+static struct active_service *
+service_new(
+    security_handle_t *        security_handle,
+    const char *       cmd,
+    const char *       arguments)
+{
+    int i;
+    int data_read[DATA_FD_COUNT + 1][2];
+    int data_write[DATA_FD_COUNT + 1][2];
+    struct active_service *as;
+    pid_t pid;
+    int newfd;
+
+    assert(security_handle != NULL);
+    assert(cmd != NULL);
+    assert(arguments != NULL);
+
+    /* a plethora of pipes */
+    for (i = 0; i < DATA_FD_COUNT + 1; i++) {
+       if (pipe(data_read[i]) < 0) {
+           error("pipe: %s\n", strerror(errno));
+           /*NOTREACHED*/
+       }
+       if (pipe(data_write[i]) < 0) {
+           error("pipe: %s\n", strerror(errno));
+           /*NOTREACHED*/
+       }
+    }
+
+    switch(pid = fork()) {
+    case -1:
+       error("could not fork service %s: %s\n", cmd, strerror(errno));
+       /*NOTREACHED*/
+    default:
+       /*
+        * The parent.  Close the far ends of our pipes and return.
+        */
+       as = alloc(SIZEOF(*as));
+       as->cmd = stralloc(cmd);
+       as->arguments = stralloc(arguments);
+       as->security_handle = security_handle;
+       as->state = NULL;
+       as->pid = pid;
+       as->send_partial_reply = 0;
+       if(strcmp(cmd+(strlen(cmd)-8), "sendsize") == 0) {
+           g_option_t *g_options;
+           char *option_str, *p;
+
+           option_str = stralloc(as->arguments+8);
+           p = strchr(option_str,'\n');
+           if(p) *p = '\0';
+
+           g_options = parse_g_options(option_str, 1);
+           if(am_has_feature(g_options->features, fe_partial_estimate)) {
+               as->send_partial_reply = 1;
+           }
+           free_g_options(g_options);
+           amfree(option_str);
+       }
+
+       /* write to the request pipe */
+       aclose(data_read[0][0]);
+       as->reqfd = data_read[0][1];
+
+       /*
+        * read from the reply pipe
+        */
+       as->repfd = data_write[0][0];
+       aclose(data_write[0][1]);
+       as->ev_repfd = NULL;
+       as->repbuf = NULL;
+       as->repbufsize = 0;
+       as->bufsize = 0;
+       as->repretry = 0;
+       as->rep_pkt.body = NULL;
+
+       /*
+        * read from the rest of the general-use pipes
+        * (netfds are opened as the client requests them)
+        */
+       for (i = 0; i < DATA_FD_COUNT; i++) {
+           aclose(data_read[i + 1][1]);
+           aclose(data_write[i + 1][0]);
+           as->data[i].fd_read = data_read[i + 1][0];
+           as->data[i].fd_write = data_write[i + 1][1];
+           as->data[i].ev_read = NULL;
+           as->data[i].ev_write = NULL;
+           as->data[i].netfd = NULL;
+           as->data[i].as = as;
+       }
+
+       /* add it to the service queue */
+       /* increment the active service count */
+       TAILQ_INSERT_TAIL(&serviceq.tailq, as, tq);
+       serviceq.qlength++;
+
+       return (as);
+    case 0:
+       /*
+        * The child.  Put our pipes in their advertised locations
+        * and start up.
+        */
+#ifdef FORCE_USERID
+       seteuid((uid_t)0);
+       setuid(client_uid);
+#endif
+
+       /*
+        * The data stream is stdin in the new process
+        */
+        if (dup2(data_read[0][0], 0) < 0) {
+           error("dup %d to %d failed: %s\n", data_read[0][0], 0,
+               strerror(errno));
+           /*NOTREACHED*/
+       }
+       aclose(data_read[0][0]);
+       aclose(data_read[0][1]);
+
+       /*
+        * The reply stream is stdout
+        */
+        if (dup2(data_write[0][1], 1) < 0) {
+           error("dup %d to %d failed: %s\n", data_write[0][1], 1,
+               strerror(errno));
+       }
+        aclose(data_write[0][0]);
+        aclose(data_write[0][1]);
+
+       /*
+        *  Make sure they are not open in the range DATA_FD_OFFSET to
+        *      DATA_FD_OFFSET + DATA_FD_COUNT*2 - 1
+        */
+       for (i = 0; i < DATA_FD_COUNT; i++) {
+           while(data_read[i + 1][1] >= DATA_FD_OFFSET &&
+                 data_read[i + 1][1] <= DATA_FD_OFFSET + DATA_FD_COUNT*2 - 1) {
+               newfd = dup(data_read[i + 1][1]);
+               if(newfd == -1)
+                   error("Can't dup out off DATA_FD range");
+               data_read[i + 1][1] = newfd;
+           }
+           while(data_write[i + 1][0] >= DATA_FD_OFFSET &&
+                 data_write[i + 1][0] <= DATA_FD_OFFSET + DATA_FD_COUNT*2 - 1) {
+               newfd = dup(data_write[i + 1][0]);
+               if(newfd == -1)
+                   error("Can't dup out off DATA_FD range");
+               data_write[i + 1][0] = newfd;
+           }
+       }
+       for (i = 0; i < DATA_FD_COUNT; i++)
+           close(DATA_FD_OFFSET + i);
+
+       /*
+        * The rest start at the offset defined in amandad.h, and continue
+        * through the internal defined.
+        */
+       for (i = 0; i < DATA_FD_COUNT; i++) {
+           if (dup2(data_read[i + 1][1], i*2 + DATA_FD_OFFSET) < 0) {
+               error("dup %d to %d failed: %s\n", data_read[i + 1][1],
+                   i + DATA_FD_OFFSET, strerror(errno));
+           }
+           aclose(data_read[i + 1][0]);
+           aclose(data_read[i + 1][1]);
+
+           if (dup2(data_write[i + 1][0], i*2 + 1 + DATA_FD_OFFSET) < 0) {
+               error("dup %d to %d failed: %s\n", data_write[i + 1][0],
+                   i + DATA_FD_OFFSET, strerror(errno));
+           }
+           aclose(data_write[i + 1][0]);
+           aclose(data_write[i + 1][1]);
+       }
+
+       /* close all unneeded fd */
+       safe_fd(DATA_FD_OFFSET, DATA_FD_COUNT*2);
+       close(2);
+
+       execle(cmd, cmd, "amandad", auth, (char *)NULL, safe_env());
+       error("could not exec service %s: %s\n", cmd, strerror(errno));
+       /*NOTREACHED*/
+    }
+    return NULL;
+}
+
+/*
+ * Unallocate a service instance
+ */
+static void
+service_delete(
+    struct active_service *    as)
+{
+    int i;
+    struct datafd_handle *dh;
+
+#ifdef AMANDAD_DEBUG
+       dbprintf(("%s: closing service: %s\n",
+           debug_prefix_time(NULL), (as->cmd)?as->cmd:"??UNKONWN??"));
+#endif
+
+    assert(as != NULL);
+
+    assert(as->cmd != NULL);
+    amfree(as->cmd);
+
+    assert(as->arguments != NULL);
+    amfree(as->arguments);
+
+    if (as->reqfd != -1)
+       aclose(as->reqfd);
+    if (as->repfd != -1)
+       aclose(as->repfd);
+
+    if (as->ev_repfd != NULL)
+       event_release(as->ev_repfd);
+    if (as->ev_reptimeout != NULL)
+       event_release(as->ev_reptimeout);
+
+    for (i = 0; i < DATA_FD_COUNT; i++) {
+       dh = &as->data[i];
+
+       aclose(dh->fd_read);
+       aclose(dh->fd_write);
+
+       if (dh->netfd != NULL)
+           security_stream_close(dh->netfd);
+
+       if (dh->ev_read != NULL)
+           event_release(dh->ev_read);
+       if (dh->ev_write != NULL)
+           event_release(dh->ev_write);
+    }
+
+    if (as->security_handle != NULL)
+       security_close(as->security_handle);
+
+    assert(as->pid > 0);
+    kill(as->pid, SIGTERM);
+    waitpid(as->pid, NULL, WNOHANG);
+
+    TAILQ_REMOVE(&serviceq.tailq, as, tq);
+    assert(serviceq.qlength > 0);
+    serviceq.qlength--;
+
+    amfree(as->cmd);
+    amfree(as->arguments);
+    amfree(as->repbuf);
+    amfree(as->rep_pkt.body);
+    amfree(as);
+
+    if(exit_on_qlength == 0 && serviceq.qlength == 0) {
+       dbclose();
+       exit(0);
+    }
+}
+
+/*
+ * Like 'fullwrite', but does the work in a child process so pipelines
+ * do not hang.
+ */
+static int
+writebuf(
+    struct active_service *    as,
+    const void *               bufp,
+    size_t                     size)
+{
+    pid_t pid;
+    ssize_t    writesize;
+
+    switch (pid=fork()) {
+    case -1:
+       break;
+
+    default:
+       waitpid(pid, NULL, WNOHANG);
+       return 0;                       /* this is the parent */
+
+    case 0:                            /* this is the child */
+       close(as->repfd);
+       writesize = fullwrite(as->reqfd, bufp, size);
+       exit(writesize != (ssize_t)size);
+       /* NOTREACHED */
+    }
+    return -1;
+}
+
+static ssize_t
+do_sendpkt(
+    security_handle_t *        handle,
+    pkt_t *            pkt)
+{
+    dbprintf(("%s: sending %s pkt:\n<<<<<\n%s>>>>>\n",
+       debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+    return security_sendpkt(handle, pkt);
+}
+
+#ifdef AMANDAD_DEBUG
+/*
+ * Convert a state into a string
+ */
+static const char *
+state2str(
+    state_t    state)
+{
+    static const struct {
+       state_t state;
+       const char str[13];
+    } states[] = {
+#define        X(state)        { state, stringize(state) }
+       X(s_sendack),
+       X(s_repwait),
+       X(s_processrep),
+       X(s_sendrep),
+       X(s_ackwait),
+#undef X
+    };
+    int i;
+
+    for (i = 0; i < (int)(sizeof(states) / sizeof(states[0])); i++)
+       if (state == states[i].state)
+           return (states[i].str);
+    return ("INVALID STATE");
+}
+
+/*
+ * Convert an action into a string
+ */
+static const char *
+action2str(
+    action_t   action)
+{
+    static const struct {
+       action_t action;
+       const char str[12];
+    } actions[] = {
+#define        X(action)       { action, stringize(action) }
+       X(A_START),
+       X(A_RECVPKT),
+       X(A_RECVREP),
+       X(A_PENDING),
+       X(A_FINISH),
+       X(A_CONTINUE),
+       X(A_SENDNAK),
+       X(A_TIMEOUT),
+#undef X
+    };
+    int i;
+
+    for (i = 0; i < (int)(sizeof(actions) / sizeof(actions[0])); i++)
+       if (action == actions[i].action)
+           return (actions[i].str);
+    return ("UNKNOWN ACTION");
+}
+#endif /* AMANDAD_DEBUG */
diff --git a/amandad-src/amandad.h b/amandad-src/amandad.h
new file mode 100644 (file)
index 0000000..471f73c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/* 
+ * $Id: amandad.h,v 1.5 2006/07/19 17:46:07 martinea Exp $
+ *
+ */
+
+#ifndef AMANDAD_UTIL_H
+#define AMANDAD_UTIL_H
+
+#include "amanda.h"
+#include "amfeatures.h"
+#include "sl.h"
+#include "util.h"              /* for bstrncmp() */
+
+#define DATA_FD_COUNT   3               /* number of general-use pipes */
+#define DATA_FD_OFFSET  50  
+
+typedef struct g_option_s {
+    char *str;
+    am_feature_t *features;
+    char *hostname;
+    char *auth;
+    int maxdumps;
+    char *config;
+} g_option_t;
+
+
+void init_g_options(g_option_t *g_options);
+g_option_t *parse_g_options(char *str, int verbose);
+void free_g_options(g_option_t *);
+
+#endif
diff --git a/amandad-src/amandad_util.c b/amandad-src/amandad_util.c
new file mode 100644 (file)
index 0000000..aef2852
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/* 
+ * $Id: amandad_util.c,v 1.5 2006/07/19 17:46:07 martinea Exp $
+ *
+ */
+
+#include "amandad.h"
+#include "util.h"
+
+#define MAXMAXDUMPS 16
+
+void
+init_g_options(
+    g_option_t *       g_options)
+{
+    g_options->str      = NULL;
+    g_options->features = NULL;
+    g_options->hostname = NULL;
+    g_options->auth     = NULL;
+    g_options->maxdumps = 0;
+    g_options->config   = NULL;
+}
+
+
+g_option_t *
+parse_g_options(
+    char *     str,
+    int                verbose)
+{
+    g_option_t *g_options;
+    char *p, *tok;
+    int new_maxdumps;
+
+    g_options = alloc(sizeof(g_option_t));
+    init_g_options(g_options);
+    g_options->str = stralloc(str);
+
+    p = stralloc(str);
+    tok = strtok(p,";");
+
+    while (tok != NULL) {
+       if(strncmp(tok,"features=", 9) == 0) {
+           if(g_options->features != NULL) {
+               dbprintf(("%s: multiple features option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple features option]\n");
+               }
+           }
+           if((g_options->features = am_string_to_feature(tok+9)) == NULL) {
+               dbprintf(("%s: bad features value \"%s\n",
+                         debug_prefix(NULL), tok+10));
+               if(verbose) {
+                   printf("ERROR [bad features value \"%s\"]\n", tok+10);
+               }
+           }
+       }
+       else if(strncmp(tok,"hostname=", 9) == 0) {
+           if(g_options->hostname != NULL) {
+               dbprintf(("%s: multiple hostname option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple hostname option]\n");
+               }
+           }
+           g_options->hostname = stralloc(tok+9);
+       }
+       else if(strncmp(tok,"auth=", 5) == 0) {
+           if(g_options->auth != NULL) {
+               dbprintf(("%s: multiple auth option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple auth option]\n");
+               }
+           }
+           g_options->auth = stralloc(tok+5);
+       }
+       else if(strncmp(tok,"maxdumps=", 9) == 0) {
+           if(g_options->maxdumps != 0) {
+               dbprintf(("%s: multiple maxdumps option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple maxdumps option]\n");
+               }
+           }
+           if(sscanf(tok+9, "%d;", &new_maxdumps) == 1) {
+               if (new_maxdumps > MAXMAXDUMPS) {
+                   g_options->maxdumps = MAXMAXDUMPS;
+               }
+               else if (new_maxdumps > 0) {
+                   g_options->maxdumps = new_maxdumps;
+               }
+               else {
+                   dbprintf(("%s: bad maxdumps value \"%s\"\n",
+                             debug_prefix(NULL), tok+9));
+                   if(verbose) {
+                       printf("ERROR [bad maxdumps value \"%s\"]\n",
+                              tok+9);
+                   }
+               }
+           }
+           else {
+               dbprintf(("%s: bad maxdumps value \"%s\"\n",
+                         debug_prefix(NULL), tok+9));
+               if(verbose) {
+                   printf("ERROR [bad maxdumps value \"%s\"]\n",
+                          tok+9);
+               }
+           }
+       }
+       else if(strncmp(tok,"config=", 7) == 0) {
+           if(g_options->config != NULL) {
+               dbprintf(("%s: multiple config option\n",
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple config option]\n");
+               }
+           }
+           g_options->config = stralloc(tok+7);
+           if (strchr(g_options->config, '/')) {
+               amfree(g_options->config);
+               dbprintf(("%s: invalid character in config option\n",
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [invalid character in config option]\n");
+               }
+           }
+       }
+       else {
+           dbprintf(("%s: unknown option \"%s\"\n",
+                                  debug_prefix(NULL), tok));
+           if(verbose) {
+               printf("ERROR [unknown option \"%s\"]\n", tok);
+           }
+       }
+       tok = strtok(NULL, ";");
+    }
+    if(g_options->features == NULL) {
+       g_options->features = am_set_default_feature_set();
+    }
+    if(g_options->maxdumps == 0) /* default */
+       g_options->maxdumps = 1;
+    amfree(p);
+    return g_options;
+}
+
+void
+free_g_options(
+    g_option_t *       g_options)
+{
+    amfree(g_options->str);
+    am_release_feature_set(g_options->features);
+    amfree(g_options->hostname);
+    amfree(g_options->auth);
+    amfree(g_options->config);
+    amfree(g_options);
+}
index 93a4b100662ed017eb8a81980a3b14bc567f2c7b..49eb2beec002e60d3dcb8c7dca6f6eb3a1abae0a 100644 (file)
@@ -72,11 +72,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -84,6 +87,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
index 8ab4d20412bee979748bcbc588db3d68c28d12ff..05a6ce8166829f7178d014fbaea949205cbd3270 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
 # Copyright (c) 1992-1998 University of Maryland at College Park
 # All Rights Reserved.
index 490e987702b095353e2e68486bcd1fc1f9c01fe1..2471aa25c22da162a6166d5cdeae53c5e353f191 100644 (file)
@@ -5,6 +5,9 @@ INCLUDES =      -I$(top_builddir)/common-src \
                -I$(top_srcdir)/server-src   \
                -I$(top_srcdir)/tape-src
 
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
 LIB_EXTENSION = la
 
 if WANT_CHIO_SCSI
@@ -36,15 +39,18 @@ CLEANFILES = $(libexec_SCRIPTS)
 LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../server-src/libamserver.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION)   \
+       $(READLINE_LIBS)
 
 SUFFIXES =             .pl .sh
 
-chg_scsi_SOURCES =     chg-scsi.c libscsi.h scsi-defs.h \
-       scsi-aix.c scsi-changer-driver.c scsi-hpux_new.c scsi-irix.c \
-       scsi-linux.c scsi-solaris.c scsi-bsd.c scsi-cam.c sense.c 
+chg_scsi_CSRC = chg-scsi.c scsi-aix.c scsi-changer-driver.c            \
+               scsi-hpux_new.c scsi-irix.c scsi-linux.c scsi-solaris.c \
+               scsi-bsd.c scsi-cam.c sense.c 
+chg_scsi_SOURCES = libscsi.h scsi-defs.h $(chg_scsi_CSRC)
 
-chg_scsi_chio_SOURCES = chg-scsi-chio.c scsi-hpux.c scsi-chio.c libscsi.h
+chg_scsi_chio_CSRC = chg-scsi-chio.c scsi-hpux.c scsi-chio.c
+chg_scsi_chio_SOURCES = libscsi.h $(chg_scsi_chio_CSRC)
 
 EXTRA_DIST = scsi-proto.c
 
@@ -74,3 +80,21 @@ install-exec-hook:
                echo chgrp $(SETUID_GROUP) $$pa; \
                chgrp $(SETUID_GROUP) $$pa; \
        done
+
+lint:
+       @ for p in $(libexec_PROGRAMS) $(EXTRA_PROGRAMS); do                    \
+               f="$$p.c $(libamandad_la_SOURCES)";                             \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               (cd ../server-src; make listlibsrc);                            \
+               f="$$f "`cat ../server-src/listlibsrc.output`;                  \
+               (cd ../tape-src; make listlibsrc);                              \
+               f="$$f "`cat ../tape-src/listlibsrc.output`;                    \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
index d897921f5cf37ed7cc3afd4e1937c3b5321cfb93..19906e5f37c2ea11fdd78156d1eeed4f03012dda 100644 (file)
@@ -66,25 +66,28 @@ CONFIG_CLEAN_FILES = chg-manual.sh chg-multi.sh chg-mtx.sh chg-chs.sh \
 am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(libexecdir)"
 libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(libexec_PROGRAMS)
-am_chg_scsi_OBJECTS = chg-scsi.$(OBJEXT) scsi-aix.$(OBJEXT) \
+am__objects_1 = chg-scsi.$(OBJEXT) scsi-aix.$(OBJEXT) \
        scsi-changer-driver.$(OBJEXT) scsi-hpux_new.$(OBJEXT) \
        scsi-irix.$(OBJEXT) scsi-linux.$(OBJEXT) \
        scsi-solaris.$(OBJEXT) scsi-bsd.$(OBJEXT) scsi-cam.$(OBJEXT) \
        sense.$(OBJEXT)
+am_chg_scsi_OBJECTS = $(am__objects_1)
 chg_scsi_OBJECTS = $(am_chg_scsi_OBJECTS)
 chg_scsi_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
 chg_scsi_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../server-src/libamserver.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
-am_chg_scsi_chio_OBJECTS = chg-scsi-chio.$(OBJEXT) scsi-hpux.$(OBJEXT) \
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
+am__objects_2 = chg-scsi-chio.$(OBJEXT) scsi-hpux.$(OBJEXT) \
        scsi-chio.$(OBJEXT)
+am_chg_scsi_chio_OBJECTS = $(am__objects_2)
 chg_scsi_chio_OBJECTS = $(am_chg_scsi_chio_OBJECTS)
 chg_scsi_chio_LDADD = $(LDADD)
 chg_scsi_chio_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../server-src/libamserver.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 libexecSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 SCRIPTS = $(libexec_SCRIPTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
@@ -110,11 +113,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -122,6 +128,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -307,6 +315,8 @@ INCLUDES = -I$(top_builddir)/common-src \
                -I$(top_srcdir)/server-src   \
                -I$(top_srcdir)/tape-src
 
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
 LIB_EXTENSION = la
 @WANT_CHIO_SCSI_TRUE@CHIO_SCSI = chg-scsi-chio
 @WANT_CHG_SCSI_TRUE@CHG_SCSI = chg-scsi
@@ -327,14 +337,17 @@ CLEANFILES = $(libexec_SCRIPTS)
 LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../server-src/libamserver.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION)   \
+       $(READLINE_LIBS)
 
 SUFFIXES = .pl .sh
-chg_scsi_SOURCES = chg-scsi.c libscsi.h scsi-defs.h \
-       scsi-aix.c scsi-changer-driver.c scsi-hpux_new.c scsi-irix.c \
-       scsi-linux.c scsi-solaris.c scsi-bsd.c scsi-cam.c sense.c 
+chg_scsi_CSRC = chg-scsi.c scsi-aix.c scsi-changer-driver.c            \
+               scsi-hpux_new.c scsi-irix.c scsi-linux.c scsi-solaris.c \
+               scsi-bsd.c scsi-cam.c sense.c 
 
-chg_scsi_chio_SOURCES = chg-scsi-chio.c scsi-hpux.c scsi-chio.c libscsi.h
+chg_scsi_SOURCES = libscsi.h scsi-defs.h $(chg_scsi_CSRC)
+chg_scsi_chio_CSRC = chg-scsi-chio.c scsi-hpux.c scsi-chio.c
+chg_scsi_chio_SOURCES = libscsi.h $(chg_scsi_chio_CSRC)
 EXTRA_DIST = scsi-proto.c
 all: all-am
 
@@ -702,6 +715,24 @@ install-exec-hook:
                echo chgrp $(SETUID_GROUP) $$pa; \
                chgrp $(SETUID_GROUP) $$pa; \
        done
+
+lint:
+       @ for p in $(libexec_PROGRAMS) $(EXTRA_PROGRAMS); do                    \
+               f="$$p.c $(libamandad_la_SOURCES)";                             \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               (cd ../server-src; make listlibsrc);                            \
+               f="$$f "`cat ../server-src/listlibsrc.output`;                  \
+               (cd ../tape-src; make listlibsrc);                              \
+               f="$$f "`cat ../tape-src/listlibsrc.output`;                    \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
index fc25b3a97204b953563e7fb475daacdc680dd5eb..bb9d5a07b4d653608f7aefac75102a7e4a4ac631 100644 (file)
@@ -68,11 +68,11 @@ if ( "@USE_VERSION_SUFFIXES@" eq "yes" ) {
 
 chomp ($tapeDevice = `$sbindir/amgetconf$SUF tapedev 2>&1`);
 die "tapedev not found in amanda.conf"
-       if !$tapeDevice or $tapeDevice =~ m/BUGGY/;
+       if !$tapeDevice or $tapeDevice =~ m/no such parameter/;
 chomp ($changerDevice = `$sbindir/amgetconf$SUF changerdev 2>&1`);
 chomp $changerDevice;
 die "changerdev not found in amanda.conf"
-       if !$changerDevice or $changerDevice =~ m/BUGGY/;
+       if !$changerDevice or $changerDevice =~ m/no such parameter/;
 
 #
 # Initialise a few global variables
index 063084b75d43df7087dc6e616de1bf31c236f95d..5980436d7f7bdaa5a4fd19dd2ceeac7f070a759b 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 #
 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
 # Copyright (c) 1991-1998 University of Maryland at College Park
index 72dc98b3e66f7ec5ff87a9af525d349e3dea5f6a..543d96d0a1a9a94f248e8b80d1ea5d5635f1ed9c 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! @SHELL@
 #
 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
 # Copyright (c) 1991-1999 University of Maryland at College Park
@@ -86,25 +86,36 @@ isinteger() {
        expr "$1" : '[0-9][0-9]*$' > /dev/null 2>&1
 }
 
+# Need rwx access to the virtual tape itself.
+if ! test -d $SLOTDIR; then
+    echo "Virtual-tape directory $SLOTDIR does not exist." 1>&2
+    exit 2
+fi
+if ! test -w $SLOTDIR; then
+    echo "Virtual-tape directory $SLOTDIR is not writable." 1>&2
+    exit 2
+fi
+
+
 # need rwx access to directory of changer file
 CHANGERFILE=`amgetconf$SUF changerfile`
 CFDir=`dirname ${CHANGERFILE}`
 [ -d ${CFDir} -a -r ${CFDir} -a -w ${CFDir} -a -x ${CFDir} ] ||
-       { echo "$MYNAME: need 'rwx' access to '$CFDir'" ; exit 2 ; }
+       { echo "$MYNAME: need 'rwx' access to '$CFDir'" 1>&2 ; exit 2 ; }
 
 # check or create changer metadata files
 ACCESSFILE=$CHANGERFILE-access
 [ -f $ACCESSFILE -a -r $ACCESSFILE -a -w $ACCESSFILE ] ||
        echo 0 > $ACCESSFILE ||
-       { echo "$MYNAME: could not access or create '$ACCESSFILE'" ; exit 2 ; }
+       { echo "$MYNAME: could not access or create '$ACCESSFILE'" 1>&2 ; exit 2 ; }
 CLEANFILE=$CHANGERFILE-clean
 [ -f $CLEANFILE -a -r $CLEANFILE -a -w $CLEANFILE ] ||
        echo 0 > $CLEANFILE ||
-       { echo "$MYNAME: could not access or create '$CLEANFILE'" ; exit 2 ; }
+       { echo "$MYNAME: could not access or create '$CLEANFILE'" 1>&2 ; exit 2 ; }
 SLOTFILE=$CHANGERFILE-slot
 [ -f $SLOTFILE -a -r $SLOTFILE -a -w $SLOTFILE ] ||
        echo 0 > $SLOTFILE ||
-       { echo "$MYNAME: could not access or create '$SLOTFILE'" ; exit 2 ; }
+       { echo "$MYNAME: could not access or create '$SLOTFILE'" 1>&2 ; exit 2 ; }
 
 # read and check metadata
 ACCESSCOUNT=`cat $ACCESSFILE`
@@ -116,6 +127,7 @@ FIRSTSLOT=1
 LASTSLOT=`amgetconf$SUF tapecycle`
 CURSLOT=0
 CLEANSLOT=$LASTSLOT
+NSLOT=`expr $LASTSLOT - $FIRSTSLOT + 1`
 
 load() {
   WHICHSLOT=$1;
@@ -165,13 +177,13 @@ loadslot() {
     if [ $WHICHSLOT -ge $FIRSTSLOT -a $WHICHSLOT -le $LASTSLOT ]; then
       NEWSLOT=$WHICHSLOT
     else
-      echo "0 illegal request"
+      echo "$WHICHSLOT illegal slot"
       exit 1
     fi
   elif [ $WHICHSLOT = "clean" ]; then
     NEWSLOT=$CLEANSLOT
   else
-    echo "0 illegal request"
+    echo "$WHICHSLOT illegal request"
     exit 1
   fi
   if [ $NEWSLOT = $CURSLOT ]; then
@@ -204,7 +216,7 @@ loadslot() {
 
 info() {
   readstatus
-  echo "$CURSLOT $LASTSLOT $FIRSTSLOT"
+  echo "$CURSLOT $NSLOT 1"
   exit 0
 }
 
index 6f946e0ad32037545e32ab912577c1e64f50a606..7307399ad5c303ad9010c0b2d051919b9ae595af 100644 (file)
@@ -81,18 +81,18 @@ if ( "@USE_VERSION_SUFFIXES@" eq "yes" ) {
 
 chomp ($tapeDevice = `$sbindir/amgetconf$SUF tapedev 2>&1`);
 die "tapedev not found in amanda.conf"
-       if !$tapeDevice or $tapeDevice =~ m/BUGGY/;
+       if !$tapeDevice or $tapeDevice =~ m/no such parameter/;
 chomp ($changerDevice = `$sbindir/amgetconf$SUF changerdev 2>&1`);
 chomp $changerDevice;
 die "changerdev not found in amanda.conf"
-       if !$changerDevice or $changerDevice =~ m/BUGGY/;
+       if !$changerDevice or $changerDevice =~ m/no such parameter/;
 
 #
 # Initialise a few global variables
 #
 
 $current_label = "";
-$current_slot = 0;
+#$current_slot = 0;
 $max_slot = 1;
 
 @dow = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
index abb0a1a1f761667cf22d247f34eae724fdbf67e7..b894623e8a73faa26987dcd7a89b782ebf395ac8 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 
 # chg-juke
 #
index 0c966d4ead225129d2a31f80ef67e542fb9fc222..6dcfaa9d273132d20bb1eb437e53e29ea1824c04 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh 
+#!@SHELL@ 
 #
 # Exit Status:
 # 0 Alles Ok
index 934e2f7d093c189aba05eefa05cff8ee406f04b7..d31201f635297f9f8848be62d35173b7d40457a1 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh 
+#!@SHELL@ 
 #
 # Author: Robert Dege
 #
index ba9f724b5fb1d478b65bd1a56ea70ed30e077742..2966161da9c03652044c9b0fd5cc9a086c3d0c46 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh 
+#!@SHELL@ 
 #
 # Exit Status:
 # 0 Alles Ok
index 0103c815b36a22bdfa97cd178423827bbc7596a1..9ac098ee4afa45b4af6265a3a5a3242c20633df0 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! @SHELL@
 #
 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
 # Copyright (c) 1991-1999 University of Maryland at College Park
index de3cb51f39ece2f2b9fb586ac0f03719f43abf88..2d97be4ba9bc9becd76835520ce2c7800be65431 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh 
+#!@SHELL@ 
 #
 # Exit Status:
 # 0 Alles Ok
index ceeffe7095802fdf5a1817fd2ad0fc8e8738059b..878996fe4c0ca3003db86e7f8e47ec2549bf0cd8 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 
 # chg-rait
 #
index b86074de3fbb4fb4509e90c08a92a7db4c3d583e..d6bf467012d8bb425af400b039f810807afe296c 100644 (file)
@@ -1,7 +1,7 @@
 /*
- *  $Id: chg-scsi-chio.c,v 1.8 2006/01/14 04:37:18 paddy_s Exp $
+ *  $Id: chg-scsi-chio.c,v 1.12 2006/07/25 18:18:46 martinea Exp $
  *
- *  chg-scsi.c -- generic SCSI changer driver
+ *  chg-scsi-chio.c -- generic SCSI changer driver
  *
  *  This program provides a driver to control generic
  *  SCSI changers, no matter what platform.  The host/OS
 #include "amanda.h"
 #include "conffile.h"
 #include "libscsi.h"
+#include "scsi-defs.h"
 
 char *tapestatfile = NULL;
 
 /*----------------------------------------------------------------------------*/
-/* Some stuff for our own configurationfile */
-typedef struct {  /* The information we can get for any drive (configuration) */
-  int drivenum;      /* Which drive to use in the library */
-  int start;         /* Which is the first slot we may use */
-  int end;           /* The last slot we are allowed to use */
-  int cleanslot;     /* Where the cleaningcartridge stays */
-  char *scsitapedev; /* Where can we send raw SCSI commands to the tape */
-  char *device;      /* Which device is associated to the drivenum */
-  char *slotfile;    /* Where we should have our memory */   
-  char *cleanfile;   /* Where we count how many cleanings we did */
-  char *timefile;    /* Where we count the time the tape was used*/
-  char *tapestatfile;/* Where can we place some drive stats */
-}config_t; 
-
-typedef struct {
-  int number_of_configs; /* How many different configurations are used */
-  int eject;             /* Do the drives need an eject-command */
-  int sleep;             /* How many seconds to wait for the drive to get ready */
-  int cleanmax;          /* How many runs could be done with one cleaning tape */
-  char *device;          /* Which device is our changer */
-  config_t *conf;
-}changer_t;
 
 typedef enum{
   NUMDRIVE,EJECT,SLEEP,CLEANMAX,DRIVE,START,END,CLEAN,DEVICE,STATFILE,CLEANFILE,DRIVENUM,
@@ -92,124 +71,170 @@ typedef enum{
 
 typedef struct {
   char *word;
-  int token;
+  token_t token;
 } tokentable_t;
 
 tokentable_t t_table[]={
-  { "number_configs",NUMDRIVE},
-  { "eject",EJECT},
-  { "sleep",SLEEP},
-  { "cleanmax",CLEANMAX},
-  { "config",DRIVE},
-  { "startuse",START},
-  { "enduse",END},
-  { "cleancart",CLEAN},
-  { "dev",DEVICE},
-  { "statfile",STATFILE},
-  { "cleanfile",CLEANFILE},
-  { "drivenum",DRIVENUM},
-  { "changerdev",CHANGERDEV},
-  { "usagecount",USAGECOUNT},
-  { "scsitapedev", SCSITAPEDEV},
-  { "tapestatus", TAPESTATFILE},
-  { NULL,-1 }
+  { "number_configs",  NUMDRIVE},
+  { "eject",           EJECT},
+  { "sleep",           SLEEP},
+  { "cleanmax",                CLEANMAX},
+  { "config",          DRIVE},
+  { "startuse",                START},
+  { "enduse",          END},
+  { "cleancart",       CLEAN},
+  { "dev",             DEVICE},
+  { "statfile",                STATFILE},
+  { "cleanfile",       CLEANFILE},
+  { "drivenum",                DRIVENUM},
+  { "changerdev",      CHANGERDEV},
+  { "usagecount",      USAGECOUNT},
+  { "scsitapedev",     SCSITAPEDEV},
+  { "tapestatus",      TAPESTATFILE},
+  { NULL,              -1 }
 };
 
-void init_changer_struct(changer_t *chg,int number_of_config)
-     /* Initialize datasructures with default values */
+changer_t *changer;
+
+void   init_changer_struct(changer_t *chg, size_t number_of_config);
+void   dump_changer_struct(changer_t *chg);
+void   free_changer_struct(changer_t **changer);
+void   parse_line(char *linebuffer,int *token,char **value);
+int    read_config(char *configfile, changer_t *chg);
+int    get_current_slot(char *count_file);
+void   put_current_slot(char *count_file,int slot);
+void   usage(char *argv[]);
+void   parse_args(int argc, char *argv[],command *rval);
+int    get_relative_target(int fd,int nslots,char *parameter,int loaded, 
+                        char *changer_file,int slot_offset,int maxslot);
+int    is_positive_number(char *tmp);
+int    ask_clean(char *tapedev);
+void   clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum, 
+                int cleancart, int maxclean,char *usagetime);
+int    main(int argc, char *argv[]);
+
+
+/*
+ * Initialize data structures with default values
+*/
+void
+init_changer_struct(
+    changer_t *        chg,
+    size_t     number_of_config)
 {
   int i;
-  
+  memset(chg, 0, SIZEOF(*chg));
   chg->number_of_configs = number_of_config;
   chg->eject = 1;
   chg->sleep = 0;
   chg->cleanmax = 0;
-  chg->device = NULL;
-  chg->conf = malloc(sizeof(config_t)*number_of_config);
-  if (chg->conf != NULL){
-    for (i=0; i < number_of_config; i++){
-      chg->conf[i].drivenum   = 0;
-      chg->conf[i].start      = -1;
-      chg->conf[i].end        = -1;
-      chg->conf[i].cleanslot  = -1;
-      chg->conf[i].device     = NULL;
-      chg->conf[i].slotfile   = NULL;
-      chg->conf[i].cleanfile  = NULL;
-      chg->conf[i].timefile  = NULL;
-      chg->conf[i].scsitapedev = NULL;
-      chg->conf[i].tapestatfile = NULL;
-    }
+  chg->device = NULL
+  chg->conf = alloc(SIZEOF(config_t) * number_of_config);
+  for (i=0; i < number_of_config; i++){
+    chg->conf[i].drivenum     = 0;
+    chg->conf[i].start        = -1;
+    chg->conf[i].end          = -1;
+    chg->conf[i].cleanslot    = -1;
+    chg->conf[i].device       = NULL;
+    chg->conf[i].slotfile     = NULL;
+    chg->conf[i].cleanfile    = NULL;
+    chg->conf[i].timefile     = NULL;
+    chg->conf[i].scsitapedev  = NULL;
+    chg->conf[i].tapestatfile = NULL;
+    chg->conf[i].changerident = NULL;
+    chg->conf[i].tapeident    = NULL;
   }
 }
 
-void dump_changer_struct(changer_t chg)
-     /* Dump of information for debug */
+/*
+ * Dump of information for debug
+*/
+void
+dump_changer_struct(
+    changer_t *        chg)
 {
   int i;
 
-  dbprintf(("Number of configurations: %d\n",chg.number_of_configs));
-  dbprintf(("Tapes need eject: %s\n",(chg.eject>0?"Yes":"No")));
-  dbprintf(("Tapes need sleep: %d seconds\n",chg.sleep));
-  dbprintf(("Cleancycles     : %d\n",chg.cleanmax));
-  dbprintf(("Changerdevice   : %s\n",chg.device));
-  for (i=0; i<chg.number_of_configs; i++){
-    dbprintf(("Tapeconfig Nr: %d\n",i));
-    dbprintf(("  Drivenumber   : %d\n",chg.conf[i].drivenum));
-    dbprintf(("  Startslot     : %d\n",chg.conf[i].start));
-    dbprintf(("  Endslot       : %d\n",chg.conf[i].end));
-    dbprintf(("  Cleanslot     : %d\n",chg.conf[i].cleanslot));
-    if (chg.conf[i].device != NULL)
-      dbprintf(("  Devicename    : %s\n",chg.conf[i].device));
+  dbprintf(("Number of configurations: %d\n", chg->number_of_configs));
+  dbprintf(("Tapes need eject: %s\n", (chg->eject>0 ? "Yes" : "No")));
+  dbprintf(("Tapes need sleep: %d seconds\n", chg->sleep));
+  dbprintf(("Cleancycles     : %d\n", chg->cleanmax));
+  dbprintf(("Changerdevice   : %s\n", chg->device));
+  for (i = 0; i < chg->number_of_configs; i++){
+    dbprintf(("Tapeconfig Nr: %d\n", i));
+    dbprintf(("  Drivenumber   : %d\n", chg->conf[i].drivenum));
+    dbprintf(("  Startslot     : %d\n", chg->conf[i].start));
+    dbprintf(("  Endslot       : %d\n", chg->conf[i].end));
+    dbprintf(("  Cleanslot     : %d\n", chg->conf[i].cleanslot));
+    if (chg->conf[i].device != NULL)
+      dbprintf(("  Devicename    : %s\n", chg->conf[i].device));
     else
       dbprintf(("  Devicename    : none\n"));
-    if (chg.conf[i].scsitapedev != NULL)
-      dbprintf(("  SCSITapedev   : %s\n",chg.conf[i].scsitapedev));
+    if (chg->conf[i].scsitapedev != NULL)
+      dbprintf(("  SCSITapedev   : %s\n", chg->conf[i].scsitapedev));
     else
       dbprintf(("  SCSITapedev   : none\n"));
-    if (chg.conf[i].tapestatfile != NULL)
-      dbprintf(("  statfile      : %s\n", chg.conf[i].tapestatfile));
+    if (chg->conf[i].tapestatfile != NULL)
+      dbprintf(("  statfile      : %s\n", chg->conf[i].tapestatfile));
     else
       dbprintf(("  statfile      : none\n"));
-    if (chg.conf[i].slotfile != NULL)
-      dbprintf(("  Slotfile      : %s\n",chg.conf[i].slotfile));
+    if (chg->conf[i].slotfile != NULL)
+      dbprintf(("  Slotfile      : %s\n", chg->conf[i].slotfile));
     else
       dbprintf(("  Slotfile      : none\n"));
-    if (chg.conf[i].cleanfile != NULL)
-      dbprintf(("  Cleanfile     : %s\n",chg.conf[i].cleanfile));
+    if (chg->conf[i].cleanfile != NULL)
+      dbprintf(("  Cleanfile     : %s\n", chg->conf[i].cleanfile));
     else
       dbprintf(("  Cleanfile     : none\n"));
-    if (chg.conf[i].timefile != NULL)
-      dbprintf(("  Usagecount    : %s\n",chg.conf[i].timefile));
+    if (chg->conf[i].timefile != NULL)
+      dbprintf(("  Usagecount    : %s\n", chg->conf[i].timefile));
     else
       dbprintf(("  Usagecount    : none\n"));
   }
 }
 
-void free_changer_struct(changer_t *chg)
-     /* Free all allocated memory */
+/*
+ * Free all allocated memory
+ */
+void
+free_changer_struct(
+changer_t **changer)
 {
+  changer_t *chg;
   int i;
 
+  assert(changer != NULL);
+  assert(*changer != NULL);
+
+  chg = *changer;
   if (chg->device != NULL)
-    free(chg->device);
+    amfree(chg->device);
   for (i=0; i<chg->number_of_configs; i++){
     if (chg->conf[i].device != NULL)
-      free(chg->conf[i].device);
+      amfree(chg->conf[i].device);
     if (chg->conf[i].slotfile != NULL)
-      free(chg->conf[i].slotfile);
+      amfree(chg->conf[i].slotfile);
     if (chg->conf[i].cleanfile != NULL)
-      free(chg->conf[i].cleanfile);
+      amfree(chg->conf[i].cleanfile);
     if (chg->conf[i].timefile != NULL)
-      free(chg->conf[i].timefile);
+      amfree(chg->conf[i].timefile);
   }
   if (chg->conf != NULL)
-    free(chg->conf);
+    amfree(chg->conf);
   chg->conf = NULL;
   chg->device = NULL;
+  amfree(*changer);
 }
 
-void parse_line(char *linebuffer,int *token,char **value)
-     /* This function parses a line, and returns the token an value */
+/*
+ * This function parses a line, and returns a token and value
+ */
+void
+parse_line(
+    char *     linebuffer,
+    int *      token,
+    char **    value)
 {
   char *tok;
   int i;
@@ -235,14 +260,19 @@ void parse_line(char *linebuffer,int *token,char **value)
   return;
 }
 
-int read_config(char *configfile, changer_t *chg)
-     /* This function reads the specified configfile and fills the structure */
+/*
+ * This function reads the specified configfile and fills the structure
+*/
+int
+read_config(
+    char *     configfile,
+    changer_t *        chg)
 {
-  int numconf;
+  size_t numconf;
   FILE *file;
   int init_flag = 0;
   int drivenum=0;
-  char *linebuffer = NULL;
+  char *linebuffer;
   int token;
   char *value;
 
@@ -253,16 +283,19 @@ int read_config(char *configfile, changer_t *chg)
     return (-1);
   }
 
-  amfree(linebuffer);
-  while (NULL!=(linebuffer=agets(file))){
+  while (NULL != (linebuffer = agets(file))) {
+      if (linebuffer[0] == '\0') {
+       amfree(linebuffer);
+       continue;
+      }
       parse_line(linebuffer,&token,&value);
       if (token != -1){
         if (0==init_flag) {
           if (token != NUMDRIVE){
-            init_changer_struct(chg,numconf);
+            init_changer_struct(chg, numconf);
           } else {
             numconf = atoi(value);
-            init_changer_struct(chg,numconf);
+            init_changer_struct(chg, numconf);
           }
           init_flag=1;
         }
@@ -387,7 +420,13 @@ int get_current_slot(char *count_file)
             get_pname(), count_file);
     return 0;
   }
-  fscanf(inf,"%d",&retval);
+
+  if (fscanf(inf, "%d", &retval) != 1) {
+    fprintf(stderr, "%s: unable to read current slot file (%s)\n",
+            get_pname(), count_file);
+    retval = 0;
+  }
+
   fclose(inf);
   return retval;
 }
@@ -481,30 +520,48 @@ void usage(char *argv[])
 void parse_args(int argc, char *argv[],command *rval)
 {
   int i=0;
-  if ((argc<2)||(argc>3))
+  if ((argc < 2) || (argc > 3)) {
     usage(argv);
+    /*NOTREACHED*/
+  }
+
   while ((i<COMCOUNT)&&(strcmp(argdefs[i].str,argv[1])))
     i++;
-  if (i==COMCOUNT)
+  if (i == COMCOUNT) {
     usage(argv);
+    /*NOTREACHED*/
+  }
   rval->command_code = argdefs[i].command_code;
   if (argdefs[i].takesparam) {
-    if (argc<3)
+    if (argc < 3) {
       usage(argv);
+      /*NOTREACHED*/
+    }
     rval->parameter=argv[2];      
   }
   else {
-    if (argc>2)
+    if (argc > 2) {
       usage(argv);
+      /*NOTREACHED*/
+    }
     rval->parameter=0;
   }
 }
 
 /* used to find actual slot number from keywords next, prev, first, etc */
-int get_relative_target(int fd,int nslots,char *parameter,int loaded, 
-                        char *changer_file,int slot_offset,int maxslot)
+int
+get_relative_target(
+    int                fd,
+    int                nslots,
+    char *     parameter,
+    int                loaded, 
+    char *     changer_file,
+    int                slot_offset,
+    int                maxslot)
 {
   int current_slot,i;
+
+  (void)loaded;                /* Quiet unused warning */
   if (changer_file != NULL)
     {
       current_slot=get_current_slot(changer_file);
@@ -519,52 +576,67 @@ int get_relative_target(int fd,int nslots,char *parameter,int loaded,
   }
 
   i=0;
-  while((i<SLOTCOUNT)&&(strcmp(slotdefs[i].str,parameter)))
+  while((i < SLOTCOUNT) && (strcmp(slotdefs[i].str,parameter)))
     i++;
 
   switch(i) {
   case SLOT_CUR:
-    return current_slot;
     break;
+
   case SLOT_NEXT:
     if (++current_slot==nslots+slot_offset)
       return slot_offset;
-    else
-      return current_slot;
     break;
+
   case SLOT_PREV:
     if (--current_slot<slot_offset)
       return maxslot;
-    else
-      return current_slot;
     break;
+
   case SLOT_FIRST:
     return slot_offset;
-    break;
+
   case SLOT_LAST:
     return maxslot;
-    break;
+
   default: 
     printf("<none> no slot `%s'\n",parameter);
     close(fd);
     exit(2);
-  };
+    /*NOTREACHED*/
+  }
+  return current_slot;
 }
 
-int ask_clean(char *tapedev)
-     /* This function should ask the drive if it wants to be cleaned */
+/*
+ * This function should ask the drive if it wants to be cleaned
+ */
+int
+ask_clean(
+    char *     tapedev)
 {
   return get_clean_state(tapedev);
 }
 
-void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum, 
-                int cleancart, int maxclean,char *usagetime)
-     /* This function should move the cleaning cartridge into the drive */
+/*
+ * This function should move the cleaning cartridge into the drive
+ */
+void
+clean_tape(
+    int                fd,
+    char *     tapedev,
+    char *     cnt_file,
+    int                drivenum,
+    int                cleancart,
+    int                maxclean,
+    char *     usagetime)
 {
-  int counter=-1;
+  int counter;
+
   if (cleancart == -1 ){
     return;
   }
+
   /* Now we should increment the counter */
   if (cnt_file != NULL){
     counter = get_current_slot(cnt_file);
@@ -573,25 +645,38 @@ void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum,
       /* Now we should inform the administrator */
       char *mail_cmd;
       FILE *mailf;
-      mail_cmd = vstralloc(MAILER,
+      int mail_pipe_opened = 1;
+      if(getconf_seen(CNF_MAILTO) && strlen(getconf_str(CNF_MAILTO)) > 0 && 
+         validate_mailto(getconf_str(CNF_MAILTO))) {
+        mail_cmd = vstralloc(MAILER,
                            " -s", " \"", "AMANDA PROBLEM: PLEASE FIX", "\"",
                            " ", getconf_str(CNF_MAILTO),
                            NULL);
-      if((mailf = popen(mail_cmd, "w")) == NULL){
-        error("could not open pipe to \"%s\": %s",
-              mail_cmd, strerror(errno));
-        printf("Mail failed\n");
-        return;
+        if((mailf = popen(mail_cmd, "w")) == NULL){
+               printf("Mail failed\n");
+               error("could not open pipe to \"%s\": %s",
+               mail_cmd, strerror(errno));
+               /*NOTREACHED*/
+       }
       }
+      else{
+        mail_pipe_opened = 0;
+        mailf = stderr;
+         fprintf(mailf, "\nNo mail recipient specified, output redirected to stderr");
+       }
+       
       fprintf(mailf,"\nThe usage count of your cleaning tape in slot %d",
-              cleancart);
+             cleancart);
       fprintf(mailf,"\nis more than %d. (cleanmax)",maxclean);
       fprintf(mailf,"\nTapedrive %s needs to be cleaned",tapedev);
       fprintf(mailf,"\nPlease insert a new cleaning tape and reset");
       fprintf(mailf,"\nthe countingfile %s",cnt_file);
 
-      if(pclose(mailf) != 0)
-        error("mail command failed: %s", mail_cmd);
+      if(mail_pipe_opened == 1 && pclose(mailf) != 0) {
+        error("mail command failed: %s", mail_cmd);
+               /*NOTREACHED*/
+      }
+      
 
       return;
     }
@@ -605,11 +690,15 @@ void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum,
 }
 /* ----------------------------------------------------------------------*/
 
-int main(int argc, char *argv[])
+int
+main(
+    int                argc,
+    char *     argv[])
 {
-  int loaded,target,oldtarget;
+  int loaded;
+  int target = -1;
+  int oldtarget;
   command com;   /* a little DOS joke */
-  changer_t chg;
   
   /*
    * drive_num really should be something from the config file, but..
@@ -619,7 +708,7 @@ int main(int argc, char *argv[])
    */
   int    drive_num = 0;
   int need_eject = 0; /* Does the drive need an eject command ? */
-  int need_sleep = 0; /* How many seconds to wait for the drive to get ready */
+  unsigned need_sleep = 0; /* How many seconds to wait for the drive to get ready */
   int clean_slot = -1;
   int maxclean = 0;
   char *clean_file=NULL;
@@ -629,9 +718,10 @@ int main(int argc, char *argv[])
   int slot_offset;
   int confnum;
 
-  int fd, rc, slotcnt, drivecnt;
+  int fd, slotcnt, drivecnt;
   int endstatus = 0;
-  char *changer_dev, *tape_device;
+  char *changer_dev = NULL;
+  char *tape_device = NULL;
   char *changer_file = NULL;
   char *scsitapedevice = NULL;
 
@@ -640,9 +730,10 @@ int main(int argc, char *argv[])
   /* Don't die when child closes pipe */
   signal(SIGPIPE, SIG_IGN);
 
-  dbopen();
+  dbopen(DBG_SUBDIR_SERVER);
   parse_args(argc,argv,&com);
 
+  changer = alloc(SIZEOF(changer_t));
   if(read_conffile(CONFFILE_NAME)) {
     fprintf(stderr, "%s: could not find config file \"%s\"",
                    changer_dev, conffile);
@@ -654,34 +745,37 @@ int main(int argc, char *argv[])
   tape_device = getconf_str(CNF_TAPEDEV);
 
   /* Get the configuration parameters */
+
   if (strlen(tape_device)==1){
-    read_config(changer_file,&chg);
+    read_config(changer_file, changer);
     confnum=atoi(tape_device);
-    use_slots    = chg.conf[confnum].end-chg.conf[confnum].start+1;
-    slot_offset  = chg.conf[confnum].start;
-    drive_num    = chg.conf[confnum].drivenum;
-    need_eject   = chg.eject;
-    need_sleep   = chg.sleep;
-    clean_file   = stralloc(chg.conf[confnum].cleanfile);
-    clean_slot   = chg.conf[confnum].cleanslot;
-    maxclean     = chg.cleanmax;
-    if (NULL != chg.conf[confnum].timefile)
-      time_file = stralloc(chg.conf[confnum].timefile);
-    if (NULL != chg.conf[confnum].slotfile)
-      changer_file = stralloc(chg.conf[confnum].slotfile);
+    use_slots    = changer->conf[confnum].end-changer->conf[confnum].start+1;
+    slot_offset  = changer->conf[confnum].start;
+    drive_num    = changer->conf[confnum].drivenum;
+    need_eject   = changer->eject;
+    need_sleep   = changer->sleep;
+    clean_file   = stralloc(changer->conf[confnum].cleanfile);
+    clean_slot   = changer->conf[confnum].cleanslot;
+    maxclean     = changer->cleanmax;
+    if (NULL != changer->conf[confnum].timefile)
+      time_file = stralloc(changer->conf[confnum].timefile);
+    if (NULL != changer->conf[confnum].slotfile)
+      changer_file = stralloc(changer->conf[confnum].slotfile);
     else
       changer_file = NULL;
-    if (NULL != chg.conf[confnum].device)
-      tape_device  = stralloc(chg.conf[confnum].device);
-    if (NULL != chg.device)
-      changer_dev  = stralloc(chg.device); 
-    if (NULL != chg.conf[confnum].scsitapedev)
-      scsitapedevice = stralloc(chg.conf[confnum].scsitapedev);
-    if (NULL != chg.conf[confnum].tapestatfile)
-      tapestatfile = stralloc(chg.conf[confnum].tapestatfile);
-    dump_changer_struct(chg);
+    if (NULL != changer->conf[confnum].device)
+      tape_device  = stralloc(changer->conf[confnum].device);
+    if (NULL != changer->device)
+      changer_dev  = stralloc(changer->device); 
+    if (NULL != changer->conf[confnum].scsitapedev)
+      scsitapedevice = stralloc(changer->conf[confnum].scsitapedev);
+    if (NULL != changer->conf[confnum].tapestatfile)
+      tapestatfile = stralloc(changer->conf[confnum].tapestatfile);
+    dump_changer_struct(changer);
     /* get info about the changer */
-    if (-1 == (fd = OpenDevice(changer_dev, "changer_dev"))) {
+    fd = OpenDevice(INDEX_CHANGER , changer_dev,
+                       "changer_dev", changer->conf[confnum].changerident);
+    if (fd == -1) {
       int localerr = errno;
       fprintf(stderr, "%s: open: %s: %s\n", get_pname(), 
               changer_dev, strerror(localerr));
@@ -701,15 +795,18 @@ int main(int argc, char *argv[])
          scsitapedevice = stralloc(tape_device);
       }
 
-    if ((chg.conf[confnum].end == -1) || (chg.conf[confnum].start == -1)){
+    if ((changer->conf[confnum].end == -1) || (changer->conf[confnum].start == -1)){
       slotcnt = get_slot_count(fd);
       use_slots    = slotcnt;
       slot_offset  = 0;
     }
-    free_changer_struct(&chg);
+    free_changer_struct(&changer);
   } else {
     /* get info about the changer */
-    if (-1 == (fd = OpenDevice(changer_dev))) {
+    confnum = 0;
+    fd = OpenDevice(INDEX_CHANGER , changer_dev,
+                       "changer_dev", changer->conf[confnum].changerident);
+    if (fd == -1) {
       int localerr = errno;
       fprintf(stderr, "%s: open: %s: %s\n", get_pname(), 
               changer_dev, strerror(localerr));
index fe7cb35b0c5eed58234e227233ad7b5d8f5d05f0..83516eabbd16e7b18316c99dfb93d5cf9b74173a 100644 (file)
@@ -1,6 +1,4 @@
-#ifndef lint
-static char rcsid[] = "$Id: chg-scsi.c,v 1.44 2006/03/09 20:06:10 johnfranks Exp $";
-#endif
+static char rcsid[] = "$Id: chg-scsi.c,v 1.52 2006/07/25 18:18:46 martinea Exp $";
 /*
  * 
  *
@@ -12,7 +10,7 @@ static char rcsid[] = "$Id: chg-scsi.c,v 1.44 2006/03/09 20:06:10 johnfranks Exp
  *  The device dependent part is handled by scsi-changer-driver.c
  *  The SCSI OS interface is handled by scsi-ostype.c
  *
- *  Original copyrigths:
+ *  Original copyrights:
  *
  *  This program provides a driver to control generic
  *  SCSI changers, no matter what platform.  The host/OS
@@ -67,15 +65,7 @@ static char rcsid[] = "$Id: chg-scsi.c,v 1.44 2006/03/09 20:06:10 johnfranks Exp
 
 
 #include "config.h"
-
-
 #include "amanda.h"
-
-#ifdef HAVE_DMALLOC_H
-#include <dmalloc.h>
-#endif
-
-
 #include "conffile.h"
 #include "libscsi.h"
 #include "scsi-defs.h"
@@ -98,12 +88,10 @@ extern ElementInfo_T *pMTE; /*Medium Transport Element */
 extern ElementInfo_T *pSTE; /*Storage Element */
 extern ElementInfo_T *pIEE; /*Import Export Element */
 extern ElementInfo_T *pDTE; /*Data Transfer Element */
-extern int MTE;             /*Counter for the above element types */
-extern int STE;
-extern int IEE;
-extern int DTE;
-
-changer_t chg;
+extern size_t MTE;             /*Counter for the above element types */
+extern size_t STE;
+extern size_t IEE;
+extern size_t DTE;
 
 int do_inventory = 0;     /* Set if load/unload functions thinks an inventory should be done */
 int clean_slot = -1;
@@ -116,167 +104,190 @@ typedef enum{
 
 typedef struct {
   char *word;
-  int token;
+  token_t token;
 } tokentable_t;
 
-tokentable_t t_table[]={
-  { "number_configs",NUMDRIVE},
-  { "autoinv", AUTOINV},
-  { "eject",EJECT},
-  { "sleep",SLEEP},
-  { "cleanmax",CLEANMAX},
-  { "config",DRIVE},
-  { "startuse",START},
-  { "enduse",END},
-  { "cleancart",CLEAN},
-  { "dev",DEVICE},
-  { "statfile",STATFILE},
-  { "cleanfile",CLEANFILE},
-  { "drivenum",DRIVENUM},
-  { "changerdev",CHANGERDEV},
-  { "usagecount",USAGECOUNT},
-  { "scsitapedev", SCSITAPEDEV},
-  { "tapestatus", TAPESTATFILE},
-  { "labelfile", LABELFILE},
-  { "changerident" , CHANGERIDENT},
-  { "tapeident", TAPEIDENT},
-  { "emubarcode", EMUBARCODE},
-  { "havebarcode", HAVEBARCODE},
-  { "debuglevel", DEBUGLEVEL},
-  { NULL,-1 }
+tokentable_t t_table[] = {
+  { "number_configs",  NUMDRIVE},
+  { "autoinv",         AUTOINV},
+  { "eject",           EJECT},
+  { "sleep",           SLEEP},
+  { "cleanmax",                CLEANMAX},
+  { "config",          DRIVE},
+  { "startuse",                START},
+  { "enduse",          END},
+  { "cleancart",       CLEAN},
+  { "dev",             DEVICE},
+  { "statfile",                STATFILE},
+  { "cleanfile",       CLEANFILE},
+  { "drivenum",                DRIVENUM},
+  { "changerdev",      CHANGERDEV},
+  { "usagecount",      USAGECOUNT},
+  { "scsitapedev",     SCSITAPEDEV},
+  { "tapestatus",      TAPESTATFILE},
+  { "labelfile",       LABELFILE},
+  { "changerident",    CHANGERIDENT},
+  { "tapeident",       TAPEIDENT},
+  { "emubarcode",      EMUBARCODE},
+  { "havebarcode",     HAVEBARCODE},
+  { "debuglevel",      DEBUGLEVEL},
+  { NULL,              -1 }
 };
-
-void init_changer_struct(changer_t *chg,int number_of_config)
-     /* Initialize datasructures with default values */
+changer_t *changer;
+int ask_clean(char *tapedev);
+int get_current_slot(char *count_file);
+int get_relative_target(int fd, int nslots, char *parameter,
+               int param_index, int loaded, char *slot_file,
+               int slot_offset, int maxslot);
+int is_positive_number(char *tmp);
+int MapBarCode(char *labelfile, MBC_T *result);
+int read_config(char *configfile, changer_t *chg);
+void clean_tape(int fd, char *tapedev, char *cnt_file, int drivenum,
+               int cleancart, int maxclean, char *usagetime);
+void dump_changer_struct(changer_t *chg);
+void free_changer_struct(changer_t **chg);
+void init_changer_struct(changer_t *chg, int number_of_config);
+void parse_line(char *linebuffer, int *token,char **value);
+void put_current_slot(char *count_file, int slot);
+void usage(char *argv[]);
+
+int main(int argc, char *argv[]);
+
+
+/* Initialize data structures with default values */
+void
+init_changer_struct(
+    changer_t *chg,
+    int number_of_config)
 {
   int i;
  
+  memset(chg, 0, SIZEOF(*chg));
   chg->number_of_configs = number_of_config;
   chg->eject = 1;
-  chg->sleep = 0;
-  chg->autoinv = 0;
-  chg->cleanmax = 0;
-  chg->havebarcode = 0;
-  chg->emubarcode = 0; 
-  chg->device = NULL;
-  chg->labelfile = NULL;
-  chg->debuglevel = NULL;
-  chg->conf = malloc(sizeof(config_t)*number_of_config);
-  if (chg->conf != NULL){
-    for (i=0; i < number_of_config; i++){
-      chg->conf[i].drivenum   = 0;
-      chg->conf[i].start      = -1;
-      chg->conf[i].end        = -1;
-      chg->conf[i].cleanslot  = -1;
-      chg->conf[i].device     = NULL;
-      chg->conf[i].slotfile   = NULL;
-      chg->conf[i].cleanfile  = NULL;
-      chg->conf[i].timefile  = NULL;
-      chg->conf[i].scsitapedev = NULL;
-      chg->conf[i].tapestatfile = NULL;
-      chg->conf[i].changerident = NULL;
-      chg->conf[i].tapeident = NULL;
-    }
-  } else {
-   fprintf(stderr,"init_changer_struct malloc failed\n");
+  chg->conf = alloc(SIZEOF(config_t) * (size_t)number_of_config);
+  for (i=0; i < number_of_config; i++){
+    chg->conf[i].drivenum     = 0;
+    chg->conf[i].start        = -1;
+    chg->conf[i].end          = -1;
+    chg->conf[i].cleanslot    = -1;
+    chg->conf[i].device       = NULL;
+    chg->conf[i].slotfile     = NULL;
+    chg->conf[i].cleanfile    = NULL;
+    chg->conf[i].timefile     = NULL;
+    chg->conf[i].scsitapedev  = NULL;
+    chg->conf[i].tapestatfile = NULL;
+    chg->conf[i].changerident = NULL;
+    chg->conf[i].tapeident    = NULL;
   }
 }
 
-void dump_changer_struct(changer_t chg)
-     /* Dump of information for debug */
+/* Dump of information for debug */
+void
+dump_changer_struct(
+    changer_t *chg)
 {
   int i;
 
-  dbprintf(("Number of configurations: %d\n",chg.number_of_configs));
-  dbprintf(("Tapes need eject: %s\n",(chg.eject>0?"Yes":"No")));
-       dbprintf (("\traw: %d\n",chg.eject));
-  dbprintf(("Inv. auto update: %s\n",(chg.autoinv>0?"Yes":"No")));
-  dbprintf (("\traw: %d\n",chg.autoinv));
-  dbprintf(("barcode reader  : %s\n",(chg.havebarcode>0?"Yes":"No")));
-  dbprintf (("\traw: %d\n",chg.havebarcode));
-  dbprintf(("Emulate Barcode : %s\n",(chg.emubarcode>0?"Yes":"No")));
-  dbprintf (("\traw: %d\n",chg.emubarcode));
-  if (chg.debuglevel != NULL)
-     dbprintf(("debug level     : %s\n", chg.debuglevel));
-  dbprintf(("Tapes need sleep: %d seconds\n",chg.sleep));
-  dbprintf(("Cleancycles     : %d\n",chg.cleanmax));
-  dbprintf(("Changerdevice   : %s\n",chg.device));
-  if (chg.labelfile != NULL)
-    dbprintf(("Labelfile       : %s\n", chg.labelfile));
-  for (i=0; i<chg.number_of_configs; i++){
+  dbprintf(("Number of configurations: %d\n",chg->number_of_configs));
+  dbprintf(("Tapes need eject: %s\n",(chg->eject>0?"Yes":"No")));
+       dbprintf (("\traw: %d\n",chg->eject));
+  dbprintf(("Inv. auto update: %s\n",(chg->autoinv>0?"Yes":"No")));
+  dbprintf (("\traw: %d\n",chg->autoinv));
+  dbprintf(("barcode reader  : %s\n",(chg->havebarcode>0?"Yes":"No")));
+  dbprintf (("\traw: %d\n",chg->havebarcode));
+  dbprintf(("Emulate Barcode : %s\n",(chg->emubarcode>0?"Yes":"No")));
+  dbprintf (("\traw: %d\n",chg->emubarcode));
+  if (chg->debuglevel != NULL)
+     dbprintf(("debug level     : %s\n", chg->debuglevel));
+  dbprintf(("Tapes need sleep: %d seconds\n",chg->sleep));
+  dbprintf(("Cleancycles     : %d\n",chg->cleanmax));
+  dbprintf(("Changerdevice   : %s\n",chg->device));
+  if (chg->labelfile != NULL)
+    dbprintf(("Labelfile       : %s\n", chg->labelfile));
+  for (i=0; i<chg->number_of_configs; i++){
     dbprintf(("Tapeconfig Nr: %d\n",i));
-    dbprintf(("  Drivenumber   : %d\n",chg.conf[i].drivenum));
-    dbprintf(("  Startslot     : %d\n",chg.conf[i].start));
-    dbprintf(("  Endslot       : %d\n",chg.conf[i].end));
-    dbprintf(("  Cleanslot     : %d\n",chg.conf[i].cleanslot));
+    dbprintf(("  Drivenumber   : %d\n",chg->conf[i].drivenum));
+    dbprintf(("  Startslot     : %d\n",chg->conf[i].start));
+    dbprintf(("  Endslot       : %d\n",chg->conf[i].end));
+    dbprintf(("  Cleanslot     : %d\n",chg->conf[i].cleanslot));
 
-    if (chg.conf[i].device != NULL)
-      dbprintf(("  Devicename    : %s\n",chg.conf[i].device));
+    if (chg->conf[i].device != NULL)
+      dbprintf(("  Devicename    : %s\n",chg->conf[i].device));
     else
       dbprintf(("  Devicename    : none\n"));
 
-    if (chg.conf[i].changerident != NULL)
-      dbprintf(("  changerident  : %s\n",chg.conf[i].changerident));
+    if (chg->conf[i].changerident != NULL)
+      dbprintf(("  changerident  : %s\n",chg->conf[i].changerident));
     else
       dbprintf(("  changerident  : none\n"));
 
-    if (chg.conf[i].scsitapedev != NULL)
-      dbprintf(("  SCSITapedev   : %s\n",chg.conf[i].scsitapedev));
+    if (chg->conf[i].scsitapedev != NULL)
+      dbprintf(("  SCSITapedev   : %s\n",chg->conf[i].scsitapedev));
     else
       dbprintf(("  SCSITapedev   : none\n"));
 
-    if (chg.conf[i].tapeident != NULL)
-      dbprintf(("  tapeident     : %s\n",chg.conf[i].tapeident));
+    if (chg->conf[i].tapeident != NULL)
+      dbprintf(("  tapeident     : %s\n",chg->conf[i].tapeident));
     else
       dbprintf(("  tapeident     : none\n"));
 
-    if (chg.conf[i].tapestatfile != NULL)
-      dbprintf(("  statfile      : %s\n", chg.conf[i].tapestatfile));
+    if (chg->conf[i].tapestatfile != NULL)
+      dbprintf(("  statfile      : %s\n", chg->conf[i].tapestatfile));
     else
       dbprintf(("  statfile      : none\n"));
 
-    if (chg.conf[i].slotfile != NULL)
-      dbprintf(("  Slotfile      : %s\n",chg.conf[i].slotfile));
+    if (chg->conf[i].slotfile != NULL)
+      dbprintf(("  Slotfile      : %s\n",chg->conf[i].slotfile));
     else
       dbprintf(("  Slotfile      : none\n"));
 
-    if (chg.conf[i].cleanfile != NULL)
-      dbprintf(("  Cleanfile     : %s\n",chg.conf[i].cleanfile));
+    if (chg->conf[i].cleanfile != NULL)
+      dbprintf(("  Cleanfile     : %s\n",chg->conf[i].cleanfile));
     else
       dbprintf(("  Cleanfile     : none\n"));
 
-    if (chg.conf[i].timefile != NULL)
-      dbprintf(("  Usagecount    : %s\n",chg.conf[i].timefile));
+    if (chg->conf[i].timefile != NULL)
+      dbprintf(("  Usagecount    : %s\n",chg->conf[i].timefile));
     else
       dbprintf(("  Usagecount    : none\n"));
   }
 }
 
-void free_changer_struct(changer_t *chg)
-     /* Free all allocated memory */
+/* Free all allocated memory */
+void
+free_changer_struct(
+    changer_t **changer)
 {
+  changer_t *chg;
   int i;
 
+  chg = *changer;
   if (chg->device != NULL)
-    free(chg->device);
-  for (i=0; i<chg->number_of_configs; i++){
+    amfree(chg->device);
+  for (i = 0; i < chg->number_of_configs; i++){
     if (chg->conf[i].device != NULL)
-      free(chg->conf[i].device);
+      amfree(chg->conf[i].device);
     if (chg->conf[i].slotfile != NULL)
-      free(chg->conf[i].slotfile);
+      amfree(chg->conf[i].slotfile);
     if (chg->conf[i].cleanfile != NULL)
-      free(chg->conf[i].cleanfile);
+      amfree(chg->conf[i].cleanfile);
     if (chg->conf[i].timefile != NULL)
-      free(chg->conf[i].timefile);
+      amfree(chg->conf[i].timefile);
   }
   if (chg->conf != NULL)
-    free(chg->conf);
+    amfree(chg->conf);
   chg->conf = NULL;
   chg->device = NULL;
+  amfree(*changer);
 }
 
-void parse_line(char *linebuffer,int *token,char **value)
-     /* This function parses a line, and returns a token and value */
+/* This function parses a line, and returns a token and value */
+void
+parse_line(
+    char *linebuffer,
+    int *token,
+    char **value)
 {
   char *tok;
   int i;
@@ -299,17 +310,19 @@ void parse_line(char *linebuffer,int *token,char **value)
     }
     tok=strtok(NULL," \t\n");
   }
-  return;
 }
 
-int read_config(char *configfile, changer_t *chg)
-     /* This function reads the specified configfile and fills the structure */
+/* This function reads the specified configfile and fills the structure */
+int
+read_config(
+    char *configfile,
+    changer_t *chg)
 {
   int numconf;
   FILE *file;
   int init_flag = 0;
   int drivenum=0;
-  char *linebuffer = NULL;
+  char *linebuffer;
   int token;
   char *value;
   char *p;
@@ -317,25 +330,35 @@ int read_config(char *configfile, changer_t *chg)
   numconf = 1;  /* At least one configuration is assumed */
   /* If there are more, it should be the first entry in the configurationfile */
 
-
-  if (NULL==(file=fopen(configfile,"r"))){
+  assert(chg != NULL);
+  if ((file=fopen(configfile,"r")) == NULL) {
     return (-1);
   }
 
-  amfree(linebuffer);
-  while ((NULL!=(linebuffer=agets(file)))) {
-      parse_line(linebuffer,&token,&value);
+  while ((NULL != (linebuffer = agets(file)))) {
+      if (linebuffer[0] == '\0') {
+       amfree(linebuffer);
+       continue;
+      }
+      parse_line(linebuffer, &token, &value);
       if (token != -1){
-        if (0==init_flag) {
+       if (value == NULL)
+         value = "0";
+
+        if (init_flag == 0) {
           if (token != NUMDRIVE){
-            init_changer_struct(chg,numconf);
+            init_changer_struct(chg, numconf);
           } else {
             numconf = atoi(value);
-            init_changer_struct(chg,numconf);
+           if (numconf < 1 || numconf > 100) {
+               fprintf(stderr,"numconf %d is bad\n", numconf);
+               numconf = 1;
+           }
+            init_changer_struct(chg, numconf);
           }
           init_flag=1;
         }
-        switch (token){
+        switch (token) {
         case NUMDRIVE: if (atoi(value) != numconf)
           fprintf(stderr,"Error: number_drives at wrong place, should be "\
                   "first in file\n");
@@ -356,7 +379,7 @@ int read_config(char *configfile, changer_t *chg)
           chg->havebarcode = atoi(value);
           break;
        case SLEEP:
-          chg->sleep = atoi(value);
+          chg->sleep = (unsigned)atoi(value);
           break;
         case LABELFILE:
           chg->labelfile = stralloc(value);
@@ -372,6 +395,10 @@ int read_config(char *configfile, changer_t *chg)
           break;
         case CHANGERIDENT:
           chg->conf[drivenum].changerident = stralloc(value);
+         if (drivenum < 0 || drivenum > 100) {
+           fprintf(stderr,"drivenum %d is bad\n", drivenum);
+           drivenum = 0;
+         }
           p = chg->conf[drivenum].changerident;
           while (*p != '\0')
           {
@@ -390,8 +417,12 @@ int read_config(char *configfile, changer_t *chg)
           break;
         case DRIVE:
           drivenum = atoi(value);
-          if(drivenum >= numconf){
+          if (drivenum < 0) {
+            fprintf(stderr,"Error: drive must be >= 0\n");
+           drivenum = 0;
+          } else if (drivenum >= numconf) {
             fprintf(stderr,"Error: drive must be less than number_drives\n");
+           drivenum = numconf;
           }
           break;
         case DRIVENUM:
@@ -477,16 +508,19 @@ int read_config(char *configfile, changer_t *chg)
  *  we use a file to store the current slot.  It is not ideal
  *  but it gets the job done  
  */
-int get_current_slot(char *count_file)
+int
+get_current_slot(
+    char *count_file)
 {
   FILE *inf;
-  int retval;
+  int retval = -1;
   int ret;          /* return value for the fscanf function */
   if ((inf=fopen(count_file,"r")) == NULL) {
     fprintf(stderr, "%s: unable to open (%s)\n",
             get_pname(), count_file);
     exit(2);
   }
+
   ret = fscanf(inf,"%d",&retval);
   fclose(inf);
   
@@ -499,13 +533,22 @@ int get_current_slot(char *count_file)
       retval = -1;
     }
 
+  if (retval < 0 || retval > 10000) {
+    retval = -1;
+  }
   return retval;
 }
 
-void put_current_slot(char *count_file,int slot)
+void
+put_current_slot(
+    char *count_file,
+    int slot)
 {
   FILE *inf;
 
+  if (!count_file)
+    return;
+
   if ((inf=fopen(count_file,"w")) == NULL) {
     fprintf(stderr, "%s: unable to open current slot file (%s)\n",
             get_pname(), count_file);
@@ -528,18 +571,21 @@ void put_current_slot(char *count_file,int slot)
  * The passed struct MBC_T will hold the found entry in the DB
  */
 
-int MapBarCode(char *labelfile, MBC_T *result)
+int
+MapBarCode(
+    char *labelfile,
+    MBC_T *result)
 {
   FILE *fp;
   int version;
   LabelV2_T *plabelv2;
-  int unusedpos = 0;
+  long unusedpos= 0;
   int unusedrec = 0;
-  int pos     = 0;
-  int record  = 0;
-  int volseen = 0;
-  int loop    = 1;
-  int rsize   = 0;
+  int record    = 0;
+  int loop      = 1;
+  size_t rsize;
+  long pos;
+  int rc;
 
   DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : Parameter\n");
   DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"labelfile -> %s, vol -> %s, barcode -> %s, action -> %c, slot -> %d, from -> %d\n",
@@ -554,6 +600,7 @@ int MapBarCode(char *labelfile, MBC_T *result)
     {
       DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"Got empty labelfile (NULL)\n");
       ChgExit("MapBarCode", "MapBarCode name of labelfile is not set\n",FATAL);
+      /*NOTREACHED*/
     }
   if (access(labelfile, F_OK) == -1)
     {
@@ -562,6 +609,7 @@ int MapBarCode(char *labelfile, MBC_T *result)
         {
           DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE," failed\n");
           ChgExit("MapBarCode", "MapBarCode, creating labelfile failed\n", FATAL);
+         /*NOTREACHED*/
         }
       fprintf(fp,":%d:", LABEL_DB_VERSION);
       fclose(fp);
@@ -571,29 +619,35 @@ int MapBarCode(char *labelfile, MBC_T *result)
     {
        DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"MapBarCode : failed to open %s\n", labelfile);
        ChgExit("MapBarCode", "MapBarCode, opening labelfile for read/write failed\n", FATAL);
+       /*NOTREACHED*/
     }
   
-  fscanf(fp,":%d:", &version);
+  if (fscanf(fp,":%d:", &version) != 1) {
+     ChgExit("MapBarCode", "MapBarCode, DB Version unreadable.\n", FATAL);
+     /*NOTREACHED*/
+  }
   DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : DB version %d\n", version);
   
   pos = ftell(fp);
   if (version != LABEL_DB_VERSION)
     {
       ChgExit("MapBarCode", "MapBarCode, DB Version does not match\n", FATAL);
+      /*NOTREACHED*/
     }
 
-  if (( plabelv2 = (LabelV2_T *)malloc(sizeof(LabelV2_T))) == NULL)
+  if (( plabelv2 = (LabelV2_T *)alloc(SIZEOF(LabelV2_T))) == NULL)
     {
-      DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"MapBarCode : malloc failed\n");
-      ChgExit("MapBarCode", "MapBarCode malloc failed\n", FATAL);
+      DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"MapBarCode : alloc failed\n");
+      ChgExit("MapBarCode", "MapBarCode alloc failed\n", FATAL);
+      /*NOTREACHED*/
     }
   
-  memset(plabelv2, 0, sizeof(LabelV2_T));
+  memset(plabelv2, 0, SIZEOF(LabelV2_T));
 
   while(feof(fp) == 0 && loop == 1)
     {
-      rsize = fread(plabelv2, 1, sizeof(LabelV2_T), fp);
-      if (rsize == sizeof(LabelV2_T))
+      rsize = fread(plabelv2, 1, SIZEOF(LabelV2_T), fp);
+      if (rsize == SIZEOF(LabelV2_T))
       {
       record++;
       DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : (%d) VolTag \"%s\", BarCode %s, inuse %d, slot %d, from %d, loadcount %d\n",record,
@@ -609,7 +663,7 @@ int MapBarCode(char *labelfile, MBC_T *result)
            * Only dump the info
            */ 
         case BARCODE_DUMP:
-          printf("Slot -> %d, from -> %d, valid -> %d, Tag -> %s, Barcode -> %s, Loadcount %d\n",
+          printf("Slot -> %d, from -> %d, valid -> %d, Tag -> %s, Barcode -> %s, Loadcount %u\n",
                  plabelv2->slot,
                  plabelv2->from,
                  plabelv2->valid,
@@ -622,9 +676,17 @@ int MapBarCode(char *labelfile, MBC_T *result)
            * Set all the record to invalid, used by the Inventory function
            */
         case RESET_VALID:
-          fseek(fp, pos, SEEK_SET);
           plabelv2->valid = 0;
-          fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+          if (fseek(fp, pos, SEEK_SET) == -1) {
+           fclose(fp);
+           amfree(plabelv2);
+           return 0; /* Fail */
+         }
+          if (fwrite(plabelv2, 1, SIZEOF(LabelV2_T), fp) < SIZEOF(LabelV2_T)) {
+           fclose(fp);
+           amfree(plabelv2);
+           return 0; /* Fail */
+         }
           break;
           /*
            * Add an entry
@@ -642,32 +704,31 @@ int MapBarCode(char *labelfile, MBC_T *result)
                  unusedrec = record;
             }
 
-          /*
-           * Hmm whats that ?
-           */
-          if (strcmp(plabelv2->voltag, result->data.voltag) == 0)
-            {
-              volseen = record;
-            }
-          
           /*
            * OK this record matches the barcode label
            * so use/update it
            */
           if (strcmp(plabelv2->barcode, result->data.barcode) == 0)
             {
+
               DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : update entry\n");
-              fseek(fp, pos, SEEK_SET);
+             if (fseek(fp, pos, SEEK_SET) == -1) {
+               fclose(fp);
+               amfree(plabelv2);
+               return 0; /* Fail */
+             }
               plabelv2->valid = 1;
               plabelv2->from = result->data.from;
               plabelv2->slot = result->data.slot;
               plabelv2->LoadCount = plabelv2->LoadCount + result->data.LoadCount;
-              strcpy(plabelv2->voltag, result->data.voltag);
-              strcpy(plabelv2->barcode, result->data.barcode);
-              fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+              strncpy(plabelv2->voltag, result->data.voltag,
+                     SIZEOF(plabelv2->voltag));
+              strncpy(plabelv2->barcode, result->data.barcode,
+                     SIZEOF(plabelv2->barcode));
+              rc = (fwrite(plabelv2, 1, SIZEOF(LabelV2_T), fp) < SIZEOF(LabelV2_T));
               fclose(fp);
-             free(plabelv2);
-              return(1);
+             amfree(plabelv2);
+              return(rc);
             }
           break;
           /*
@@ -678,8 +739,8 @@ int MapBarCode(char *labelfile, MBC_T *result)
           if (strcmp(plabelv2->voltag, result->data.voltag) == 0)
             {
               DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode FIND_SLOT : \n");
-              memcpy(&(result->data), plabelv2, sizeof(LabelV2_T));
-             free(plabelv2);
+              memcpy(&(result->data), plabelv2, SIZEOF(LabelV2_T));
+             amfree(plabelv2);
               return(1);
            }
           break;
@@ -692,17 +753,23 @@ int MapBarCode(char *labelfile, MBC_T *result)
           if (strcmp(plabelv2->voltag, result->data.voltag) == 0)
             {
               DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode UPDATE_SLOT : update entry\n");
-              fseek(fp, pos, SEEK_SET);
-              strcpy(plabelv2->voltag, result->data.voltag);
-              strcpy(plabelv2->barcode, result->data.barcode);
+             if (fseek(fp, pos, SEEK_SET) == -1) {
+               fclose(fp);
+               amfree(plabelv2);
+               return 0; /* Fail */
+             }
+              strncpy(plabelv2->voltag, result->data.voltag,
+                    SIZEOF(plabelv2->voltag));
+              strncpy(plabelv2->barcode, result->data.barcode,
+                    SIZEOF(plabelv2->barcode));
               plabelv2->valid = 1;
               plabelv2->slot = result->data.slot;
               plabelv2->from = result->data.from;
               plabelv2->LoadCount = plabelv2->LoadCount + result->data.LoadCount;
-              fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+              rc = (fwrite(plabelv2, 1, SIZEOF(LabelV2_T), fp) < SIZEOF(LabelV2_T));
               fclose(fp);
-             free(plabelv2);
-              return(1);
+             amfree(plabelv2);
+              return(rc);
             }
           break;
           /*
@@ -720,8 +787,8 @@ int MapBarCode(char *labelfile, MBC_T *result)
               DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : VOL %s match\n", result->data.voltag);
               fclose(fp);
               
-              memcpy(&(result->data), plabelv2, sizeof(LabelV2_T));
-             free(plabelv2);
+              memcpy(&(result->data), plabelv2, SIZEOF(LabelV2_T));
+             amfree(plabelv2);
               return(1);
             }
           break;
@@ -735,8 +802,8 @@ int MapBarCode(char *labelfile, MBC_T *result)
               DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : BARCODE %s match\n", result->data.barcode);
               fclose(fp);
               
-              memcpy(&(result->data), plabelv2, sizeof(LabelV2_T));
-             free(plabelv2);
+              memcpy(&(result->data), plabelv2, SIZEOF(LabelV2_T));
+             amfree(plabelv2);
               return(1);
             }
           break;
@@ -748,7 +815,7 @@ int MapBarCode(char *labelfile, MBC_T *result)
       pos = ftell(fp);
       } else {
          DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : feof (%d)\n", feof(fp));
-         DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : error in read record expect %d, got %d\n",sizeof(LabelV2_T), rsize);
+         DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : error in read record expect %d, got %d\n",SIZEOF(LabelV2_T), rsize);
        loop=0;
       }
     }
@@ -768,22 +835,28 @@ int MapBarCode(char *labelfile, MBC_T *result)
       if (unusedpos != 0)
         {
           DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : reuse record %d\n", unusedrec);
-          fseek(fp, unusedpos, SEEK_SET);
+          if (fseek(fp, unusedpos, SEEK_SET) == -1) {
+           fclose(fp);
+           amfree(plabelv2);
+           return 0; /* Fail */
+         }
         }
       /*
        * Set all values to zero
        */
-      memset(plabelv2, 0, sizeof(LabelV2_T));     
+      memset(plabelv2, 0, SIZEOF(LabelV2_T));     
 
-      strcpy(plabelv2->voltag, result->data.voltag);
-      strncpy(plabelv2->barcode, result->data.barcode, TAG_SIZE);
+      strncpy(plabelv2->voltag, result->data.voltag,
+             SIZEOF(plabelv2->voltag));
+      strncpy(plabelv2->barcode, result->data.barcode,
+             SIZEOF(plabelv2->barcode));
       plabelv2->valid = 1;
       plabelv2->from = result->data.from;
       plabelv2->slot = result->data.slot;
-      fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+      rc = (fwrite(plabelv2, 1, SIZEOF(LabelV2_T), fp) < SIZEOF(LabelV2_T));
       fclose(fp);
-      free(plabelv2);
-      return(1);
+      amfree(plabelv2);
+      return(rc);
     }
 
   /*
@@ -791,7 +864,7 @@ int MapBarCode(char *labelfile, MBC_T *result)
    * found, so return an 0
    */
   fclose(fp);
-  free(plabelv2);
+  amfree(plabelv2);
   return(0);
 }
 
@@ -812,6 +885,7 @@ typedef struct com_stru
   char *parameter;
 } command;
 
+void parse_args(int argc, char *argv[],command *rval);
 
 /* major command line args */
 #define COMCOUNT 13
@@ -858,9 +932,12 @@ argument slotdefs[]={{"current",SLOT_CUR,0},
                      {"last",SLOT_LAST,0},
                      {"advance",SLOT_ADVANCE,0},
        };
-#define SLOTCOUNT (sizeof(slotdefs) / sizeof(slotdefs[0]))
+#define SLOTCOUNT (int)(sizeof(slotdefs) / sizeof(slotdefs[0]))
 
-int is_positive_number(char *tmp) /* is the string a valid positive int? */
+/* is the string a valid positive int? */
+int
+is_positive_number(
+    char *tmp)
 {
   int i=0;
   if ((tmp==NULL)||(tmp[0]==0))
@@ -873,7 +950,9 @@ int is_positive_number(char *tmp) /* is the string a valid positive int? */
     return 0;
 }
 
-void usage(char *argv[])
+void
+usage(
+    char *argv[])
 {
   int cnt;
   printf("%s: Usage error.\n", argv[0]);
@@ -888,9 +967,14 @@ void usage(char *argv[])
 }
 
 
-void parse_args(int argc, char *argv[],command *rval)
+void
+parse_args(
+    int argc,
+    char *argv[],
+    command *rval)
 {
-  int i=0;
+  int i;
+
   for (i=0; i < argc; i++)
     dbprintf(("ARG [%d] : %s\n", i, argv[i]));
   i = 0;
@@ -914,55 +998,64 @@ void parse_args(int argc, char *argv[],command *rval)
 }
 
 /* used to find actual slot number from keywords next, prev, first, etc */
-int get_relative_target(int fd,int nslots,char *parameter,int param_index,
-                       int loaded,char *slot_file,
-                       int slot_offset,int maxslot)
+int
+get_relative_target(
+    int fd,
+    int nslots,
+    char *parameter,
+    int param_index,
+    int loaded,
+    char *slot_file,
+    int slot_offset,
+    int maxslot)
 {
   int current_slot;
   
+  (void)loaded;        /* Quiet unused parameter warning */
+
   current_slot = get_current_slot(slot_file);
 
-  if (current_slot > maxslot){
+  if (current_slot > maxslot) {
     current_slot = slot_offset;
   }
-  if (current_slot < slot_offset){
+  if (current_slot < slot_offset) {
     current_slot = slot_offset;
   }
 
   switch(param_index) {
   case SLOT_CUR:
     return current_slot;
-    break;
+
   case SLOT_NEXT:
   case SLOT_ADVANCE:
     if (++current_slot==nslots+slot_offset)
       return slot_offset;
-    else
-      return current_slot;
-    break;
+    return current_slot;
+
   case SLOT_PREV:
     if (--current_slot<slot_offset)
       return maxslot;
-    else
-      return current_slot;
-    break;
+    return current_slot;
+
   case SLOT_FIRST:
     return slot_offset;
-    break;
+
   case SLOT_LAST:
     return maxslot;
-    break;
+
   default: 
-    printf("<none> no slot `%s'\n",parameter);
-    close(fd);
-    exit(2);
     break;
-  };
-  return(-1); /* never executed */
+  }
+  printf("<none> no slot `%s'\n",parameter);
+  close(fd);
+  exit(2);
+  /*NOTREACHED*/
 }
 
-int ask_clean(char *tapedev)
-     /* This function should ask the drive if it wants to be cleaned */
+/* This function should ask the drive if it wants to be cleaned */
+int
+ask_clean(
+    char *tapedev)
 {
   int ret;
 
@@ -975,32 +1068,50 @@ int ask_clean(char *tapedev)
   return ret;
 }
 
-void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum, 
-                int cleancart, int maxclean,char *usagetime)
-     /* This function should move the cleaning cartridge into the drive */
+/* This function should move the cleaning cartridge into the drive */
+void
+clean_tape(
+    int fd,
+    char *tapedev,
+    char *cnt_file,
+    int drivenum, 
+    int cleancart,
+    int maxclean,
+    char *usagetime)
 {
-  int counter=-1;
+  int counter;
+
   if (cleancart == -1 ){
     return;
   }
+
   /* Now we should increment the counter */
   if (cnt_file != NULL){
     counter = get_current_slot(cnt_file);
     counter++;
     if (counter>=maxclean){
       /* Now we should inform the administrator */
-      char *mail_cmd;
-      FILE *mailf;
-      mail_cmd = vstralloc(MAILER,
+      char *mail_cmd = NULL;
+      FILE *mailf = NULL;
+      int mail_pipe_opened = 1;
+      if(getconf_seen(CNF_MAILTO) && strlen(getconf_str(CNF_MAILTO)) > 0 &&
+         validate_mailto(getconf_str(CNF_MAILTO))) {
+        mail_cmd = vstralloc(MAILER,
                            " -s", " \"", "AMANDA PROBLEM: PLEASE FIX", "\"",
                            " ", getconf_str(CNF_MAILTO),
                            NULL);
-      if((mailf = popen(mail_cmd, "w")) == NULL){
-        error("could not open pipe to \"%s\": %s",
-              mail_cmd, strerror(errno));
-        printf("Mail failed\n");
-        return;
+        if((mailf = popen(mail_cmd, "w")) == NULL){
+               printf("Mail failed\n");
+               error("could not open pipe to \"%s\": %s",
+               mail_cmd, strerror(errno));
+               /*NOTREACHED*/
+       }
       }
+      else {
+       mail_pipe_opened = 0;
+        mailf = stderr;
+        fprintf(mailf, "\nNo mail recipient specified, output redirected to stderr");
+      }   
       fprintf(mailf,"\nThe usage count of your cleaning tape in slot %d",
               cleancart);
       fprintf(mailf,"\nis more than %d. (cleanmax)",maxclean);
@@ -1008,12 +1119,13 @@ void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum,
       fprintf(mailf,"\nPlease insert a new cleaning tape and reset");
       fprintf(mailf,"\nthe countingfile %s",cnt_file);
 
-      if(pclose(mailf) != 0)
-        error("mail command failed: %s", mail_cmd);
-
+      if(mail_pipe_opened == 1 && pclose(mailf) != 0) {
+               error("mail command failed: %s", mail_cmd);
+       /*NOTREACHED*/
+      }
       return;
     }
-    put_current_slot(cnt_file,counter);
+    put_current_slot(cnt_file, counter);
   }
   load(fd,drivenum,cleancart);
   /*
@@ -1023,32 +1135,36 @@ void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum,
   sleep(60);
 
   if (drive_loaded(fd, drivenum))
-    unload(fd,drivenum,cleancart);  
-  unlink(usagetime);
+    unload(fd, drivenum, cleancart);  
+  if (usagetime)
+    unlink(usagetime);
 }
 /* ----------------------------------------------------------------------*/
 
-int main(int argc, char *argv[])
+int
+main(
+    int argc,
+    char *argv[])
 {
-  int loaded,target,oldtarget;
+  int loaded;
+  int target, oldtarget;
   command com;   /* a little DOS joke */
   int x;
-
-  MBC_T *pbarcoderes = malloc(sizeof(MBC_T));
+  MBC_T *pbarcoderes;
   /*
    * drive_num really should be something from the config file, but..
    * for now, it is set to zero, since most of the common changers
    * used by amanda only have one drive ( until someone wants to 
    * use an EXB60/120, or a Breece Hill Q45.. )
    */
-  unsigned char emubarcode = 0;
-  int drive_num = 0;
-  int need_eject = 0; /* Does the drive need an eject command ? */
-  int need_sleep = 0; /* How many seconds to wait for the drive to get ready */
+  unsigned char emubarcode;
+  int drive_num;
+  int need_eject; /* Does the drive need an eject command ? */
+  time_t need_sleep; /* How many seconds to wait for the drive to get ready */
 
-  int maxclean = 0;
-  char *clean_file=NULL;
-  char *time_file=NULL;
+  int maxclean;
+  char *clean_file;
+  char *time_file;
 
   /*
    * For the emubarcode stuff
@@ -1057,27 +1173,32 @@ int main(int argc, char *argv[])
   int slot_offset;
   int confnum;
 
-  int fd, slotcnt, drivecnt;
+  int fd;
+  int slotcnt;
+  int drivecnt;
   int endstatus = 0;
 
-  char *changer_dev    = NULL;
-  char *tape_device    = NULL;
-  char *chg_scsi_conf  = NULL;          /* The config file for us */
-  char *slot_file      = NULL;          /* Where we will place the info which
+  char *changer_dev;
+  char *tape_device;
+  char *chg_scsi_conf;          /* The config file for us */
+  char *slot_file;             /* Where we will place the info which
                                          * slot is loaded
                                          */
-  char *scsitapedevice = NULL;
+  char *scsitapedevice;
 
   int param_index = 0;
 
-  memset(pbarcoderes, 0 , sizeof(MBC_T));
-  chg.number_of_configs = 0;
-  chg.eject = 0;
-  chg.sleep = 0;
-  chg.cleanmax = 0;
-  chg.device = NULL;
-  chg.labelfile = NULL;
-  chg.conf = NULL;
+  changer = alloc(SIZEOF(changer_t));
+  pbarcoderes = alloc(SIZEOF(MBC_T));
+
+  memset(pbarcoderes, 0 , SIZEOF(MBC_T));
+  changer->number_of_configs = 0;
+  changer->eject = 0;
+  changer->sleep = 0;
+  changer->cleanmax = 0;
+  changer->device = NULL;
+  changer->labelfile = NULL;
+  changer->conf = NULL;
 #ifdef CHG_SCSI_STANDALONE
   printf("Ups standalone\n");
 #else
@@ -1086,9 +1207,9 @@ int main(int argc, char *argv[])
   /* Don't die when child closes pipe */
   signal(SIGPIPE, SIG_IGN);
 
-  dbopen();
+  dbopen(DBG_SUBDIR_SERVER);
 
-  dbprintf(("chg-scsi: %s\n",rcsid));
+  dbprintf(("chg-scsi: %s\n", rcsid));
   ChangerDriverVersion();
 
   if (debug_file == NULL)
@@ -1098,8 +1219,8 @@ int main(int argc, char *argv[])
   
   parse_args(argc,argv,&com);
 
-  pDev = (OpenFiles_T *)malloc(sizeof(OpenFiles_T) * CHG_MAXDEV);
-  memset(pDev, 0, sizeof(OpenFiles_T) * CHG_MAXDEV );
+  pDev = (OpenFiles_T *)alloc(SIZEOF(OpenFiles_T) * CHG_MAXDEV);
+  memset(pDev, 0, SIZEOF(OpenFiles_T) * CHG_MAXDEV );
 
 
   switch(com.command_code) 
@@ -1107,12 +1228,12 @@ int main(int argc, char *argv[])
     case COM_SCAN:
       ScanBus(1);
       return(0);
-      break;
+
     case COM_GEN_CONF:
       ScanBus(0);
       PrintConf();
       return(0);
-      break;
+
     default:
       break;
     }
@@ -1120,6 +1241,7 @@ int main(int argc, char *argv[])
   if(read_conffile(CONFFILE_NAME)) {
     perror(CONFFILE_NAME);
     exit(1);
+    /*NOTREACHED*/
   }
 
   chg_scsi_conf = getconf_str(CNF_CHNGRFILE);
@@ -1129,51 +1251,70 @@ int main(int argc, char *argv[])
   /* Attention, this will not support more than 10 tape devices 0-9 */
   /* */
   if (strlen(tape_device)==1){
-    if (read_config(chg_scsi_conf,&chg) == -1)
+    if (read_config(chg_scsi_conf, changer) == -1)
     {
       fprintf(stderr, "%s open: of %s failed\n", get_pname(), chg_scsi_conf);
-      return 2;
+      return (2);
     }
     confnum=atoi(tape_device);
-    if (chg.number_of_configs == 0)
+    if (changer->number_of_configs == 0)
     {
-       fprintf(stderr,"%s: chg.conf[%d] == NULL\n",get_pname(), confnum);
-       return(2);
+       fprintf(stderr,"%s: changer->conf[%d] == NULL\n",
+               get_pname(), confnum);
+       return (2);
+    }
+    if (confnum >= changer->number_of_configs) {
+       fprintf(stderr,"%s: Configuration %s config # out of range (%d >= %d)\n",
+               get_pname(), chg_scsi_conf,
+               confnum, 
+               changer->number_of_configs);
+       return (2);
     }
-    use_slots    = chg.conf[confnum].end-chg.conf[confnum].start+1;
-    slot_offset  = chg.conf[confnum].start;
-    drive_num    = chg.conf[confnum].drivenum;
-    need_eject   = chg.eject;
-    need_sleep   = chg.sleep;
-
-    if ( NULL != chg.conf[confnum].cleanfile)
-      clean_file   = stralloc(chg.conf[confnum].cleanfile);
+
+    use_slots    = changer->conf[confnum].end-changer->conf[confnum].start+1;
+    slot_offset  = changer->conf[confnum].start;
+    drive_num    = changer->conf[confnum].drivenum;
+    need_eject   = changer->eject;
+    need_sleep   = changer->sleep;
+
+    if ( NULL != changer->conf[confnum].cleanfile)
+      clean_file   = stralloc(changer->conf[confnum].cleanfile);
     else
       clean_file = NULL;
 
-    clean_slot   = chg.conf[confnum].cleanslot;
-    maxclean     = chg.cleanmax;
-    emubarcode   = chg.emubarcode;
-    if (NULL != chg.conf[confnum].timefile)
-      time_file = stralloc(chg.conf[confnum].timefile);
+    clean_slot   = changer->conf[confnum].cleanslot;
+    maxclean     = changer->cleanmax;
+    emubarcode   = changer->emubarcode;
+    if (NULL != changer->conf[confnum].timefile)
+      time_file = stralloc(changer->conf[confnum].timefile);
+    else
+      time_file = NULL;
 
-    if (NULL != chg.conf[confnum].slotfile)
-      slot_file = stralloc(chg.conf[confnum].slotfile);
+    if (NULL != changer->conf[confnum].slotfile)
+      slot_file = stralloc(changer->conf[confnum].slotfile);
     else
       slot_file = NULL;
 
-    if (NULL != chg.conf[confnum].device)
-      tape_device  = stralloc(chg.conf[confnum].device);
+    if (NULL != changer->conf[confnum].device)
+      tape_device  = stralloc(changer->conf[confnum].device);
+    else
+      tape_device = NULL;
 
-    if (NULL != chg.device)
-      changer_dev  = stralloc(chg.device); 
+    if (NULL != changer->device)
+      changer_dev  = stralloc(changer->device); 
+    else
+      changer_dev = NULL;
 
-    if (NULL != chg.conf[confnum].scsitapedev)
-      scsitapedevice = stralloc(chg.conf[confnum].scsitapedev);
+    if (NULL != changer->conf[confnum].scsitapedev)
+      scsitapedevice = stralloc(changer->conf[confnum].scsitapedev);
+    else
+      scsitapedevice = NULL;
 
-    if (NULL != chg.conf[confnum].tapestatfile)
-      tapestatfile = stralloc(chg.conf[confnum].tapestatfile);
-    dump_changer_struct(chg);
+    if (NULL != changer->conf[confnum].tapestatfile)
+      tapestatfile = stralloc(changer->conf[confnum].tapestatfile);
+    else
+      tapestatfile = NULL;
+    dump_changer_struct(changer);
 
 
 
@@ -1182,7 +1323,7 @@ int main(int argc, char *argv[])
      * If we can't open it fail with a message
      */
 
-    if (OpenDevice(INDEX_CHANGER , changer_dev, "changer_dev", chg.conf[confnum].changerident) == 0)
+    if (OpenDevice(INDEX_CHANGER , changer_dev, "changer_dev", changer->conf[confnum].changerident) == 0)
       {
         int localerr = errno;
         fprintf(stderr, "%s: open: %s: %s\n", get_pname(), 
@@ -1203,7 +1344,7 @@ int main(int argc, char *argv[])
      */
     if (tape_device != NULL)
       {
-        if (OpenDevice(INDEX_TAPE, tape_device, "tape_device", chg.conf[confnum].tapeident) == 0)
+        if (OpenDevice(INDEX_TAPE, tape_device, "tape_device", changer->conf[confnum].tapeident) == 0)
           {
             dbprintf(("warning open of %s: failed\n",  tape_device));
           }
@@ -1214,7 +1355,7 @@ int main(int argc, char *argv[])
      */
     if (scsitapedevice != NULL)
       {
-        if (OpenDevice(INDEX_TAPECTL, scsitapedevice, "scsitapedevice", chg.conf[confnum].tapeident) == 0)
+        if (OpenDevice(INDEX_TAPECTL, scsitapedevice, "scsitapedevice", changer->conf[confnum].tapeident) == 0)
           {
             dbprintf(("warning open of %s: failed\n", scsitapedevice));
           }
@@ -1236,7 +1377,7 @@ int main(int argc, char *argv[])
       }
 
        
-    if ((chg.conf[confnum].end == -1) || (chg.conf[confnum].start == -1)){
+    if ((changer->conf[confnum].end == -1) || (changer->conf[confnum].start == -1)){
       slotcnt = get_slot_count(fd);
       use_slots    = slotcnt;
       slot_offset  = 0;
@@ -1248,9 +1389,9 @@ int main(int argc, char *argv[])
      * we need an label file
      */
     
-    if ( chg.emubarcode == 1 || BarCode(INDEX_CHANGER) == 1) 
+    if ( changer->emubarcode == 1 || BarCode(INDEX_CHANGER) == 1) 
       {
-        if (chg.labelfile == NULL)
+        if (changer->labelfile == NULL)
           {
             printf("labelfile param not set in your config\n");
             return(2);
@@ -1288,7 +1429,7 @@ int main(int argc, char *argv[])
     return 2;
   }
 
-  loaded = drive_loaded(fd, drive_num);
+  loaded = (int)drive_loaded(fd, drive_num);
   target = -1;
 
   switch(com.command_code) {
@@ -1300,22 +1441,26 @@ int main(int argc, char *argv[])
 */
   case COM_DUMPDB:
     pbarcoderes->action = BARCODE_DUMP;
-    MapBarCode(chg.labelfile, pbarcoderes);
+    MapBarCode(changer->labelfile, pbarcoderes);
     break;
   case COM_STATUS:
-    ChangerStatus(com.parameter, chg.labelfile, BarCode(fd),slot_file, changer_dev, tape_device);
+    ChangerStatus(com.parameter, changer->labelfile,
+               BarCode(fd), slot_file, changer_dev, tape_device);
     break;
   case COM_LABEL: /* Update BarCode/Label mapping file */
     pbarcoderes->action = BARCODE_PUT;
     pbarcoderes->data.from = pbarcoderes->data.slot = get_current_slot(slot_file);
-    strcpy(pbarcoderes->data.voltag, com.parameter);
+    strncpy(pbarcoderes->data.voltag, com.parameter,
+          SIZEOF(pbarcoderes->data.voltag));
     if (BarCode(fd) == 1 && emubarcode != 1)
     {
-       strcpy( pbarcoderes->data.barcode, pDTE[drive_num].VolTag);
+       strncpy(pbarcoderes->data.barcode, pDTE[drive_num].VolTag,
+          SIZEOF(pbarcoderes->data.barcode));
     } else {
-       strcpy( pbarcoderes->data.barcode, com.parameter);
+       strncpy(pbarcoderes->data.barcode, com.parameter,
+          SIZEOF(pbarcoderes->data.barcode));
     }
-    MapBarCode(chg.labelfile, pbarcoderes);
+    MapBarCode(changer->labelfile, pbarcoderes);
     printf("0 0 0\n");
     break;
 
@@ -1347,9 +1492,9 @@ int main(int argc, char *argv[])
         (void)unload(fd, drive_num, oldtarget);
         if (ask_clean(scsitapedevice))
           clean_tape(fd,tape_device,clean_file,drive_num,
-                     clean_slot,maxclean,time_file);
+                     clean_slot, maxclean, time_file);
       }
-    Inventory(chg.labelfile, drive_num, need_eject, 0, 0, clean_slot);
+    Inventory(changer->labelfile, drive_num, need_eject, 0, 0, clean_slot);
     do_inventory = 0;                        /* If set on exit the labeldb will be set to invalid ..... */
     break;
  
@@ -1367,8 +1512,9 @@ int main(int argc, char *argv[])
         dbprintf(("search : look for %s\n", com.parameter));
         pbarcoderes->action = BARCODE_VOL;
         pbarcoderes->data.slot = -1;
-        strcpy(pbarcoderes->data.voltag, com.parameter);
-        if (MapBarCode(chg.labelfile, pbarcoderes) == 1)
+        strncpy(pbarcoderes->data.voltag, com.parameter,
+              SIZEOF(pbarcoderes->data.voltag));
+        if (MapBarCode(changer->labelfile, pbarcoderes) == 1)
           {
             /*
              * If both values are unset we have an problem
@@ -1390,7 +1536,7 @@ int main(int argc, char *argv[])
             if (pbarcoderes->data.barcode != NULL)
               {
  
-                for (x = 0; x < STE; x++)
+                for (x = 0; x < (int)STE; x++)
                   {
                     if (strcmp(pSTE[x].VolTag, pbarcoderes->data.barcode) == 0)
                       {
@@ -1404,7 +1550,7 @@ int main(int argc, char *argv[])
                  * If we find it check if it is in the right drive
                  * if we have more than one drive.
                  */
-                for (x = 0; x < DTE; x++)
+                for (x = 0; x < (int)DTE; x++)
                   {
                     if (strcmp(pDTE[x].VolTag, pbarcoderes->data.barcode) == 0)
                       {
@@ -1413,7 +1559,7 @@ int main(int argc, char *argv[])
                          */
                         if (x == drive_num) {
                           oldtarget = get_current_slot(slot_file);
-                          printf("%d %s\n", oldtarget- slot_offset, tape_device);
+                          printf("%d %s\n", oldtarget - slot_offset, tape_device);
                           return(0);
                         } else {
                           printf("LABEL in wrong tape Unit\n");
@@ -1466,9 +1612,10 @@ int main(int argc, char *argv[])
         dbprintf(("search : look for %s\n", com.parameter));
         pbarcoderes->action = FIND_SLOT;
         pbarcoderes->data.slot = -1;
-        strcpy(pbarcoderes->data.voltag, com.parameter);
+        strncpy(pbarcoderes->data.voltag, com.parameter,
+              SIZEOF(pbarcoderes->data.voltag));
 
-        if (MapBarCode(chg.labelfile, pbarcoderes) == 1)
+        if (MapBarCode(changer->labelfile, pbarcoderes) == 1)
           {
             if (pbarcoderes->data.valid == 1)
               {
@@ -1500,19 +1647,20 @@ int main(int argc, char *argv[])
             endstatus = 2;
             break;
           } else {
-            target = target+slot_offset;
+            target = target + slot_offset;
           }
         } else {
           param_index=0;
-          while((param_index<SLOTCOUNT)
-               &&(strcmp(slotdefs[param_index].str,com.parameter))) {
+          while((param_index < SLOTCOUNT) &&
+               (strcmp(slotdefs[param_index].str,com.parameter))) {
             param_index++;
          }
           target=get_relative_target(fd, use_slots,
                                      com.parameter,param_index,
                                      loaded, 
                                      slot_file,
-                                    slot_offset,slot_offset+use_slots-1);
+                                    slot_offset,
+                                    (slot_offset + use_slots - 1));
         }
       }
 
@@ -1547,8 +1695,8 @@ int main(int argc, char *argv[])
 
         (void)unload(fd, drive_num, oldtarget);
         if (ask_clean(scsitapedevice))
-          clean_tape(fd,tape_device,clean_file,drive_num,
-                     clean_slot,maxclean,time_file);
+          clean_tape(fd, tape_device, clean_file, drive_num,
+                     clean_slot, maxclean, time_file);
         loaded=0;
       }
     }
@@ -1556,8 +1704,8 @@ int main(int argc, char *argv[])
     put_current_slot(slot_file, target);
     
     if (!loaded && isempty(fd, target)) {
-      printf("%d slot %d is empty\n",target-slot_offset,
-             target-slot_offset);
+      printf("%d slot %d is empty\n",target - slot_offset,
+             target - slot_offset);
       close(fd);
       endstatus = 1;
       break;
@@ -1566,11 +1714,11 @@ int main(int argc, char *argv[])
     if (!loaded && param_index != SLOT_ADVANCE)
       {
         if (ask_clean(scsitapedevice))
-          clean_tape(fd,tape_device,clean_file,drive_num,
-                     clean_slot,maxclean,time_file);
+          clean_tape(fd, tape_device, clean_file, drive_num,
+                     clean_slot, maxclean, time_file);
         if (load(fd, drive_num, target) != 0) {
-          printf("%d slot %d move failed\n",target-slot_offset,
-                 target-slot_offset);  
+          printf("%d slot %d move failed\n",target - slot_offset,
+                 target - slot_offset);  
           close(fd);
           endstatus = 2;
           break;
@@ -1597,17 +1745,17 @@ int main(int argc, char *argv[])
         }
       }
 
-    printf("%d %s\n", target-slot_offset, tape_device);
+    printf("%d %s\n", target - slot_offset, tape_device);
     break;
 
   case COM_INFO:
-    loaded = get_current_slot(slot_file);
+    loaded = (int)get_current_slot(slot_file);
 
     if (loaded < 0)
       {
         loaded = find_empty(fd, slot_offset, use_slots);
       }
-    loaded = loaded - slot_offset;
+    loaded = loaded - (int)slot_offset;
       
     printf("%d %d 1", loaded, use_slots);
 
@@ -1625,14 +1773,14 @@ int main(int argc, char *argv[])
     if (target < 0)
     {
       dbprintf(("COM_RESET: get_current_slot %d\n", target));
-      target=find_empty(fd, slot_offset, use_slots);
+      target = find_empty(fd, slot_offset, use_slots);
       dbprintf(("COM_RESET: find_empty %d\n", target));
     }
 
     if (loaded) {
       
       if (!isempty(fd, target))
-        target=find_empty(fd, slot_offset, use_slots);
+        target = find_empty(fd, slot_offset, use_slots);
       
       if (need_eject)
         {
@@ -1650,8 +1798,8 @@ int main(int argc, char *argv[])
       
       (void)unload(fd, drive_num, target);
       if (ask_clean(scsitapedevice))
-        clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
-                   maxclean,time_file);
+        clean_tape(fd,tape_device, clean_file, drive_num, clean_slot,
+                   maxclean, time_file);
     }
     
     if (isempty(fd, slot_offset)) {
@@ -1662,8 +1810,8 @@ int main(int argc, char *argv[])
     }
     
     if (load(fd, drive_num, slot_offset) != 0) {
-      printf("%d slot %d move failed\n",drive_num,
-             slot_offset);  
+      printf("%d slot %d move failed\n",
+            drive_num, slot_offset);  
       close(fd);
       put_current_slot(slot_file, slot_offset);
       endstatus = 2;
@@ -1697,7 +1845,7 @@ int main(int argc, char *argv[])
 
   case COM_EJECT:
     if (loaded) {
-      target=get_current_slot(slot_file);
+      target = get_current_slot(slot_file);
       if (target < 0)
         {
           dbprintf(("COM_EJECT: get_current_slot %d\n", target));
@@ -1718,8 +1866,8 @@ int main(int argc, char *argv[])
 
       (void)unload(fd, drive_num, target);
       if (ask_clean(scsitapedevice))
-        clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
-                   maxclean,time_file);
+        clean_tape(fd, tape_device, clean_file, drive_num, clean_slot,
+                   maxclean, time_file);
       printf("%d %s\n", target, tape_device);
     } else {
       printf("%d %s\n", target, "drive was not loaded");
@@ -1728,7 +1876,7 @@ int main(int argc, char *argv[])
     break;
   case COM_CLEAN:
     if (loaded) {
-      target=get_current_slot(slot_file);
+      target = get_current_slot(slot_file);
       if (target < 0)
         {
           dbprintf(("COM_CLEAN: get_current_slot %d\n", target));
@@ -1749,13 +1897,13 @@ int main(int argc, char *argv[])
       (void)unload(fd, drive_num, target);
     } 
 
-    clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
-               maxclean,time_file);
+    clean_tape(fd, tape_device, clean_file, drive_num, clean_slot,
+               maxclean, time_file);
     printf("%s cleaned\n", tape_device);
     break;
   };
 
-  /* FIX ME, should be an function to close the device */  
+/* FIX ME, should be an function to close the device */  
 /*   if (pChangerDev != NULL) */
 /*     close(pChangerDev->fd); */
  
@@ -1767,17 +1915,18 @@ int main(int argc, char *argv[])
 
 
 #endif
-  if (do_inventory == 1 && endstatus == 0 && chg.labelfile != NULL)
+  if (do_inventory == 1 && endstatus == 0 && changer->labelfile != NULL)
     {
-      if ( chg.autoinv == 1)
+      if (changer->autoinv == 1)
         {
           DebugPrint(DEBUG_INFO,SECTION_INFO, "Do an inventory \n");
-          Inventory(chg.labelfile, drive_num , chg.eject, 0, 0, clean_slot);
+          Inventory(changer->labelfile, drive_num, changer->eject,
+               0, 0, clean_slot);
         } else {
           DebugPrint(DEBUG_INFO,SECTION_INFO, "Set all entrys in DB to invalid\n");
-          memset(pbarcoderes, 0 , sizeof(MBC_T));
+          memset(pbarcoderes, 0 , SIZEOF(MBC_T));
           pbarcoderes->action = RESET_VALID;
-          MapBarCode(chg.labelfile,pbarcoderes);
+          MapBarCode(changer->labelfile,pbarcoderes);
         }
     }
 
@@ -1791,4 +1940,3 @@ int main(int argc, char *argv[])
  * tab-width: 4
  * End:
  */
-
index f0f0cbb3b8c1f29b263632254d373fdfd3385da4..52e750d18c284de18a6cf0d0b0f63aa30cb5ecbd 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh 
+#!@SHELL@ 
 #
 # Exit Status:
 # 0 Alles Ok
 # in amanda.conf.  For example, if amanda.conf has:
 #
 #      changerfile="/etc/amanda/Dailyset1/CHANGER"
+#    or changerfile="/etc/amanda/Dailyset1/CHANGER.conf"
 #
 # the variables must be in "/etc/amanda/Dailyset1/CHANGER.conf".
+# The ".conf" is appended only if it's not there".
 #
 # If "changerfile" is a relative path, it is relative to the directory
 # that contains amanda.conf.  That also happens to be the directory Amanda
@@ -632,20 +634,20 @@ else
        SUF=
 fi
 
-DBGFILE=`amgetconf$SUF dbopen.$argv0 2>/dev/null | grep -v BUGGY`
+DBGFILE=`amgetconf$SUF dbopen.$argv0 2>/dev/null`
 if [ -z "$DBGFILE" ]
 then
        DBGFILE=/dev/null                       # will try this again below
 fi
 
-changerfile=`amgetconf$SUF changerfile 2>/dev/null | grep -v BUGGY`
+changerfile=`amgetconf$SUF changerfile 2>/dev/null`
 if [ -z "$changerfile" ]; then
        Exit 2 \
             "<none>" \
             "changerfile must be specified in amanda.conf"
 fi
 
-tape=`amgetconf$SUF tapedev 2>/dev/null | grep -v BUGGY`
+tape=`amgetconf$SUF tapedev 2>/dev/null`
 if [ -z "$tape" ]; then
        Exit 2 \
             "<none>" \
@@ -655,7 +657,7 @@ elif [ $tape = "/dev/null" -o `expr "$tape" : 'null:'` -eq 5 ]; then
             "<none>" \
             "tapedev ($tape) may not be the null device"
 fi
-TAPE=`amgetconf$SUF changerdev 2>/dev/null | grep -v BUGGY`
+TAPE=`amgetconf$SUF changerdev 2>/dev/null`
 if [ -z "$TAPE" ]; then
        Exit 2 \
             "<none>" \
@@ -669,7 +671,14 @@ export TAPE                                        # for mtx command
 
 #### Set up the various config files.
 
-configfile=$changerfile.conf
+conf_match=`expr "$changerfile" : .\*\.conf\$`
+if [ $conf_match -ge 6 ]; then
+       configfile=$changerfile
+       changerfile=`echo $changerfile | sed 's/.conf$//g'`
+else
+       configfile=$changerfile.conf
+fi
+
 cleanfile=$changerfile-clean
 accessfile=$changerfile-access
 slotfile=$changerfile-slot
@@ -1141,9 +1150,7 @@ info() {
        if [ $currentslot -lt $firstslot -o $currentslot -gt $lastslot ]; then
                currentslot=$firstslot          # what "current" will get
        fi
-       set x $slot_list
-       shift                                   # get rid of the "x"
-       numslots=$#
+       numslots=`expr $lastslot - $firstslot + 1`
        Exit 0 "$currentslot" "$numslots 1 $reader"
        return $?                               # in case we are internal
 }
index e0fe00eaeb75e142965c131576b996b8a8c04e47..e0d190de92168cf89c3c2c0f1f882c06450923ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: libscsi.h,v 1.9 2000/06/25 18:48:11 ant Exp $
+ *     $Id: libscsi.h,v 1.10 2006/05/25 01:47:07 johnfranks Exp $
  *
  *     libscsi.h -- library header for routines to handle the changer
  *                     support for chio based systems
 /*
  * This function gets the actual cleaning state of the drive 
  */
-int get_clean_state P((char *tape));
+int get_clean_state(char *tape);
 
 /*
  * This function gets the next empty slot from the changer
  * (From this slot the tape is loaded ...)
  */
-int GetCurrentSlot P((int fd, int drive));
+int GetCurrentSlot(int fd, int drive);
 
 /*
  * Eject the actual tape from the tapedrive
  */
-void eject_tape P((char *tape, int type));
+int eject_tape(char *tape, int type);
 
 
 /* 
  * is the specified slot empty?
  */
-int isempty P((int fd, int slot));
+int isempty(int fd, int slot);
 
 /*
  * find the first empty slot 
  */
-int find_empty P((int fd, int start, int count));
+int find_empty(int fd, int start, int count);
 
 /*
  * returns one if there is a tape loaded in the drive 
  */
-int drive_loaded P((int fd, int drivenum));
+int drive_loaded(int fd, int drivenum);
 
 
 /*
  * unloads the drive, putting the tape in the specified slot 
  */
-int unload P((int fd, int drive, int slot));
+int unload(int fd, int drive, int slot);
 
 /*
  * moves tape from the specified slot into the drive 
  */
-int load P((int fd, int drive, int slot));
+int load(int fd, int drive, int slot);
 
 /* 
  * return the number of slots in the robot
  */
-int get_slot_count P((int fd));
+int get_slot_count(int fd);
 
 /*
  * return the number of drives in the robot
  */
-int get_drive_count P((int fd));
+int get_drive_count(int fd);
 
 #endif /* !LIBSCSI_H */
index 4696faf693c66d571d76a4b7a2adbd4aecf2a547..5e0dba86f44fa1aa1c4979d0d13e15c6292c8ef0 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-aix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-aix.c,v 1.23 2006/05/25 01:47:07 johnfranks Exp $
  *
  * Interface to execute SCSI commands on an AIX System
  *
@@ -36,6 +36,8 @@
 
 #ifdef HAVE_AIX_LIKE_SCSI
 
+#include <scsi-defs.h>
+
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
 #include <scsi-defs.h>
 #include <gscdds.h>
 
-void SCSI_OS_Version()
+void SCSI_OS_Version(void)
 {
 #ifndef lint
-   static char rcsid[] = "$Id: scsi-aix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $";
+   static char rcsid[] = "$Id: scsi-aix.c,v 1.23 2006/05/25 01:47:07 johnfranks Exp $";
    DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
 #endif
 }
@@ -126,12 +128,10 @@ int SCSI_OpenDevice(int ip)
                  free(pDev[ip].inquiry);
                  return(0);
                }
-           } else {
-             free(pDev[ip].inquiry);
-             pDev[ip].inquiry = NULL;
-             return(1);
            }
-        return(1);
+           free(pDev[ip].inquiry);
+           pDev[ip].inquiry = NULL;
+           return(1);
        } else {
         dbprintf(("SCSI_OpenDevice %s failed\n", pDev[ip].dev));
          return(0);
@@ -161,11 +161,11 @@ int SCSI_CloseDevice(int DeviceFD)
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *RequestSenseBuf,
-                        int RequestSenseLength)
+                        size_t DataBufferLength,
+                        RequestSense_T *RequestSenseBuf,
+                        size_t RequestSenseLength)
 {
   extern OpenFiles_T *pDev;
   extern FILE * debug_file;
@@ -179,6 +179,12 @@ int SCSI_ExecuteCommand(int DeviceFD,
   int isbusy = 0;
   int target = 3;
 
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
+  /* Clear buffer for cases where sense is not returned */
+  memset(RequestSenseBuf, 0, RequestSenseLength);
 
   if (pDev[DeviceFD].avail == 0)
     {
@@ -192,7 +198,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
       scmd.cdblen = CDB_Length;
       scmd.data_buf = DataBuffer;
       scmd.datalen = DataBufferLength;
-      scmd.sense_buf = RequestSenseBuf;
+      scmd.sense_buf = (unsigned char *)RequestSenseBuf;
       scmd.senselen = RequestSenseLength;
       scmd.statusp = &sbyte;
       scmd.timeval = 60;
@@ -212,9 +218,9 @@ int SCSI_ExecuteCommand(int DeviceFD,
       return(SCSI_OK);
 
     } else {
-      bzero(&ds, sizeof(struct sc_iocmd));
+      bzero(&ds, SIZEOF(struct sc_iocmd));
       bzero(RequestSenseBuf, RequestSenseLength);
-      bzero(&ExtendedRequestSense, sizeof(ExtendedRequestSense_T));
+      bzero(&ExtendedRequestSense, SIZEOF(ExtendedRequestSense_T));
       
       ds.flags = SC_ASYNC; 
       /* Timeout */
@@ -235,7 +241,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
       /* Sense Buffer is not available on AIX ?*/
       /*
         ds.req_sense_length = 255;
-        ds.request_sense_ptr = (char *)RequestSense;
+        ds.request_sense_ptr = (unsigned char *)RequestSense;
       */
       switch (Direction) 
         {
@@ -267,7 +273,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
               SINQ[5] = 0x80;
               bcopy(SINQ, ds.scsi_cdb, 6);
               ds.command_length = 6;
-              ds.buffer = RequestSenseBuf;
+              ds.buffer = (unsigned char *)RequestSenseBuf;
               ds.data_length = RequestSenseLength;
               
               if (pDev[DeviceFD].devopen == 0)
@@ -276,10 +282,10 @@ int SCSI_ExecuteCommand(int DeviceFD,
               Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);
               SCSI_CloseDevice(DeviceFD);
               return(SCSI_OK);
-              break;
+
             case SC_BUSY_STATUS:
               return(SCSI_BUSY);
-              break;
+
             case SC_CHECK_CONDITION:
               SINQ[0] = SC_COM_REQUEST_SENSE;
               SINQ[1] = 0; 
@@ -289,8 +295,8 @@ int SCSI_ExecuteCommand(int DeviceFD,
               SINQ[5] = 0x80;
               bcopy(SINQ, ds.scsi_cdb, 6);
               ds.command_length = 6;
-              ds.buffer = RequestSenseBuf;
-              ds.data_length = RequestSenseLength;
+              ds.buffer = (unsigned char *)RequestSenseBuf;
+              ds.data_length = (unsigned char)RequestSenseLength;
 
               if (pDev[DeviceFD].devopen == 0)
                 if (SCSI_OpenDevice(DeviceFD) == 0)
@@ -298,7 +304,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
               Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);
               SCSI_CloseDevice(DeviceFD);
               return(SCSI_CHECK);
-              break;
+
             default:
               /*
                * Makes no sense yet, may result in an endless loop
@@ -325,10 +331,9 @@ int SCSI_ExecuteCommand(int DeviceFD,
     }
 }
 
-int SCSI_Scan()
+int SCSI_Scan(void)
 {
   int fd;
-  extern int errno;
   struct sc_inquiry si;
   u_char buf[255];
   int target;
@@ -356,7 +361,7 @@ int SCSI_Scan()
             isbusy = 0;
           }
           
-          bzero(&si, sizeof(si));
+          bzero(&si, SIZEOF(si));
           si.scsi_id = target;
           si.lun_id = lun;
           si.inquiry_len = 255;
@@ -366,9 +371,9 @@ int SCSI_Scan()
               printf("SCIOINQU: %s\n", strerror(errno));
             } else {
               dump_hex(&buf, 255, DEBUG_INFO, SECTION_SCSI);
-              type = buf[0] & 0x1f;
+              type = buf[0] & 0x1lf;
               buf[8+28] = 0;
-              printf(stdout,"%-28s|Device Type %d\n",buf[8], type);
+              printf("%-28s|Device Type %d\n",buf[8], type);
             }
           if (!isbusy && ioctl(fd, SCIOSTOP, IDLUN(target, lun)) == -1)
             return(1);
index bd010667520414e007f6e1216eea7865ea2d3d26..0850c9e6f4ddebb278a980ee97b51ddcff67b58b 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-bsd.c,v 1.17 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-bsd.c,v 1.18 2006/05/25 01:47:07 johnfranks Exp $
  *
  * Interface to execute SCSI commands on an BSD System (FreeBSD)
  *
@@ -61,7 +61,7 @@
 void SCSI_OS_Version()
 {
 #ifndef lint
-   static char rcsid[] = "$Id: scsi-bsd.c,v 1.17 2005/10/15 13:20:47 martinea Exp $";
+   static char rcsid[] = "$Id: scsi-bsd.c,v 1.18 2006/05/25 01:47:07 johnfranks Exp $";
    DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
 #endif
 }
@@ -163,11 +163,11 @@ int SCSI_CloseDevice(int DeviceFD)
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *pRequestSense,
-                        int RequestSenseLength)
+                        size_t DataBufferLength,
+                        RequestSense_T *pRequestSense,
+                        size_t RequestSenseLength)
 {
   extern OpenFiles_T *pDev;
   ExtendedRequestSense_T ExtendedRequestSense;
@@ -176,14 +176,21 @@ int SCSI_ExecuteCommand(int DeviceFD,
   int retries = 5;
   extern int errno;
   
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
+  /* Clear buffer for cases where sense is not returned */
+  memset(pRequestSense, 0, RequestSenseLength);
+
   if (pDev[DeviceFD].avail == 0)
     {
       return(SCSI_ERROR);
     }
 
-  memset(&ds, 0, sizeof(scsireq_t));
+  memset(&ds, 0, SIZEOF(scsireq_t));
   memset(pRequestSense, 0, RequestSenseLength);
-  memset(&ExtendedRequestSense, 0 , sizeof(ExtendedRequestSense_T)); 
+  memset(&ExtendedRequestSense, 0 , SIZEOF(ExtendedRequestSense_T)); 
   
   ds.flags = SCCMD_ESCAPE; 
   /* Timeout */
@@ -224,7 +231,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
     memcpy(pRequestSense, ds.sense, RequestSenseLength);
     if (Result < 0)
       {
-        dbprintf(("errno : %d\n",errno));
+        dbprintf(("errno : %s\n",strerror(errno)));
         return (SCSI_ERROR);
       }
     dbprintf(("SCSI_ExecuteCommand(BSD) %02X STATUS(%02X) \n", CDB[0], ds.retsts));
@@ -232,12 +239,13 @@ int SCSI_ExecuteCommand(int DeviceFD,
       {
       case SCCMD_BUSY:                /*  BUSY */
         break;
+
       case SCCMD_OK:                /*  GOOD */
         return(SCSI_OK);
-        break;
+
       case SCCMD_SENSE:               /*  CHECK CONDITION */
         return(SCSI_SENSE);
-        break;
+
       default:
         continue;
       }
@@ -271,7 +279,7 @@ int Tape_Ioctl( int DeviceFD, int command)
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
     {
-      dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+      dbprintf(("Tape_Ioctl error ioctl %s\n",strerror(errno)));
       SCSI_CloseDevice(DeviceFD);
       return(-1);
     }
index e159b45facf8ab30b2f46051e2badf4f1deef105..9f0c497f1aa51272e20a77c2b1e319111722fe67 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-cam.c,v 1.14 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-cam.c,v 1.15 2006/05/25 01:47:07 johnfranks Exp $
  *
  * Interface to execute SCSI commands on an system with cam support
  * Current support is for FreeBSD 4.x
@@ -75,7 +75,7 @@ extern FILE *debug_file;
 void SCSI_OS_Version()
 {
 #ifndef lint
-   static char rcsid[] = "$Id: scsi-cam.c,v 1.14 2005/10/15 13:20:47 martinea Exp $";
+   static char rcsid[] = "$Id: scsi-cam.c,v 1.15 2006/05/25 01:47:07 johnfranks Exp $";
    DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
 #endif
 }
@@ -94,18 +94,33 @@ int parse_btl(char *DeviceName,
     return 0;
 
   p = strtok(DeviceName, ":");
-  sscanf(p,"%d", path);
+  if (sscanf(p,"%d", path) != 1) {
+      free(DeviceName);
+      ChgExit("SCSI_OpenDevice",
+       "Path conversion error. Digits expected", FATAL);
+  }
           
   if ((p = strtok(NULL,":")) == NULL) {
       free(DeviceName);
       ChgExit("SCSI_OpenDevice", "target in Device Name not found", FATAL);
   }
-  sscanf(p,"%d", target);
+
+  if (sscanf(p,"%d", target) != 1) {
+      free(DeviceName);
+      ChgExit("SCSI_OpenDevice",
+       "Target conversion error. Digits expected", FATAL);
+  }
+
   if ((p = strtok(NULL,":")) == NULL) {
       free(DeviceName);
       ChgExit("SCSI_OpenDevice", "lun in Device Name not found", FATAL);
   }
-  sscanf(p,"%d", lun);
+  if (sscanf(p,"%d", lun) != 1) {
+      free(DeviceName);
+      ChgExit("SCSI_OpenDevice",
+       "LUN conversion error. Digits expected", FATAL);
+  }
+
   return 1;
 }
 
@@ -179,22 +194,20 @@ int SCSI_OpenDevice(int ip)
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice open failed\n");
       return(0);
     }
-  } else {
-    if (parse_btl(DeviceName, &path, &target, &lun))
-        pDev[ip].curdev = cam_open_btl(path, target, lun, O_RDWR, NULL);
-    else
-        pDev[ip].curdev = cam_open_device(DeviceName, O_RDWR);
-
-    free(DeviceName);
-
-    if (pDev[ip].curdev) {
-      pDev[ip].devopen = 1;
-      return(1);
-    } else  {
-      return(0);
-    }
   }
-  return(0); 
+  if (parse_btl(DeviceName, &path, &target, &lun))
+      pDev[ip].curdev = cam_open_btl(path, target, lun, O_RDWR, NULL);
+  else
+      pDev[ip].curdev = cam_open_device(DeviceName, O_RDWR);
+
+  free(DeviceName);
+
+  if (pDev[ip].curdev) {
+    pDev[ip].devopen = 1;
+    return(1);
+  } else  {
+    return(0);
+  }
 }
 
 int SCSI_CloseDevice(int DeviceFD)
@@ -215,11 +228,11 @@ int SCSI_CloseDevice(int DeviceFD)
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *pRequestSense,
-                        int RequestSenseLength)
+                        size_t DataBufferLength,
+                        RequestSense_T *pRequestSense,
+                        size_t RequestSenseLength)
 {
   ExtendedRequestSense_T ExtendedRequestSense;
   extern OpenFiles_T *pDev;
@@ -228,6 +241,13 @@ int SCSI_ExecuteCommand(int DeviceFD,
   uint32_t ccb_flags;
   OpenFiles_T *pwork = NULL;
 
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
+  /* Clear buffer for cases where sense is not returned */
+  memset(pRequestSense, 0, RequestSenseLength);
+
   if (pDev[DeviceFD].avail == 0)
     {
       return(SCSI_ERROR);
@@ -243,7 +263,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
   ccb = cam_getccb(pDev[DeviceFD].curdev);
 
   /* Build the CCB */
-  bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
+  bzero(&(&ccb->ccb_h)[1], SIZEOF(struct ccb_scsiio));
   bcopy(&CDB[0], &ccb->csio.cdb_io.cdb_bytes, CDB_Length);
 
   switch (Direction)
@@ -341,7 +361,7 @@ int Tape_Ioctl( int DeviceFD, int command)
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
     {
-      dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+      dbprintf(("Tape_Ioctl error ioctl %s\n", strerror(errno)));
       SCSI_CloseDevice(DeviceFD);
       return(-1);
     }
@@ -362,7 +382,7 @@ int Tape_Status( int DeviceFD)
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
   {
-     dbprintf(("Tape_Status error ioctl %d\n",errno));
+     dbprintf(("Tape_Status error ioctl %s\n", strerror(errno)));
      SCSI_CloseDevice(DeviceFD);
      return(-1);
   }
@@ -463,6 +483,7 @@ int ScanBus(int print)
             }
         }
     }
+    return 0;
 }
 
 #endif
index c9dad844638e9e2beda7edbf7530d45645c1ac6e..0c274af7b64b64dcb6ac621c5d122916d2a3687e 100644 (file)
@@ -1,6 +1,4 @@
-#ifndef lint
-static char rcsid[] = "$Id: scsi-changer-driver.c,v 1.49 2006/03/16 00:20:53 paddy_s Exp $";
-#endif
+static char rcsid[] = "$Id: scsi-changer-driver.c,v 1.52 2006/07/21 00:25:50 martinea Exp $";
 /*
  * Interface to control a tape robot/library connected to the SCSI bus
  *
@@ -9,10 +7,6 @@ static char rcsid[] = "$Id: scsi-changer-driver.c,v 1.49 2006/03/16 00:20:53 pad
 
 #include <amanda.h>
 
-#ifdef HAVE_DMALLOC_H
-#include <dmalloc.h>
-#endif
-
 #include "arglist.h"
 /*
 #ifdef HAVE_STDIO_H
@@ -47,9 +41,8 @@ static char rcsid[] = "$Id: scsi-changer-driver.c,v 1.49 2006/03/16 00:20:53 pad
 
 #include "tapeio.h"
 
-extern int TapeEject(int DeviceFD);
-
 extern FILE *debug_file;
+extern changer_t *changer;    /* Needed for the infos about emubarcode and labelfile */
 
 int PrintInquiry(SCSIInquiry_T *);
 int GenericElementStatus(int DeviceFD, int InitStatus);
@@ -58,84 +51,90 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus);
 ElementInfo_T *LookupElement(int addr);
 int GenericResetStatus(int DeviceFD);
 int RequestSense(int, ExtendedRequestSense_T *, int  );
-void dump_hex(char *, int, int, int);
-void TerminateString(char *string, int length);
+void dump_hex(u_char *, size_t, int, int);
+void TerminateString(char *string, size_t length);
 void ChgExit(char *, char *, int);
 int BarCode(int fd);
 int LogSense(int fd);
-int SenseHandler(int fd, unsigned char flag, unsigned char SenseKey, unsigned char AdditionalSenseCode, unsigned char AdditionalSenseCodeQualifier, char *buffer);
+int SenseHandler(int fd, u_char flag, u_char SenseKey, u_char AdditionalSenseCode, u_char AdditionalSenseCodeQualifier, RequestSense_T *buffer);
+
+int SCSI_AlignElements(int DeviceFD, size_t MTE, size_t DTE, size_t STE);
 
-int SCSI_AlignElements(int DeviceFD, int MTE, int DTE, int STE);
+int DoNothing0(void);
+int DoNothing1(int);
+int DoNothing2(int, int);
+int DoNothing3(int, int, int);
 
-int DoNothing();
 int GenericMove(int, int, int);
 int SDXMove(int, int, int);
 int CheckMove(ElementInfo_T *from, ElementInfo_T *to);
 int GenericRewind(int);
-/* int GenericStatus(); */
-int GenericFree();
-int TapeStatus();                   /* Is the tape loaded ? */
+/* int GenericStatus(void); */
+int GenericFree(void);
+int TapeStatus(void);                   /* Is the tape loaded ? */
 int DLT4000Eject(char *Device, int type);
 int GenericEject(char *Device, int type);
 int GenericClean(char *Device);                 /* Does the tape need a clean */
 int GenericBarCode(int DeviceFD);               /* Do we have Barcode reader support */
 int NoBarCode(int DeviceFD);
 
-int GenericSearch();
+int GenericSearch(void);
 void Inventory(char *labelfile, int drive, int eject, int start, int stop, int clean);
 
 int TreeFrogBarCode(int DeviceFD);
 int EXB_BarCode(int DeviceFD);
-int GenericSenseHandler(int fd, int flags, unsigned char SenseKey, unsigned char AdditionalSenseCode, unsigned char AdditionalSenseCodeQualifier, char *);
+int GenericSenseHandler(int fd, u_char flags, u_char SenseKey, u_char AdditionalSenseCode, u_char AdditionalSenseCodeQualifier, RequestSense_T *);
 
 ElementInfo_T *LookupElement(int address);
 int eject_tape(char *tapedev, int type);
 int unload(int fd, int drive, int slot);
 int load(int fd, int drive, int slot);
 int GetElementStatus(int DeviceFD);
+int drive_loaded(int fd, int drivenum);
 
 /*
  * Log Pages Decode
  */
-void WriteErrorCountersPage(LogParameter_T *, int);
-void ReadErrorCountersPage(LogParameter_T *, int);
-void C1553APage30(LogParameter_T *, int);
-void C1553APage37(LogParameter_T *, int);
-void EXB85058HEPage39(LogParameter_T *, int);
-void EXB85058HEPage3c(LogParameter_T *, int);
-int Decode(LogParameter_T *, int *);
-int DecodeModeSense(char *buffer, int offset, char *pstring, char block, FILE *out);
+void WriteErrorCountersPage(LogParameter_T *, size_t);
+void ReadErrorCountersPage(LogParameter_T *, size_t);
+void C1553APage30(LogParameter_T *, size_t);
+void C1553APage37(LogParameter_T *, size_t);
+void EXB85058HEPage39(LogParameter_T *, size_t);
+void EXB85058HEPage3c(LogParameter_T *, size_t);
+int Decode(LogParameter_T *, unsigned *);
+int DecodeModeSense(u_char *buffer, size_t offset, char *pstring, char block, FILE *out);
 
 int SCSI_Run(int DeviceFD,
             Direction_T Direction,
             CDB_T CDB,
-            int CDB_Length,
+            size_t CDB_Length,
             void *DataBuffer,
-            int DataBufferLength,
-            char *pRequestSense,
-            int RequestSenseLength);
+            size_t DataBufferLength,
+            RequestSense_T *pRequestSense,
+            size_t RequestSenseLength);
 
-int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to);
-int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, unsigned char byte1, unsigned char load);
+int SCSI_Move(int DeviceFD, u_char chm, int from, int to);
+int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, u_char byte1, u_char load);
 int SCSI_TestUnitReady(int, RequestSense_T *);
-int SCSI_ModeSense(int DeviceFD, char *buffer, u_char size, u_char byte1, u_char byte2);
+int SCSI_ModeSense(int DeviceFD, u_char *buffer, u_char size, u_char byte1, u_char byte2);
 int SCSI_ModeSelect(int DeviceFD,
-                    char *buffer,
-                    unsigned char length,
-                    unsigned char save,
-                    unsigned char mode,
-                    unsigned char lun);
+                    u_char *buffer,
+                    u_char length,
+                    u_char save,
+                    u_char mode,
+                    u_char lun);
 
 int SCSI_ReadElementStatus(int DeviceFD,
-                           unsigned char type,
-                           unsigned char lun,
-                           unsigned char VolTag,
+                           u_char type,
+                           u_char lun,
+                           u_char VolTag,
                            int StartAddress,
-                           int NoOfElements,
-                          int DescriptorSize,
-                          char **data);
+                           size_t NoOfElements,
+                          size_t DescriptorSize,
+                          u_char **data);
 
 FILE *StatFile;
+static int barcode;   /* cache the result from the BarCode function */
 
 SC_COM_T SCSICommand[] = {
   {0x00,
@@ -198,7 +197,7 @@ ChangerCMD_T ChangerIO[] = {
    "HP Auto Loader [C1553A]",
    GenericMove,
    GenericElementStatus,
-   DoNothing,
+   DoNothing1,
    GenericFree,
    GenericEject,
    GenericClean,
@@ -245,10 +244,10 @@ ChangerCMD_T ChangerIO[] = {
    GenericSenseHandler},
   {"EXB-85058HE-0000",
    "Exabyte Tape [EXB-85058HE-0000]",
-   DoNothing,
-   DoNothing,
-   DoNothing,
-   DoNothing,
+   DoNothing3,
+   DoNothing2,
+   DoNothing1,
+   DoNothing0,
    GenericEject,
    GenericClean,
    GenericRewind,
@@ -374,10 +373,10 @@ ChangerCMD_T ChangerIO[] = {
    GenericSenseHandler},
   {"DLT8000",
    "DLT Tape [DLT8000]",
-   DoNothing,
-   DoNothing,
-   DoNothing,
-   DoNothing,
+   DoNothing3,
+   DoNothing2,
+   DoNothing1,
+   DoNothing0,
    DLT4000Eject,
    GenericClean,
    GenericRewind,
@@ -386,10 +385,10 @@ ChangerCMD_T ChangerIO[] = {
    GenericSenseHandler},
   {"DLT7000",
    "DLT Tape [DLT7000]",
-   DoNothing,
-   DoNothing,
-   DoNothing,
-   DoNothing,
+   DoNothing3,
+   DoNothing2,
+   DoNothing1,
+   DoNothing0,
    DLT4000Eject,
    GenericClean,
    GenericRewind,
@@ -398,10 +397,10 @@ ChangerCMD_T ChangerIO[] = {
    GenericSenseHandler},
   {"DLT4000",
    "DLT Tape [DLT4000]",
-   DoNothing,
-   DoNothing,
-   DoNothing,
-   DoNothing,
+   DoNothing3,
+   DoNothing2,
+   DoNothing1,
+   DoNothing0,
    DLT4000Eject,
    GenericClean,
    GenericRewind,
@@ -446,10 +445,10 @@ int LibModeSenseValid = 0;          /* Set if we did an scussefull MODE SENSE */
 
 char *SlotArgs = 0;
 /* Pointer to MODE SENSE Pages */
-char *pModePage = NULL;
+u_char *pModePage = NULL;
 EAAPage_T *pEAAPage = NULL;
 DeviceCapabilitiesPage_T *pDeviceCapabilitiesPage = NULL;
-char *pVendorUnique = NULL;
+u_char *pVendorUnique = NULL;
 
 /*
  *  New way, every element type has its on array
@@ -459,10 +458,10 @@ ElementInfo_T *pMTE = NULL; /*Medium Transport Element */
 ElementInfo_T *pSTE = NULL; /*Storage Element */
 ElementInfo_T *pIEE = NULL; /*Import Export Element */
 ElementInfo_T *pDTE = NULL; /*Data Transfer Element */
-int MTE = 0;                /*Counter for the above element types */
-int STE = 0;
-int IEE = 0;
-int DTE = 0;
+size_t MTE = 0;                /*Counter for the above element types */
+size_t STE = 0;
+size_t IEE = 0;
+size_t DTE = 0;
 
 char *chgscsi_datestamp = NULL;       /* Result pointer for tape_rdlabel */
 char *chgscsi_label = NULL;           /* Result pointer for tape_rdlabel */
@@ -477,7 +476,8 @@ char *chgscsi_result = NULL;          /* Needed for the result string of MapBarC
  * Print the scsi-changer-driver version
  */
 
-void ChangerDriverVersion()
+void
+ChangerDriverVersion(void)
 {
   DebugPrint(DEBUG_ERROR, SECTION_INFO, "scsi-changer-driver: %s\n",rcsid);
   SCSI_OS_Version();
@@ -487,7 +487,8 @@ void ChangerDriverVersion()
  * Try to generate an template which can be used as an example for the config file
  *
  */
-void PrintConf()
+void
+PrintConf(void)
 {
   extern OpenFiles_T *pDev;
   int count;
@@ -581,7 +582,7 @@ void PrintConf()
     {
       printf("startuse          0  # Which is the first slot to use\n");
       printf("                     #\n");
-      printf("enduse            %d  # Which is the last slot to use\n", STE);
+      printf("enduse            " SIZE_T_FMT "  # Which is the last slot to use\n", STE);
     } else {
       printf("startuse         ??? # Which is the first slot to use\n");
       printf("                     #\n");
@@ -591,7 +592,9 @@ void PrintConf()
       printf("                     # cleaning tape in the last slot\n");
       printf("                     #\n");
 
-  cwd = getcwd(NULL, 0);
+  if ((cwd = getcwd(NULL, 0)) == NULL) {
+      cwd = "<unknown>";
+  }
 
   printf("statfile %s/tape0-slot #\n",cwd);
   printf("cleanfile %s/tape0-clean #\n", cwd);
@@ -622,28 +625,33 @@ void PrintConf()
  * If an tape is loaded unload it and do initialize element status to
  * get all labels if an bar code reader is installed
  */
-void Inventory(char *labelfile, int drive, int eject, int start, int stop, int clean)
+void
+Inventory(
+    char *     labelfile,
+    int                drive,
+    int                eject,
+    int                start,
+    int                stop,
+    int                clean)
 {
   extern OpenFiles_T *pDev;
-  int x;
-  char *result;                 /* Used to store the result of MapBarCode */
-  int barcode;                  /* cache the result from the BarCode function */
+  size_t x;
   static int inv_done = 0;     /* Inventory function called ?, marker to disable recursion */
   MBC_T *pbarcoderes;          /* Here we will pass the parameter to MapBarCode and get the result */
 
+  (void)start; /* Quiet unused parameter warning */
+  (void)stop;  /* Quiet unused parameter warning */
+
   DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, "##### START Inventory\n");
-  if ((pbarcoderes = malloc(sizeof(MBC_T))) == NULL)
-    {
-      DebugPrint(DEBUG_ERROR, SECTION_MAP_BARCODE,"##### malloc failed (-1)\n");
-      return;
-    }
-  memset(pbarcoderes, 0 , sizeof(MBC_T));
+  pbarcoderes = alloc(SIZEOF(MBC_T));
+  memset(pbarcoderes, 0 , SIZEOF(MBC_T));
 
   if (inv_done != 0)
     {
       DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, "##### STOP inv_done -> %d Inventory\n",inv_done);
       free(pbarcoderes);
       return;
+      /*NOTREACHED*/
     }
   inv_done = 1;
   barcode = BarCode(INDEX_CHANGER);
@@ -661,7 +669,7 @@ void Inventory(char *labelfile, int drive, int eject, int start, int stop, int c
     {
       if (eject)
        {
-         eject_tape("", eject);
+         (void)eject_tape("", eject);
        }
       (void)unload(INDEX_TAPE, 0, 0);
     }
@@ -670,7 +678,7 @@ void Inventory(char *labelfile, int drive, int eject, int start, int stop, int c
 
   for (x = 0; x < STE; x++)
     {
-      if (x == clean)
+      if (x == (size_t)clean)
        {
          continue;
        }
@@ -692,16 +700,18 @@ void Inventory(char *labelfile, int drive, int eject, int start, int stop, int c
 
       SCSI_CloseDevice(INDEX_TAPE);
 
-      if ((result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label)) == NULL)
+      if ((chgscsi_result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label)) == NULL)
       {
        pbarcoderes->action = UPDATE_SLOT;
-       strcpy(pbarcoderes->data.voltag, chgscsi_label);
+       strncpy(pbarcoderes->data.voltag, chgscsi_label,
+               SIZEOF(pbarcoderes->data.voltag));
        pbarcoderes->data.slot = x;
        pbarcoderes->data.from = 0;
        pbarcoderes->data.LoadCount = 1;
        if (BarCode(INDEX_CHANGER) == 1)
          {
-           strcpy(pbarcoderes->data.barcode, pDTE[drive].VolTag);
+           strncpy(pbarcoderes->data.barcode, pDTE[drive].VolTag,
+                   SIZEOF(pbarcoderes->data.barcode));
            MapBarCode(labelfile, pbarcoderes);
          } else {
            MapBarCode(labelfile, pbarcoderes);
@@ -712,7 +722,7 @@ void Inventory(char *labelfile, int drive, int eject, int start, int stop, int c
 
       if (eject)
        {
-         eject_tape("", eject);
+         (void)eject_tape("", eject);
        }
 
       (void)unload(INDEX_TAPE, drive, x);
@@ -725,7 +735,10 @@ void Inventory(char *labelfile, int drive, int eject, int start, int stop, int c
  * Check if the slot ist empty
  * slot -> slot number to check
  */
-int isempty(int fd, int slot)
+int
+isempty(
+    int                fd,
+    int                slot)
 {
   extern OpenFiles_T *pDev;
   DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### START isempty\n");
@@ -736,6 +749,7 @@ int isempty(int fd, int slot)
         {
           DebugPrint(DEBUG_ERROR,SECTION_TAPE,"##### STOP isempty [-1]\n");
           return(-1);
+         /*NOTREACHED*/
         }
     }
 
@@ -743,12 +757,15 @@ int isempty(int fd, int slot)
     {
       DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP isempty [1]\n");
       return(1);
+      /*NOTREACHED*/
     }
   DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP isempty [0]\n");
   return(0);
 }
 
-int get_clean_state(char *tapedev)
+int
+get_clean_state(
+    char *tapedev)
 {
   extern OpenFiles_T *pDev;
   /* Return 1 if cleaning is needed */
@@ -760,6 +777,7 @@ int get_clean_state(char *tapedev)
     {
       DebugPrint(DEBUG_ERROR,SECTION_TAPE,"##### STOP get_clean_state [-1]\n");
       return(-1);
+      /*NOTREACHED*/
     }
   ret=pDev[INDEX_TAPECTL].functions->function_clean(tapedev);
   DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP get_clean_state [%d]\n", ret);
@@ -772,19 +790,22 @@ int get_clean_state(char *tapedev)
  * Type describes if we should force the SCSI eject if available
  * normal eject is done with the ioctl
  */
-int eject_tape(char *tapedev, int type)
-  /* This function ejects the tape from the drive */
+/* This function ejects the tape from the drive */
+
+int
+eject_tape(
+    char *     tapedev,
+    int                type)
 {
   extern OpenFiles_T *pDev;
-  int ret = 0;
-  extern changer_t chg;         /* Needed for the infos about emubarcode and labelfile */
+  int ret;
 
   DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### START eject_tape\n");
 
   /*
    * Try to read the label
    */
-  if (pDev[INDEX_TAPE].avail == 1 && (chg.emubarcode == 1 || BarCode(INDEX_CHANGER)))
+  if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER)))
     {
 
       if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
@@ -806,6 +827,7 @@ int eject_tape(char *tapedev, int type)
       ret=pDev[INDEX_TAPECTL].functions->function_eject(tapedev, type);
       DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP (SCSI)eject_tape [%d]\n", ret);
       return(ret);
+      /*NOTREACHED*/
     }
 
   if (pDev[INDEX_TAPE].avail == 1)
@@ -813,6 +835,7 @@ int eject_tape(char *tapedev, int type)
       ret=Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT);
       DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP (ioctl)eject_tape [%d]\n", ret);
       return(ret);
+      /*NOTREACHED*/
     }
 
   DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP eject_tape [-1]\n");
@@ -821,11 +844,15 @@ int eject_tape(char *tapedev, int type)
 
 
 /* Find an empty slot, starting at start, ending at start+count */
-int find_empty(int fd, int start, int count)
+int
+find_empty(
+    int        fd,
+    int        start,
+    int        count)
 {
   extern OpenFiles_T *pDev;
-  int x;
-  int end;
+  size_t x;
+  size_t end;
 
   DebugPrint(DEBUG_INFO,SECTION_ELEMENT,"###### START find_empty\n");
 
@@ -833,8 +860,10 @@ int find_empty(int fd, int start, int count)
     {
       if ( pDev[fd].functions->function_status(fd , 1) != 0)
         {
-          DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,"###### END find_empty [%d]\n", -1);
-          return(-1);
+          DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,
+                    "###### END find_empty [-1]\n");
+          return((ssize_t)-1);
+         /*NOTREACHED*/
         }
     }
 
@@ -850,18 +879,23 @@ int find_empty(int fd, int start, int count)
       end = STE;
     }
 
-  DebugPrint(DEBUG_INFO,SECTION_ELEMENT,"start at %d, end at %d\n", start, end);
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,
+            "start at " SIZE_T_FMT ", end at " SIZE_T_FMT "\n",
+            (SIZE_T_FMT_TYPE)start,
+            (SIZE_T_FMT_TYPE)end);
 
   for (x = start; x < end; x++)
     {
       if (pSTE[x].status == 'E')
         {
-          DebugPrint(DEBUG_INFO,SECTION_ELEMENT,"###### END find_empty [%d]\n", x);
-          return(x);
+          DebugPrint(DEBUG_INFO,SECTION_ELEMENT,
+                    "###### END find_empty [" SIZE_T_FMT "]\n", x);
+          return((ssize_t)x);
+         /*NOTREACHED*/
         }
     }
-  DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,"###### END find_empty [%d]\n", -1);
-  return(-1);
+  DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,"###### END find_empty [-1]\n");
+  return((ssize_t)-1);
 }
 
 /*
@@ -872,7 +906,10 @@ int find_empty(int fd, int start, int count)
  * 0  -> drive is empty
  * 1  -> drive is loaded
  */
-int drive_loaded(int fd, int drivenum)
+int
+drive_loaded(
+    int                fd,
+    int                drivenum)
 {
   extern OpenFiles_T *pDev;
 
@@ -886,16 +923,17 @@ int drive_loaded(int fd, int drivenum)
        {
          DebugPrint(DEBUG_ERROR,SECTION_TAPE,"Fatal error\n");
          return(-1);
+         /*NOTREACHED*/
        }
     }
 
   if (pDTE[drivenum].status == 'E') {
     DebugPrint(DEBUG_INFO,SECTION_TAPE,"###### STOP drive_loaded (empty)\n");
     return(0);
-  } else {
-    DebugPrint(DEBUG_INFO,SECTION_TAPE,"###### STOP drive_loaded (not empty)\n");
-    return(1);
+    /*NOTREACHED*/
   }
+  DebugPrint(DEBUG_INFO,SECTION_TAPE,"###### STOP drive_loaded (not empty)\n");
+  return(1);
 }
 
 
@@ -906,22 +944,20 @@ int drive_loaded(int fd, int drivenum)
  * TODO:
  * Check if the MTE is empty
  */
-int unload(int fd, int drive, int slot)
+int
+unload(
+    int                fd,
+    int                drive,
+    int                slot)
 {
   extern OpenFiles_T *pDev;
-  int ret;
-  extern changer_t chg;         /* Needed for the infos about emubarcode and labelfile */
   extern int do_inventory;
   MBC_T *pbarcoderes;
 
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"###### START unload\n");
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"%-20s : fd %d, slot %d, drive %d \n", "unload", fd, slot, drive);
-  if ((pbarcoderes = malloc(sizeof(MBC_T))) == NULL)
-    {
-      DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### malloc failed (-1)\n");
-      return(-1);
-    }
-  memset(pbarcoderes, 0, sizeof(MBC_T));
+  pbarcoderes = alloc(SIZEOF(MBC_T));
+  memset(pbarcoderes, 0, SIZEOF(MBC_T));
 
   /*
    * If the Element Status is not valid try to
@@ -935,6 +971,7 @@ int unload(int fd, int drive, int slot)
          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1)\n");
          free(pbarcoderes);
          return(-1);
+         /*NOTREACHED*/
        }
     }
 
@@ -954,6 +991,7 @@ int unload(int fd, int drive, int slot)
       DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1)\n");
       free(pbarcoderes);
       return(-1);
+      /*NOTREACHED*/
     }
 
   /*
@@ -968,6 +1006,7 @@ int unload(int fd, int drive, int slot)
          DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "unload: Element Status not valid, can't find an empty slot\n");
          free(pbarcoderes);
          return(-1);
+         /*NOTREACHED*/
        }
 
       slot = find_empty(fd, 0, 0);
@@ -976,6 +1015,7 @@ int unload(int fd, int drive, int slot)
              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "unload: No Empty slot found\n");
              free(pbarcoderes);
              return(-1);
+             /*NOTREACHED*/
       }
       DebugPrint(DEBUG_INFO, SECTION_TAPE,"unload : found empty one, try to unload to slot %d\n", slot);
     }
@@ -986,9 +1026,9 @@ int unload(int fd, int drive, int slot)
    * If eject is not set we must read the label info
    */
 
-  if (chg.eject == 0)
+  if (changer->eject == 0)
     {
-      if (pDev[INDEX_TAPE].avail == 1 && (chg.emubarcode == 1 || BarCode(INDEX_CHANGER)))
+      if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER)))
        {
 
          if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
@@ -1009,7 +1049,14 @@ int unload(int fd, int drive, int slot)
   /*
    * Do the unload/move
    */
-  ret = pDev[INDEX_CHANGER].functions->function_move(INDEX_CHANGER , pDTE[drive].address, pSTE[slot].address);
+  if (pDev[INDEX_CHANGER].functions->function_move(INDEX_CHANGER,
+           pDTE[drive].address, pSTE[slot].address) != 0) {
+      DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1 move failed)\n");
+      free(pbarcoderes);
+      return(-1);
+      /*NOTREACHED*/
+    }
+
 
   /*
    * Update the Status
@@ -1019,6 +1066,7 @@ int unload(int fd, int drive, int slot)
       DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1 update status failed)\n");
       free(pbarcoderes);
       return(-1);
+      /*NOTREACHED*/
     }
 
   /*
@@ -1026,14 +1074,14 @@ int unload(int fd, int drive, int slot)
    * if no update the vol/label mapping
    * If chgscsi_label is NULL don't do it
    */
-  if (chgscsi_result  == NULL && chgscsi_label != NULL && chg.labelfile != NULL)
+  if (chgscsi_result  == NULL && chgscsi_label != NULL && changer->labelfile != NULL)
   {
     /*
      * OK this is only needed if we have emubarcode set
      * There we need an exact inventory to get the search function working
      * and returning correct results
      */
-    if (BarCode(INDEX_CHANGER) == 0 && chg.emubarcode == 1)
+    if (BarCode(INDEX_CHANGER) == 0 && changer->emubarcode == 1)
       {
        /*
         * We got something, update the db
@@ -1041,14 +1089,16 @@ int unload(int fd, int drive, int slot)
         * to where we placed the tape, if no force an inventory
         */
        pbarcoderes->action = FIND_SLOT;
-       strcpy(pbarcoderes->data.voltag, chgscsi_label);
-       strcpy(pbarcoderes->data.barcode, pSTE[slot].VolTag );
+       strncpy(pbarcoderes->data.voltag, chgscsi_label,
+               SIZEOF(pbarcoderes->data.voltag));
+       strncpy(pbarcoderes->data.barcode, pSTE[slot].VolTag,
+              SIZEOF(pbarcoderes->data.barcode));
        pbarcoderes->data.slot = 0;
        pbarcoderes->data.from = 0;
        pbarcoderes->data.LoadCount = 0;
 
 
-       if ( MapBarCode(chg.labelfile, pbarcoderes) == 0) /* Nothing known about this, do an Inventory */
+       if ( MapBarCode(changer->labelfile, pbarcoderes) == 0) /* Nothing known about this, do an Inventory */
          {
            do_inventory = 1;
          } else {
@@ -1077,9 +1127,12 @@ int unload(int fd, int drive, int slot)
  * return -> 0 = success
  *           !0 = failure
  */
-int load(int fd, int drive, int slot)
+int
+load(
+    int                fd,
+    int                drive,
+    int                slot)
 {
-  extern changer_t chg;         /* Needed for the infos about emubarcode and labelfile */
   char *result = NULL;          /* Needed for the result of tape_rdlabel */
   int ret;
   extern OpenFiles_T *pDev;
@@ -1088,12 +1141,8 @@ int load(int fd, int drive, int slot)
 
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"###### START load\n");
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"%-20s : fd %d, drive %d, slot %d \n", "load", fd, drive, slot);
-  if ((pbarcoderes = malloc(sizeof(MBC_T))) == NULL)
-    {
-      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### malloc failed (-1)\n");
-      return(-1);
-    }
-  memset(pbarcoderes, 0 , sizeof(MBC_T));
+  pbarcoderes = alloc(SIZEOF(MBC_T));
+  memset(pbarcoderes, 0 , SIZEOF(MBC_T));
 
   if (ElementStatusValid == 0)
       {
@@ -1103,6 +1152,7 @@ int load(int fd, int drive, int slot)
                DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
                free(pbarcoderes);
                return(-1);
+               /*NOTREACHED*/
               }
       }
 
@@ -1112,19 +1162,21 @@ int load(int fd, int drive, int slot)
    * is ge than the value we got from the ModeSense fail with an return value
    * of 2
    */
-  if (slot >= STE)
+  if ((size_t)slot >= STE)
     {
       DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"load : slot %d ge STE %d\n",slot, STE);
       ChgExit("load", "slot >= STE", FATAL);
+      /*NOTREACHED*/
     }
 
   /*
    * And the same for the tape drives
    */
-  if (drive >= DTE)
+  if (drive >= (int)DTE)
     {
       DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"load : drive %d ge DTE %d\n",drive, DTE);
       ChgExit("load", "drive >= DTE", FATAL);
+      /*NOTREACHED*/
     }
 
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"load : load drive %d[%d] slot %d[%d]\n",drive,
@@ -1138,6 +1190,7 @@ int load(int fd, int drive, int slot)
       DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
       free(pbarcoderes);
       return(-1);
+      /*NOTREACHED*/
     }
 
   if (pSTE[slot].status == 'E')
@@ -1146,6 +1199,7 @@ int load(int fd, int drive, int slot)
       DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
       free(pbarcoderes);
       return(-1);
+      /*NOTREACHED*/
     }
 
   ret = pDev[fd].functions->function_move(fd, pSTE[slot].address, pDTE[drive].address);
@@ -1158,13 +1212,14 @@ int load(int fd, int drive, int slot)
        DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
        free(pbarcoderes);
        return(-1);
+       /*NOTREACHED*/
       }
 
   /*
    * Try to read the label
    * and update the label/slot database
    */
-  if (pDev[INDEX_TAPE].avail == 1 && (chg.emubarcode == 1 || BarCode(INDEX_CHANGER)))
+  if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER)))
     {
 
       if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
@@ -1185,14 +1240,15 @@ int load(int fd, int drive, int slot)
    * Did we get an error from tape_rdlabel
    * if no update the vol/label mapping
    */
-  if (result  == NULL && chg.labelfile != NULL && chgscsi_label != NULL )
+  if (result  == NULL && changer->labelfile != NULL && chgscsi_label != NULL )
     {
       /*
        * We got something, update the db
        * but before check if the db has as entry the slot
        * to where we placed the tape, if no force an inventory
        */
-      strcpy(pbarcoderes->data.voltag, chgscsi_label);
+      strncpy(pbarcoderes->data.voltag, chgscsi_label,
+             SIZEOF(pbarcoderes->data.voltag));
       pbarcoderes->data.slot = 0;
       pbarcoderes->data.from = 0;
       pbarcoderes->data.LoadCount = 0;
@@ -1204,19 +1260,20 @@ int load(int fd, int drive, int slot)
        * info in the DB is up to date, if no we set the do_inventory flag
        */
 
-      if (BarCode(INDEX_CHANGER) == 1 && chg.emubarcode == 0)
+      if (BarCode(INDEX_CHANGER) == 1 && changer->emubarcode == 0)
        {
          pbarcoderes->action = UPDATE_SLOT;
-         strcpy(pbarcoderes->data.barcode, pDTE[drive].VolTag);
+         strncpy(pbarcoderes->data.barcode, pDTE[drive].VolTag,
+                 SIZEOF(pbarcoderes->data.barcode));
          pbarcoderes->data.LoadCount = 1;
          pbarcoderes->data.slot = slot;
-         MapBarCode(chg.labelfile, pbarcoderes);
+         MapBarCode(changer->labelfile, pbarcoderes);
        }
 
-      if (BarCode(INDEX_CHANGER) == 0 && chg.emubarcode == 1)
+      if (BarCode(INDEX_CHANGER) == 0 && changer->emubarcode == 1)
        {
          pbarcoderes->action = FIND_SLOT;
-         if (MapBarCode(chg.labelfile, pbarcoderes) == 0) /* Nothing found, do an inventory */
+         if (MapBarCode(changer->labelfile, pbarcoderes) == 0) /* Nothing found, do an inventory */
            {
              do_inventory = 1;
            } else { /* We got something, is it correct ? */
@@ -1224,23 +1281,26 @@ int load(int fd, int drive, int slot)
                {
                  DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Slot DB out of sync, slot %d != map %d",slot, pbarcoderes->data.slot);
                  ChgExit("Load", "Label DB out of sync", FATAL);
+                 /*NOTREACHED*/
                } else { /* OK, so increment the load count */
                  pbarcoderes->action = UPDATE_SLOT;
                  pbarcoderes->data.LoadCount = 1;
                  pbarcoderes->data.slot = slot;
-                 MapBarCode(chg.labelfile, pbarcoderes);
+                 MapBarCode(changer->labelfile, pbarcoderes);
                }
            }
        }
 
-      if (BarCode(INDEX_CHANGER) == 1 && chg.emubarcode == 1)
+      if (BarCode(INDEX_CHANGER) == 1 && changer->emubarcode == 1)
        {
          ChgExit("Load", "BarCode == 1 and emubarcode == 1", FATAL);
+         /*NOTREACHED*/
        }
 
       DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP load (%d)\n",ret);
       free(pbarcoderes);
       return(ret);
+      /*NOTREACHED*/
     }
     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP load (%d)\n",ret);
     free(pbarcoderes);
@@ -1252,7 +1312,9 @@ int load(int fd, int drive, int slot)
  * fd -> pointer to the internal devie structure pDev
  * return -> Number of slots
  */
-int get_slot_count(int fd)
+int
+get_slot_count(
+    int fd)
 {
   extern OpenFiles_T *pDev;
 
@@ -1263,13 +1325,14 @@ int get_slot_count(int fd)
     {
       pDev[fd].functions->function_status(fd, 1);
     }
-  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP get_slot_count (%d)\n",STE);
-  return(STE);
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,
+            "##### STOP get_slot_count (" SIZE_T_FMT ")\n",
+            (SIZE_T_FMT_TYPE)STE);
+  return((ssize_t)STE);
   /*
    * return the number of slots in the robot
    * to the caller
    */
-
 }
 
 
@@ -1278,7 +1341,9 @@ int get_slot_count(int fd)
  * fd     -> pointer to the internal devie structure pDev
  * return -> -1 on failure
  */
-int get_drive_count(int fd)
+int
+get_drive_count(
+    int fd)
 {
 
   extern OpenFiles_T *pDev;
@@ -1286,7 +1351,6 @@ int get_drive_count(int fd)
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### START get_drive_count\n");
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-20s : fd %d\n", "get_drive_count", fd);
 
-
   if (ElementStatusValid == 0)
       {
           if ( pDev[fd].functions->function_status(fd, 1) != 0)
@@ -1294,10 +1358,13 @@ int get_drive_count(int fd)
                DebugPrint(DEBUG_ERROR, SECTION_SCSI, "Error getting drive count\n");
                DebugPrint(DEBUG_ERROR, SECTION_SCSI, "##### STOP get_drive_count (-1)\n");
                return(-1);
+               /*NOTREACHED*/
            }
       }
-  DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP get_drive_count (%d drives)\n",DTE);
-  return(DTE);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,
+            "###### STOP get_drive_count (" SIZE_T_FMT " drives)\n",
+            (SIZE_T_FMT_TYPE)DTE);
+  return((ssize_t)DTE);
 }
 
 /*
@@ -1309,12 +1376,22 @@ int get_drive_count(int fd)
  * The OS has to decide if it is an SCSI Commands capable device
  */
 
-int OpenDevice(int ip , char *DeviceName, char *ConfigName, char *ident)
+int
+OpenDevice(
+    int                ip,
+    char *     DeviceName,
+    char *     ConfigName,
+    char *     ident)
 {
   extern OpenFiles_T *pDev;
   char tmpstr[15];
   ChangerCMD_T *p = (ChangerCMD_T *)&ChangerIO;
 
+  if (!ConfigName)
+       return 1;
+  if (!DeviceName)
+       return 1;
+
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START OpenDevice\n");
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"OpenDevice : %s\n", DeviceName);
 
@@ -1334,10 +1411,12 @@ int OpenDevice(int ip , char *DeviceName, char *ConfigName, char *ident)
                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"override using ident = %s, type = %s\n",p->ident, p->type);
                DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP OpenDevice\n");
                 return(1);
+               /*NOTREACHED*/
               }
             p++;
           }
          ChgExit("OpenDevice", "ident not found", FATAL);
+         /*NOTREACHED*/
       } else {
         while(p->ident != NULL)
           {
@@ -1347,6 +1426,7 @@ int OpenDevice(int ip , char *DeviceName, char *ConfigName, char *ident)
                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"using ident = %s, type = %s\n",p->ident, p->type);
                DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP OpenDevice\n");
                 return(1);
+               /*NOTREACHED*/
               }
             p++;
           }
@@ -1355,7 +1435,7 @@ int OpenDevice(int ip , char *DeviceName, char *ConfigName, char *ident)
       /* divide generic in generic_type, where type is the */
       /* num returned by the inquiry command */
       p = (ChangerCMD_T *)&ChangerIO;
-      sprintf(&tmpstr[0],"%s_%s","generic",pDev[0].type);
+      snprintf(&tmpstr[0], SIZEOF(tmpstr), "%s_%s","generic",pDev[0].type);
       while(p->ident != NULL)
         {
           if (strcmp(tmpstr, p->ident) == 0)
@@ -1364,6 +1444,7 @@ int OpenDevice(int ip , char *DeviceName, char *ConfigName, char *ident)
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"using ident = %s, type = %s\n",p->ident, p->type);
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP OpenDevice\n");
               return(1);
+             /*NOTREACHED*/
             }
           p++;
         }
@@ -1379,9 +1460,11 @@ int OpenDevice(int ip , char *DeviceName, char *ConfigName, char *ident)
  * This functions checks if the library has an barcode reader.
  * fd     -> pointer to the internal devie structure pDev
  */
-int BarCode(int fd)
+int
+BarCode(
+    int                fd)
 {
-  int ret = 0;
+  int ret;
   extern OpenFiles_T *pDev;
 
   DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START BarCode\n");
@@ -1402,12 +1485,15 @@ int BarCode(int fd)
  * wait -> time to wait for the ready status
  *
  */
-int Tape_Ready(int fd, int wait_time)
+int
+Tape_Ready(
+    int                fd,
+    time_t     wait_time)
 {
   extern OpenFiles_T *pDev;
-  int true = 1;
+  int done;
   int ret;
-  int cnt = 0;
+  time_t cnt = 0;
 
   RequestSense_T *pRequestSense;
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START Tape_Ready\n");
@@ -1453,6 +1539,7 @@ int Tape_Ready(int fd, int wait_time)
                  DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : Ready after %d seconds\n",cnt);
                  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
                  return(0);
+                 /*NOTREACHED*/
                }
              cnt++;
              sleep(1);
@@ -1462,21 +1549,17 @@ int Tape_Ready(int fd, int wait_time)
          DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : not ready, stop after %d seconds\n",cnt);
          DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
          return(0);
+         /*NOTREACHED*/
 
-       } else {
-         DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : no ioctl interface, will sleep for %d seconds\n", wait_time);
-         sleep(wait_time);
-         DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
-         return(0);
        }
+       DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : no ioctl interface, will sleep for %d seconds\n", wait_time);
+       sleep(wait_time);
+       DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
+       return(0);
+       /*NOTREACHED*/
     }
 
-  if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-    {
-      DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : malloc failed\n");
-      DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
-      return(-1);
-    }
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
 
   /*
    * Ignore errors at this point
@@ -1487,39 +1570,40 @@ int Tape_Ready(int fd, int wait_time)
    * Wait until we get an ready condition
    */
 
-  while (true && cnt < wait_time)
+  done = 0;
+  while (!done && (cnt < wait_time))
     {
       ret = SCSI_TestUnitReady(fd, pRequestSense );
       switch (ret)
        {
        case SCSI_OK:
-         true = 0;
+         done = 1;
          break;
        case SCSI_SENSE:
-         switch (SenseHandler(fd, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+         switch (SenseHandler(fd, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
            {
            case SENSE_NO:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_NO\n");
-             true=0;
+             done = 1;
              break;
            case SENSE_TAPE_NOT_ONLINE:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
              break;
            case SENSE_IGNORE:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_IGNORE\n");
-             true = 0;
+             done = 1;
              break;
            case SENSE_ABORT:
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_ABORT\n");
-             free(pRequestSense);
+             amfree(pRequestSense);
              return(-1);
-             break;
+             /*NOTREACHED*/
            case SENSE_RETRY:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_RETRY\n");
              break;
            default:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) default (SENSE)\n");
-             true=0;
+             done = 1;
              break;
            }
          break;
@@ -1527,7 +1611,7 @@ int Tape_Ready(int fd, int wait_time)
          DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeReady (TestUnitReady) SCSI_ERROR\n");
          free(pRequestSense);
          return(-1);
-         break;
+         /*NOTREACHED*/
        case SCSI_BUSY:
          DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SCSI_BUSY\n");
          break;
@@ -1542,14 +1626,17 @@ int Tape_Ready(int fd, int wait_time)
       cnt++;
     }
 
+  amfree(pRequestSense);
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready after %d sec\n", cnt);
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
-  free(pRequestSense);
   return(0);
 }
 
 
-int DecodeSCSI(CDB_T CDB, char *string)
+int
+DecodeSCSI(
+    CDB_T      CDB,
+    char *     string)
 {
   SC_COM_T *pSCSICommand;
   int x;
@@ -1569,6 +1656,7 @@ int DecodeSCSI(CDB_T CDB, char *string)
           DebugPrint(DEBUG_INFO, SECTION_SCSI,"\n");
           DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP DecodeSCSI\n");
           return(0);
+         /*NOTREACHED*/
        }
       pSCSICommand++;
     }
@@ -1577,11 +1665,19 @@ int DecodeSCSI(CDB_T CDB, char *string)
   return(0);
 }
 
-int DecodeModeSense(char *buffer, int offset, char *pstring, char block, FILE *out)
+int
+DecodeModeSense(
+    u_char *   buffer,
+    size_t     offset,
+    char *     pstring,
+    char       block,
+    FILE *     out)
 {
   ReadWriteErrorRecoveryPage_T *prp;
   DisconnectReconnectPage_T *pdrp;
-  int length = (unsigned char)*buffer - 4 - offset;
+  size_t length = (size_t)buffer[0] - 4 - offset;
+
+  (void)pstring;       /* Quiet unused parameter warning */
 
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START DecodeModeSense\n");
 
@@ -1598,7 +1694,7 @@ int DecodeModeSense(char *buffer, int offset, char *pstring, char block, FILE *o
   if (block) /* Do we have an block descriptor page ?*/
     {
       if (out != NULL)
-        fprintf(out, "DecodeModeSense : Density Code %x\n", buffer[0]);
+        fprintf(out, "DecodeModeSense : Density Code %x\n", (unsigned)buffer[0]);
       buffer++;
 
       if (out != NULL)
@@ -1731,18 +1827,24 @@ int DecodeModeSense(char *buffer, int offset, char *pstring, char block, FILE *o
           /*           EAAPage = NULL; */
           /*           DeviceCapabilitiesPage = NULL; */
           return(-1);
+         /*NOTREACHED*/
         }
-      length = length - *buffer - 2;
-      buffer = buffer + *buffer + 1;
+      length = length - (size_t)*buffer - 2;
+      buffer = buffer + (size_t)*buffer + 1;
     }
   return(0);
 }
 
-int DecodeSense(RequestSense_T *sense, char *pstring, FILE *out)
+int
+DecodeSense(
+    RequestSense_T *   sense,
+    char *             pstring,
+    FILE *             out)
 {
   if (out == NULL)
     {
       return(0);
+      /*NOTREACHED*/
     }
   fprintf(out,"##### START DecodeSense\n");
   fprintf(out,"%sSense Keys\n", pstring);
@@ -1810,7 +1912,11 @@ int DecodeSense(RequestSense_T *sense, char *pstring, FILE *out)
   return(0);
 }
 
-int DecodeExtSense(ExtendedRequestSense_T *sense, char *pstring, FILE *out)
+int
+DecodeExtSense(
+    ExtendedRequestSense_T *   sense,
+    char *                     pstring,
+    FILE *                     out)
 {
   ExtendedRequestSense_T *p;
 
@@ -1823,7 +1929,7 @@ int DecodeExtSense(ExtendedRequestSense_T *sense, char *pstring, FILE *out)
   fprintf(out,"\tLog Parameter Code              %02X\n", sense->LogParameterCode);
   fprintf(out,"\tUnderrun/Overrun Counter        %02X\n", sense->UnderrunOverrunCounter);
   fprintf(out,"\tRead/Write Error Counter        %d\n", V3((char *)sense->ReadWriteDataErrorCounter));
-  if (sense->AdditionalSenseLength > sizeof(RequestSense_T))
+  if (sense->AdditionalSenseLength > (u_char)sizeof(RequestSense_T))
     {
       if (sense->PF)
         fprintf(out,"\tPower Fail\n");
@@ -1877,7 +1983,9 @@ int DecodeExtSense(ExtendedRequestSense_T *sense, char *pstring, FILE *out)
   return(0);
 }
 
-int PrintInquiry(SCSIInquiry_T *SCSIInquiry)
+int
+PrintInquiry(
+    SCSIInquiry_T *    SCSIInquiry)
 {
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START PrintInquiry\n");
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %x\n", "qualifier", SCSIInquiry->qualifier);
@@ -1896,25 +2004,66 @@ int PrintInquiry(SCSIInquiry_T *SCSIInquiry)
 }
 
 
-int DoNothing()
+int
+DoNothing0(void)
+{
+  dbprintf(("##### START DoNothing\n"));
+  return(0);
+}
+
+int
+DoNothing1(
+    int                unused1)
+{
+  (void)unused1;       /* Quiet unused parameter warning */
+
+  dbprintf(("##### START DoNothing\n"));
+  return(0);
+}
+
+int
+DoNothing2(
+    int                unused1,
+    int                unused2)
+{
+  (void)unused1;       /* Quiet unused parameter warning */
+  (void)unused2;       /* Quiet unused parameter warning */
+
+  dbprintf(("##### START DoNothing\n"));
+  return(0);
+}
+
+int
+DoNothing3(
+    int                unused1,
+    int                unused2,
+    int                unused3)
 {
+  (void)unused1;       /* Quiet unused parameter warning */
+  (void)unused2;       /* Quiet unused parameter warning */
+  (void)unused3;       /* Quiet unused parameter warning */
+
   dbprintf(("##### START DoNothing\n"));
   return(0);
 }
 
-int GenericFree()
+int
+GenericFree(void)
 {
   dbprintf(("##### START GenericFree\n"));
   return(0);
 }
 
-int GenericSearch()
+int
+GenericSearch(void)
 {
   dbprintf(("##### START GenericSearch\n"));
   return(0);
 }
 
-int TreeFrogBarCode(int DeviceFD)
+int
+TreeFrogBarCode(
+    int DeviceFD)
 {
   extern OpenFiles_T *pDev;
 
@@ -1923,11 +2072,7 @@ int TreeFrogBarCode(int DeviceFD)
   dbprintf(("##### START TreeFrogBarCode\n"));
   if (pModePage == NULL)
     {
-      if ((pModePage = malloc(0xff)) == NULL)
-        {
-          dbprintf(("TreeFrogBarCode : malloc failed\n"));
-          return(-1);
-        }
+      pModePage = alloc(0xff);
     }
 
   if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x0, 0x3f) == 0)
@@ -1938,33 +2083,34 @@ int TreeFrogBarCode(int DeviceFD)
       {
          dbprintf(("TreeFrogBarCode : no pVendorUnique\n"));
          return(0);
+        /*NOTREACHED*/
       }
       pVendor = ( ModePageTreeFrogVendorUnique_T *)pVendorUnique;
 
       dbprintf(("TreeFrogBarCode : EBARCO %d\n", pVendor->EBARCO));
       dbprintf(("TreeFrogCheckSum : CHKSUM  %d\n", pVendor->CHKSUM));
 
-      dump_hex((char *)pDev[INDEX_CHANGER].inquiry, INQUIRY_SIZE, DEBUG_INFO, SECTION_ELEMENT);
+      dump_hex((u_char *)pDev[INDEX_CHANGER].inquiry, INQUIRY_SIZE, DEBUG_INFO, SECTION_ELEMENT);
       return(pVendor->EBARCO);
+      /*NOTREACHED*/
     }
   return(0);
 }
 
-int EXB_BarCode(int DeviceFD)
+int
+EXB_BarCode(
+    int                DeviceFD)
 {
   extern OpenFiles_T *pDev;
 
   ModePageEXB120VendorUnique_T *pVendor;
-  ModePageEXB120VendorUnique_T *pVendorWork = NULL;
+  ModePageEXB120VendorUnique_T *pVendorWork;
 
   DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START EXB_BarCode\n");
   if (pModePage == NULL && LibModeSenseValid == 0)
     {
-      if ((pModePage = malloc(0xff)) == NULL)
-        {
-          DebugPrint(DEBUG_ERROR, SECTION_BARCODE,"EXB_BarCode : malloc failed\n");
-          return(-1);
-        }
+      pModePage = alloc(0xff);
+
       if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
        {
          DecodeModeSense(pModePage, 0, "EXB_BarCode :", 0, debug_file);
@@ -1980,6 +2126,7 @@ int EXB_BarCode(int DeviceFD)
        {
          DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : no pVendorUnique\n");
          return(0);
+        /*NOTREACHED*/
       }
       pVendor = ( ModePageEXB120VendorUnique_T *)pVendorUnique;
 
@@ -1987,17 +2134,13 @@ int EXB_BarCode(int DeviceFD)
       DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : PS  %d\n", pVendor->PS);
       if (pVendor->NBL == 1 && pVendor->PS == 1 )
         {
-          if ((pVendorWork = ( ModePageEXB120VendorUnique_T *)malloc(pVendor->ParameterListLength + 2)) == NULL)
-            {
-              DebugPrint(DEBUG_ERROR, SECTION_BARCODE,"EXB_BarCode : malloc failed\n");
-              return(-1);
-            }
+          pVendorWork = alloc((size_t)pVendor->ParameterListLength + 2);
           DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : setting NBL to 1\n");
-          memcpy(pVendorWork, pVendor, pVendor->ParameterListLength + 2);
+          memcpy(pVendorWork, pVendor, (size_t)pVendor->ParameterListLength + 2);
           pVendorWork->NBL = 0;
           pVendorWork->PS = 0;
           pVendorWork->RSVD0 = 0;
-          if (SCSI_ModeSelect(DeviceFD, (char *)pVendorWork, pVendorWork->ParameterListLength + 2, 0, 1, 0) == 0)
+          if (SCSI_ModeSelect(DeviceFD, (u_char *)pVendorWork, (u_char)(pVendorWork->ParameterListLength + 2), 0, 1, 0) == 0)
             {
               DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : SCSI_ModeSelect OK\n");
               /* Hack !!!!!!
@@ -2010,38 +2153,51 @@ int EXB_BarCode(int DeviceFD)
             } else {
               DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : SCSI_ModeSelect failed\n");
             }
-           amfree(pVendorWork);
+            amfree(pVendorWork);
         }
-      dump_hex((char *)pDev[INDEX_CHANGER].inquiry, INQUIRY_SIZE, DEBUG_INFO, SECTION_BARCODE);
+      dump_hex((u_char *)pDev[INDEX_CHANGER].inquiry, INQUIRY_SIZE, DEBUG_INFO, SECTION_BARCODE);
       DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : vendor_specific[19] %x\n",
                 pDev[INDEX_CHANGER].inquiry->vendor_specific[19]);
     }
-
   return(1);
 }
 
-int NoBarCode(int DeviceFD)
+int
+NoBarCode(
+    int DeviceFD)
 {
+  (void)DeviceFD;      /* Quiet unused parameter warning */
+
   DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START NoBarCode\n");
   DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP  NoBarCode\n");
   return(0);
 }
 
-int GenericBarCode(int DeviceFD)
+int
+GenericBarCode(
+    int                DeviceFD)
 {
-  extern changer_t chg;
+  (void)DeviceFD;      /* Quiet unused parameter warning */
 
   DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START GenericBarCode\n");
-  if ( chg.havebarcode  >= 1)
+  if ( changer->havebarcode  >= 1)
     {
-      DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP GenericBarCode (havebarcode) => %d\n",chg.havebarcode);
+      DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP GenericBarCode (havebarcode) => %d\n",changer->havebarcode);
       return(1);
+      /*NOTREACHED*/
     }
   DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP GenericBarCode => 0\n");
   return(0);
 }
 
-int SenseHandler(int DeviceFD, unsigned char flag, unsigned char SenseKey, unsigned char AdditionalSenseCode, unsigned char AdditionalSenseCodeQualifier, char *buffer)
+int
+SenseHandler(
+    int                        DeviceFD,
+    u_char             flag,
+    u_char             SenseKey,
+    u_char             AdditionalSenseCode,
+    u_char             AdditionalSenseCodeQualifier,
+    RequestSense_T *   buffer)
 {
   extern OpenFiles_T *pDev;
   int ret = 0;
@@ -2069,13 +2225,14 @@ int SenseHandler(int DeviceFD, unsigned char flag, unsigned char SenseKey, unsig
  * if there are more than one
  * Implement the SCSI path if available
 */
-int TapeStatus()
+int
+TapeStatus(void)
 {
   extern OpenFiles_T *pDev;
   int ret;
-  int true = 1;
-  int cnt = 0;
-  RequestSense_T *pRequestSense = NULL;
+  int done;
+  int cnt;
+  RequestSense_T *pRequestSense;
 
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START TapeStatus\n");
 
@@ -2086,13 +2243,10 @@ int TapeStatus()
    */
   if (pDev[INDEX_TAPECTL].SCSI == 1)
     {
-      if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
-       {
-         dbprintf(("%-20s : malloc failed\n","TapeStatus"));
-         return(-1);
-       }
+      pRequestSense = alloc(SIZEOF(RequestSense_T));
+      memset(pRequestSense, 0, SIZEOF(RequestSense_T));
 
-      while (true && cnt < 60)
+      for (done = 0, cnt = 0; !done && (cnt < 60); cnt++)
        {
          ret = SCSI_TestUnitReady(INDEX_TAPECTL, pRequestSense);
          DebugPrint(DEBUG_INFO, SECTION_SCSI, "TapeStatus TestUnitReady ret %d\n",ret);
@@ -2100,49 +2254,58 @@ int TapeStatus()
            {
            case SCSI_OK:
            case SCSI_SENSE:
-             switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+             switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
                {
                case SENSE_IGNORE:
                case SENSE_NO:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_NO\n");
                  pDTE[0].status = 'F';
                  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### FULL\n");
-                 true = 0;
+                 done = 1;
                  break;
+
                case SENSE_TAPE_NOT_ONLINE:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
                  pDTE[0].status = 'E';
                  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### EMPTY\n");
-                 true = 0;
+                 done = 1;
                  break;
+
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_ABORT\n");
-                 true = 0;
+                 done = 1;
                  break;
+
                case SENSE_RETRY:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_RETRY\n");
                  break;
+
                default:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) default (SENSE)\n");
                  break;
                }
              break;
+
            case SCSI_ERROR:
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeStatus (TestUnitReady) SCSI_ERROR\n");
-             true = 0;
+             done = 1;
              break;
+
            case SCSI_BUSY:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SCSI_BUSY\n");
              break;
+
            case SCSI_CHECK:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SCSI_CHECK\n");
              break;
+
            default:
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeStatus (TestUnitReady) unknown (%d)\n",ret);
              break;
+
            }
-         sleep(2);
-         cnt++;
+         if (!done)
+           sleep(2);
        }
         amfree(pRequestSense);
     } else {
@@ -2160,7 +2323,10 @@ int TapeStatus()
     return(0);
 }
 
-int DLT4000Eject(char *Device, int type)
+int
+DLT4000Eject(
+    char *     Device,
+    int                type)
 {
   extern OpenFiles_T *pDev;
 
@@ -2168,22 +2334,14 @@ int DLT4000Eject(char *Device, int type)
   ExtendedRequestSense_T *pExtendedRequestSense;
   int ret;
   int cnt = 0;
-  int true = 1;
+  int done;
 
-  dbprintf(("##### START DLT4000Eject\n"));
+  (void)Device;        /* Quiet unused parameter warning */
 
-  if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
-    {
-      dbprintf(("%-20s : malloc failed\n","DLT4000Eject"));
-      return(-1);
-    }
+  dbprintf(("##### START DLT4000Eject\n"));
 
-  if ((pExtendedRequestSense = malloc(sizeof(ExtendedRequestSense_T))) == NULL)
-    {
-      dbprintf(("%-20s : malloc failed\n","DLT4000Eject"));
-      free(pRequestSense);
-      return(-1);
-    }
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
+  pExtendedRequestSense = alloc(SIZEOF(ExtendedRequestSense_T));
 
   if ( type > 1)
     {
@@ -2191,6 +2349,7 @@ int DLT4000Eject(char *Device, int type)
       free(pExtendedRequestSense);
       free(pRequestSense);
       return(Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT));
+      /*NOTREACHED*/
     }
 
 
@@ -2201,6 +2360,7 @@ int DLT4000Eject(char *Device, int type)
       free(pExtendedRequestSense);
       free(pRequestSense);
       return(Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT));
+      /*NOTREACHED*/
     }
 
 
@@ -2221,44 +2381,46 @@ int DLT4000Eject(char *Device, int type)
       free(pExtendedRequestSense);
       free(pRequestSense);
       return(-1);
+      /*NOTREACHED*/
     }
 
-  true = 1;
-  while (true && cnt < 300)
+  done = 0;
+  while (!done && cnt < 300)
     {
       ret = SCSI_TestUnitReady(INDEX_TAPECTL, pRequestSense);
       DebugPrint(DEBUG_INFO, SECTION_SCSI, "DLT4000Eject TestUnitReady ret %d\n",ret);
       switch (ret)
        {
        case SCSI_OK:
-         true = 0;
+         done = 1;
          break;
        case SCSI_SENSE:
-         switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+         switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
            {
            case SENSE_NO:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_NO\n");
-             true = 0;
+             done = 1;
              break;
            case SENSE_TAPE_NOT_ONLINE:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
-             true = 0;
+             done = 1;
              break;
            case SENSE_IGNORE:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_IGNORE\n");
-             true = 0;
+             done = 1;
              break;
            case SENSE_ABORT:
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_ABORT\n");
              free(pExtendedRequestSense);
              free(pRequestSense);
              return(-1);
+             /*NOTREACHED*/
            case SENSE_RETRY:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_RETRY\n");
              break;
            default:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) default (SENSE)\n");
-             true = 0;
+             done = 1;
              break;
            }
          break;
@@ -2267,6 +2429,7 @@ int DLT4000Eject(char *Device, int type)
          free(pExtendedRequestSense);
          free(pRequestSense);
          return(-1);
+         /*NOTREACHED*/
        case SCSI_BUSY:
          DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SCSI_BUSY\n");
          break;
@@ -2282,7 +2445,7 @@ int DLT4000Eject(char *Device, int type)
       sleep(2);
     }
 
-  dbprintf(("DLT4000Eject : Ready after %d sec, true = %d\n", cnt * 2, true));
+  dbprintf(("DLT4000Eject : Ready after %d sec, done = %d\n", cnt * 2, done));
 
   free(pExtendedRequestSense);
   free(pRequestSense);
@@ -2298,21 +2461,23 @@ int DLT4000Eject(char *Device, int type)
  * Before unload check if there is an tape in the drive
  *
  */
-int GenericEject(char *Device, int type)
+int
+GenericEject(
+    char *     Device,
+    int                type)
 {
   extern OpenFiles_T *pDev;
   RequestSense_T *pRequestSense;
   int ret;
   int cnt = 0;
-  int true = 1;
+  int done;
+
+  (void)Device;        /* Quiet unused parameter warning */
+  (void)type;  /* Quiet unused parameter warning */
 
   DebugPrint(DEBUG_INFO, SECTION_TAPE, "##### START GenericEject\n");
 
-  if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
-    {
-      DebugPrint(DEBUG_ERROR, SECTION_TAPE, "%-20s : malloc failed\n","GenericEject");
-      return(-1);
-    }
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
 
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericEject : SCSI eject on %s = %s\n",
              pDev[INDEX_TAPECTL].dev, pDev[INDEX_TAPECTL].ConfigName);
@@ -2333,10 +2498,11 @@ int GenericEject(char *Device, int type)
       if (ret < 0) {
        free(pRequestSense);
        return(-1);
+       /*NOTREACHED*/
       }
 
-      true = 1;
-      while (true && cnt < 300)
+      done = 0;
+      while (!done && cnt < 300)
        {
          ret = SCSI_TestUnitReady(INDEX_TAPECTL, pRequestSense);
          DebugPrint(DEBUG_INFO, SECTION_SCSI, "GenericEject TestUnitReady ret %d\n",ret);
@@ -2344,14 +2510,14 @@ int GenericEject(char *Device, int type)
            {
            case SCSI_OK:
            case SCSI_SENSE:
-             switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+             switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
                {
                case SENSE_NO:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_NO\n");
                  break;
                case SENSE_TAPE_NOT_ONLINE:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
-                 true = 0;
+                 done = 1;
                  break;
                case SENSE_IGNORE:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_IGNORE\n");
@@ -2360,6 +2526,7 @@ int GenericEject(char *Device, int type)
                  DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_ABORT\n");
                  free(pRequestSense);
                  return(-1);
+                 /*NOTREACHED*/
                case SENSE_RETRY:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_RETRY\n");
                  break;
@@ -2372,6 +2539,7 @@ int GenericEject(char *Device, int type)
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericEject (TestUnitReady) SCSI_ERROR\n");
              free(pRequestSense);
              return(-1);
+             /*NOTREACHED*/
            case SCSI_BUSY:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SCSI_BUSY\n");
              break;
@@ -2389,7 +2557,8 @@ int GenericEject(char *Device, int type)
       DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericEject : Device can't understand SCSI try ioctl\n");
       Tape_Ioctl(INDEX_TAPECTL, IOCTL_EJECT);
     }
-  DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericEject : Ready after %d sec, true = %d\n", cnt * 2, true);
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,
+            "GenericEject : Ready after %d sec\n", cnt * 2);
   free(pRequestSense);
   return(0);
 }
@@ -2404,15 +2573,17 @@ int GenericEject(char *Device, int type)
  * -1 -> error
  * 0  -> success
  */
-int GenericRewind(int DeviceFD)
+int
+GenericRewind(
+    int                DeviceFD)
 {
   CDB_T CDB;
   extern OpenFiles_T *pDev;
-  RequestSense_T *pRequestSense = NULL;
+  RequestSense_T *pRequestSense;
   char *errstr;                    /* Used by tape_rewind */
   int ret;
   int cnt = 0;
-  int true = 1;
+  int done;
 
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START GenericRewind pDEV -> %d\n",DeviceFD);
 
@@ -2423,51 +2594,49 @@ int GenericRewind(int DeviceFD)
    */
   if (pDev[DeviceFD].SCSI == 1)
     {
-      if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-       {
-          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"GenericRewind : malloc failed\n");
-          return(-1);
-       }
+      pRequestSense = alloc(SIZEOF(RequestSense_T));
+
       /*
        * Before doing the rewind check if the tape is ready to accept commands
        */
 
-      while (true == 1)
+      done = 0;
+      while (!done)
        {
          ret = SCSI_TestUnitReady(DeviceFD, (RequestSense_T *)pRequestSense );
          DebugPrint(DEBUG_INFO, SECTION_TAPE, "GenericRewind (TestUnitReady) ret %d\n",ret);
          switch (ret)
            {
            case SCSI_OK:
-             true= 0;
+             done = 1;
              break;
                    case SCSI_SENSE:
-             switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+             switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
                {
                case SENSE_NO:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_NO\n");
-                 true = 0;
+                 done = 1;
                  break;
                case SENSE_TAPE_NOT_ONLINE:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
                  free(pRequestSense);
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                case SENSE_IGNORE:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_IGNORE\n");
-                 true = 0;
+                 done = 1;
                  break;
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_ABORT\n");
                  free(pRequestSense);
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                case SENSE_RETRY:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_RETRY\n");
                  break;
                default:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) default (SENSE)\n");
-                 true = 0;
+                 done = 1;
                  break;
                }  /* switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey.... */
              break;
@@ -2476,7 +2645,8 @@ int GenericRewind(int DeviceFD)
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_ERROR\n");
              free(pRequestSense);
              return(-1);
-             break;
+             /*NOTREACHED*/
+
            case SCSI_BUSY:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_BUSY\n");
              break;
@@ -2495,11 +2665,11 @@ int GenericRewind(int DeviceFD)
              DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP GenericRewind (-1)\n");
              free(pRequestSense);
              return(-1);
+             /*NOTREACHED*/
            }
-       } /* while true == 1 */
+       } /* while !done */
 
       cnt = 0;
-      true = 1;
 
       CDB[0] = SC_COM_REWIND;
       CDB[1] = 1;
@@ -2508,12 +2678,13 @@ int GenericRewind(int DeviceFD)
       CDB[4] = 0;
       CDB[5] = 0;
 
-      while (true)
+      done = 0;
+      while (!done)
        {
          ret = SCSI_Run(DeviceFD, Input, CDB, 6,
                         NULL, 0,
-                        (char *) pRequestSense,
-                        sizeof(RequestSense_T));
+                        pRequestSense,
+                        SIZEOF(RequestSense_T));
 
          DecodeSense(pRequestSense, "GenericRewind : ", debug_file);
 
@@ -2521,66 +2692,65 @@ int GenericRewind(int DeviceFD)
            {
              if (pRequestSense->SenseKey != UNIT_ATTENTION)
                {
-                 true = 0;
+                 done = 1;
                }
            }
          if (ret == 0)
            {
-             true = 0;
+             done = 1;
            }
          if (ret < 0)
            {
              DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : failed %d\n", ret);
-             true = 0;
+             done = 1;
            }
        }
 
-      true = 1;
-
-      while (true && cnt < 300)
+      done = 0;
+      while (!done && (cnt < 300))
        {
          ret = SCSI_TestUnitReady(DeviceFD, pRequestSense);
          DebugPrint(DEBUG_INFO, SECTION_SCSI, "GenericRewind TestUnitReady ret %d\n",ret);
          switch (ret)
            {
            case SCSI_OK:
-             true = 0;
+             done = 1;
              break;
            case SCSI_SENSE:
-             switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+             switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
                {
                case SENSE_NO:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_NO\n");
-                 true = 0;
+                 done = 1;
                  break;
                case SENSE_TAPE_NOT_ONLINE:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
                  free(pRequestSense);
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                case SENSE_IGNORE:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_IGNORE\n");
-                 true = 0;
+                 done = 1;
                  break;
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_ABORT\n");
                  free(pRequestSense);
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                case SENSE_RETRY:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_RETRY\n");
                  break;
                default:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) default (SENSE)\n");
-                 true = 0;
+                 done = 1;
                  break;
                }
              break;
            case SCSI_ERROR:
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_ERROR\n");
-             free(pRequestSense);
              return(-1);
-             break;
+             /*NOTREACHED*/
+
            case SCSI_BUSY:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_BUSY\n");
              break;
@@ -2598,7 +2768,8 @@ int GenericRewind(int DeviceFD)
 
       amfree(pRequestSense);
 
-      DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : Ready after %d sec, true = %d\n", cnt * 2, true);
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : Ready after %d sec, "
+                       "done = %d\n", cnt * 2, done);
       DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericRewind (0)\n");
     } else {
       DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : use ioctl rewind\n");
@@ -2609,18 +2780,16 @@ int GenericRewind(int DeviceFD)
        }
       /* We don't retry if it fails; that is left to the vtape driver. */
       if ((errstr = tape_rewind(pDev[DeviceFD].dev)) == NULL) {
-          true = 0;
           DebugPrint(DEBUG_INFO, SECTION_TAPE,"Rewind OK,\n", cnt);
       } else {
           DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Rewind failed %s\n",errstr);
           DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericRewind (-1)\n");
-         amfree(pRequestSense);
           return(-1);
+         /*NOTREACHED*/
       }
       DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericRewind (0)\n");
     }
 
-  amfree(pRequestSense);
   return(0);
 }
 
@@ -2630,18 +2799,23 @@ int GenericRewind(int DeviceFD)
  * bit set in the return of an request sense
  *
  */
-int GenericClean(char * Device)
+int
+GenericClean(
+    char *     Device)
 {
   extern OpenFiles_T *pDev;
   ExtendedRequestSense_T ExtRequestSense;
   int ret = 0;
 
+  (void)Device;        /* Quiet unused parameter warning */
+
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START GenericClean\n");
   if (pDev[INDEX_TAPECTL].SCSI == 0)
       {
           DebugPrint(DEBUG_ERROR, SECTION_TAPE,"GenericClean : can't send SCSI commands\n");
          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP GenericClean\n");
           return(0);
+         /*NOTREACHED*/
       }
 
   /*
@@ -2663,7 +2837,9 @@ int GenericClean(char * Device)
   return(ret);
 }
 
-int GenericResetStatus(int DeviceFD)
+int
+GenericResetStatus(
+    int                DeviceFD)
 {
   CDB_T CDB;
   RequestSense_T *pRequestSense;
@@ -2672,11 +2848,7 @@ int GenericResetStatus(int DeviceFD)
 
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START GenericResetStatus\n");
 
-  if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-      {
-          DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericResetStatus : malloc failed\n");
-          return(-1);
-      }
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
 
   while (retry)
     {
@@ -2690,31 +2862,32 @@ int GenericResetStatus(int DeviceFD)
 
       ret = SCSI_Run(DeviceFD, Input, CDB, 6,
                                 NULL, 0,
-                                (char *) pRequestSense,
-                                sizeof(RequestSense_T));
+                                pRequestSense,
+                                SIZEOF(RequestSense_T));
 
       if (ret < 0)
         {
           /*        fprintf(stderr, "%s: Request Sense[Inquiry]: %02X", */
-          /*                "chs", ((unsigned char *) &pRequestSense)[0]); */
-          /*        for (i = 1; i < sizeof(RequestSense_T); i++)                */
-          /*          fprintf(stderr, " %02X", ((unsigned char *) &pRequestSense)[i]); */
+          /*                "chs", ((u_char *) &pRequestSense)[0]); */
+          /*        for (i = 1; i < SIZEOF(RequestSense_T); i++)                */
+          /*          fprintf(stderr, " %02X", ((u_char *) &pRequestSense)[i]); */
           /*        fprintf(stderr, "\n");    */
          free(pRequestSense);
           return(ret);
+         /*NOTREACHED*/
         }
       if ( ret > 0 )
         {
-          switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+          switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
             {
             case SENSE_IGNORE:
              free(pRequestSense);
               return(0);
-              break;
+              /*NOTREACHED*/
             case SENSE_ABORT:
              free(pRequestSense);
               return(-1);
-              break;
+              /*NOTREACHED*/
             case SENSE_RETRY:
               retry++;
               if (retry < MAX_RETRIES )
@@ -2725,13 +2898,14 @@ int GenericResetStatus(int DeviceFD)
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericResetStatus : return (-1)\n");
                  free(pRequestSense);
                   return(-1);
+                 /*NOTREACHED*/
                 }
               break;
             default:
              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericResetStatus :  (default) return (-1)\n");
              free(pRequestSense);
               return(-1);
-              break;
+              /*NOTREACHED*/
             }
         }
       if (ret == 0)
@@ -2756,12 +2930,18 @@ int GenericResetStatus(int DeviceFD)
  * TODO:
  * Limit recursion, may run in an infinite loop
  */
-int GenericSenseHandler(int ip, int flag, unsigned char SenseKey, unsigned char AdditionalSenseCode, unsigned char AdditionalSenseCodeQualifier, char *buffer)
+int
+GenericSenseHandler(
+    int                        ip,
+    u_char             flag,
+    u_char             SenseKey,
+    u_char             AdditionalSenseCode,
+    u_char             AdditionalSenseCodeQualifier,
+    RequestSense_T *   pRequestSense)
 {
   extern OpenFiles_T *pDev;
-  RequestSense_T *pRequestSense = (RequestSense_T *)buffer;
-  int ret = 0;
-  unsigned char *info = NULL;
+  int ret;
+  char *info = NULL;
 
   dbprintf(("##### START GenericSenseHandler\n"));
 
@@ -2772,7 +2952,7 @@ int GenericSenseHandler(int ip, int flag, unsigned char SenseKey, unsigned char
                     flag, SenseKey,
                     AdditionalSenseCode,
                     AdditionalSenseCodeQualifier,
-                    (char **)&info);
+                    &info);
 
   dbprintf(("##### STOP GenericSenseHandler\n"));
   return(ret);
@@ -2790,14 +2970,18 @@ int GenericSenseHandler(int ip, int flag, unsigned char SenseKey, unsigned char
  *                 the element handling
  * TODO:
 */
-int SDXMove(int DeviceFD, int from, int to)
+int
+SDXMove(
+    int                DeviceFD,
+    int                from,
+    int                to)
 {
   extern OpenFiles_T *pDev;
   ElementInfo_T *pfrom;
   ElementInfo_T *pto;
   int ret;
   int tapestat;
-  int moveok = 0;
+  int moveok;
   int SDX_MTE = 0;      /* This are parameters  passed */
   int SDX_STE = -1;     /* to                          */
   int SDX_DTE = -1;     /* AlignElements               */
@@ -2812,6 +2996,7 @@ int SDXMove(int DeviceFD, int from, int to)
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : ElementInfo for %d not found\n", from);
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   if ((pto = LookupElement(to)) == NULL)
@@ -2819,6 +3004,7 @@ int SDXMove(int DeviceFD, int from, int to)
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : ElementInfo for %d not found\n", to);
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   if (pfrom->status == 'E')
@@ -2826,6 +3012,7 @@ int SDXMove(int DeviceFD, int from, int to)
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : from %d is empty\n", from);
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   if (pto->status == 'F')
@@ -2842,6 +3029,7 @@ int SDXMove(int DeviceFD, int from, int to)
            {
                    DebugPrint(DEBUG_ERROR, SECTION_MOVE,"SDXMove : no empty slot found for unload\n");
                    return(-1);
+                   /*NOTREACHED*/
            }
             DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : Unload to %d\n", to);
             if ((pto = LookupElement(to)) == NULL)
@@ -2849,6 +3037,7 @@ int SDXMove(int DeviceFD, int from, int to)
              DebugPrint(DEBUG_INFO, SECTION_MOVE, "SDXMove : ElementInfo for %d not found\n", to);
              DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
              return(-1);
+             /*NOTREACHED*/
             }
            break;
          case IMPORT:
@@ -2894,11 +3083,13 @@ int SDXMove(int DeviceFD, int from, int to)
     {
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
       return(-1);
+      /*NOTREACHED*/
     }
   } else {
     DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### Error setting STE/DTE %d/%d\n", SDX_STE, SDX_DTE);
     DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
     return(-1);
+    /*NOTREACHED*/
   }
 
   /*
@@ -2919,12 +3110,13 @@ int SDXMove(int DeviceFD, int from, int to)
     }
   }
 
-  if ( ret == 0)
+  if ((ret == 0) && moveok)
   {
     ret = SCSI_Move(DeviceFD, 0, from, to);
   } else {
     DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
     return(ret);
+    /*NOTREACHED*/
   }
   DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
   return(ret);
@@ -2940,7 +3132,11 @@ int SDXMove(int DeviceFD, int from, int to)
  *                 the element handling
  * TODO:
 */
-int GenericMove(int DeviceFD, int from, int to)
+int
+GenericMove(
+    int                DeviceFD,
+    int                from,
+    int                to)
 {
   ElementInfo_T *pfrom;
   ElementInfo_T *pto;
@@ -2956,6 +3152,7 @@ int GenericMove(int DeviceFD, int from, int to)
       DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : ElementInfo for %d not found\n", from);
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   if ((pto = LookupElement(to)) == NULL)
@@ -2963,6 +3160,7 @@ int GenericMove(int DeviceFD, int from, int to)
       DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : ElementInfo for %d not found\n", to);
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   if (pfrom->status == 'E')
@@ -2970,6 +3168,7 @@ int GenericMove(int DeviceFD, int from, int to)
       DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : from %d is empty\n", from);
       DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   if (pto->status == 'F')
@@ -2981,6 +3180,7 @@ int GenericMove(int DeviceFD, int from, int to)
       {
              DebugPrint(DEBUG_ERROR, SECTION_MOVE, "GenericMove : no empty slot found\n");
              return(-1);
+             /*NOTREACHED*/
       }
       DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : Unload to %d\n", to);
       if ((pto = LookupElement(to)) == NULL)
@@ -2988,6 +3188,7 @@ int GenericMove(int DeviceFD, int from, int to)
           DebugPrint(DEBUG_ERROR, SECTION_MOVE, " Ups should not happen\n");
          DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
          return(-1);
+         /*NOTREACHED*/
         }
     }
 
@@ -3009,7 +3210,10 @@ int GenericMove(int DeviceFD, int from, int to)
  * 0 => Not OK
  */
 
-int CheckMove(ElementInfo_T *from, ElementInfo_T *to)
+int
+CheckMove(
+    ElementInfo_T *    from,
+    ElementInfo_T *    to)
 {
        int moveok = 0;
 
@@ -3181,16 +3385,22 @@ int CheckMove(ElementInfo_T *from, ElementInfo_T *to)
 /*
  */
 
-int GetCurrentSlot(int fd, int drive)
+int
+GetCurrentSlot(
+    int                fd,
+    int                drive)
 {
   extern OpenFiles_T *pDev;
-  int x;
+  size_t x;
   dbprintf(("##### START GetCurrentSlot\n"));
 
+  (void)fd;    /* Quiet unused parameter warning */
+
   if (pDev[0].SCSI == 0)
       {
           dbprintf(("GetCurrentSlot : can't send SCSI commands\n"));
           return(-1);
+         /*NOTREACHED*/
       }
 
   if (ElementStatusValid == 0)
@@ -3198,6 +3408,7 @@ int GetCurrentSlot(int fd, int drive)
       if (pDev[0].functions->function_status(0, 1) != 0)
         {
           return(-1);
+         /*NOTREACHED*/
         }
     }
 
@@ -3208,14 +3419,18 @@ int GetCurrentSlot(int fd, int drive)
         {
           if (pSTE[x].address == pDTE[drive].from)
             return(x);
+           /*NOTREACHED*/
         }
       return(-1);
+      /*NOTREACHED*/
     }
 
   for (x = 0; x < STE;x++)
     {
-      if (pSTE[x].status == 'E')
-        return(x);
+      if (pSTE[x].status == 'E') {
+          return(x);
+         /*NOTREACHED*/
+        }
     }
 
   /* Ups nothing loaded */
@@ -3233,19 +3448,23 @@ int GetCurrentSlot(int fd, int drive)
  * If there are error conditions try to fix them
  *
  */
-int GenericElementStatus(int DeviceFD, int InitStatus)
+int
+GenericElementStatus(
+    int                DeviceFD,
+    int                InitStatus)
 {
   int MTEError = 0;
   int STEError = 0;
   int IEEError = 0;
   int DTEError = 0;
-  int STEEmpty = 0;
 
   extern OpenFiles_T *pDev;
 
-  int error = 0;   /* If set do an INIT ELEMENT STATUS */
-  int x;           /* The standard loop counter :-) */
-  int loop = 2;    /* Redo it if an error has been reset */
+  int error = 0;    /* If set do an INIT ELEMENT STATUS */
+  size_t x;         /* The standard loop counter :-) */
+  int retry = 2;    /* Redo it if an error has been reset */
+
+  (void)InitStatus;    /* Quiet unused parameter warning */
 
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START GenericElementStatus\n");
 
@@ -3258,11 +3477,8 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
        */
       if (pModePage == NULL && LibModeSenseValid == 0)
         {
-          if ((pModePage = malloc(0xff)) == NULL)
-            {
-              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-              return(-1);
-            }
+          pModePage = alloc(0xff);
+
          if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
            {
              LibModeSenseValid = 1;
@@ -3274,14 +3490,13 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
         }
     }
 
-  if (GetElementStatus(DeviceFD) == 0 && loop > 0)
+  while ((GetElementStatus(DeviceFD) == 0) && (retry-- > 0))
     {
-      loop--;
       for (x = 0; x < MTE; x++)
        {
          if (pMTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (char *)&pMTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (RequestSense_T *)&pMTE[x]))
                {
                case SENSE_IES:
                  MTEError = 1;
@@ -3290,7 +3505,7 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on MTE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3299,7 +3514,7 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
        {
          if (pIEE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&pIEE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (RequestSense_T *)&pIEE[x]))
                {
                case SENSE_IES:
                  IEEError = 1;
@@ -3308,7 +3523,7 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on IEE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3316,18 +3531,9 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
 
       for (x = 0; x < STE; x++)
        {
-         /*
-          * Needed for the hack to guess the tape status if an error
-          * for the tape is pending
-          */
-         if (pSTE[x].status == 'E')
-           {
-             STEEmpty = 1;
-           }
-
          if (pSTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (char *)&pSTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (RequestSense_T *)&pSTE[x]))
                {
                case SENSE_IES:
                  STEError = 1;
@@ -3336,7 +3542,7 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on IES\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3345,7 +3551,7 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
        {
          if (pDTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (RequestSense_T *)&pDTE[x]))
                {
                case SENSE_IES:
                  DTEError = 1;
@@ -3354,7 +3560,7 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on DTE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3371,6 +3577,7 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
              ElementStatusValid = 0;
              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Can't init status STEError(%d) MTEError(%d) DTEError(%d) IEEError(%d)\n", STEError, MTEError, DTEError, IEEError);
              return(-1);
+             /*NOTREACHED*/
            }
          error = 0;
        }
@@ -3395,6 +3602,7 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
     {
       DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Can't init status (after loop)\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   ElementStatusValid = 1;
@@ -3407,20 +3615,21 @@ int GenericElementStatus(int DeviceFD, int InitStatus)
  * This is for the ADIC changer, it seems that they have an diferent
  * offset in the mode sense data before the first mode page (+12)
  */
-int DLT448ElementStatus(int DeviceFD, int InitStatus)
+int
+DLT448ElementStatus(
+    int                DeviceFD,
+    int                InitStatus)
 {
-  int MTEError = 0;
-  int STEError = 0;
-  int IEEError = 0;
   int DTEError = 0;
-  int STEEmpty = 0;
 
   extern OpenFiles_T *pDev;
 
   int error = 0;   /* If set do an INIT ELEMENT STATUS */
-  int x;           /* The standard loop counter :-) */
+  size_t x;        /* The standard loop counter :-) */
   int loop = 2;    /* Redo it if an error has been reset */
 
+  (void)InitStatus;    /* Quiet unused parameter warning */
+
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START DLT448ElementStatus\n");
 
   if (pEAAPage == NULL)
@@ -3432,11 +3641,8 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
        */
       if (pModePage == NULL && LibModeSenseValid == 0)
         {
-          if ((pModePage = malloc(0xff)) == NULL)
-            {
-              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"DLT448ElementStatus : malloc failed\n");
-              return(-1);
-            }
+          pModePage = alloc(0xff);
+
          if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
            {
              LibModeSenseValid = 1;
@@ -3448,23 +3654,21 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
         }
     }
 
-  if (GetElementStatus(DeviceFD) == 0 && loop > 0)
+  while (GetElementStatus(DeviceFD) == 0 && loop-- > 0)
     {
-      loop--;
       for (x = 0; x < MTE; x++)
        {
          if (pMTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (char *)&pMTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (RequestSense_T *)&pMTE[x]))
                {
                case SENSE_IES:
-                 MTEError = 1;
                  error = 1;
                  break;
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on MTE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3473,16 +3677,15 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
        {
          if (pIEE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&pIEE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (RequestSense_T *)&pIEE[x]))
                {
                case SENSE_IES:
-                 IEEError = 1;
                  error = 1;
                  break;
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on IEE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3494,23 +3697,17 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
           * Needed for the hack to guess the tape status if an error
           * for the tape is pending
           */
-         if (pSTE[x].status == 'E')
-           {
-             STEEmpty = 1;
-           }
-
          if (pSTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (char *)&pSTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (RequestSense_T *)&pSTE[x]))
                {
                case SENSE_IES:
-                 STEError = 1;
                  error = 1;
                  break;
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on IES\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3519,7 +3716,7 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
        {
          if (pDTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (RequestSense_T *)&pDTE[x]))
                {
                case SENSE_IES:
                  DTEError = 1;
@@ -3528,7 +3725,7 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on DTE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3545,6 +3742,7 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
              ElementStatusValid = 0;
              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Can't init status\n");
              return(-1);
+             /*NOTREACHED*/
            }
          error = 0;
        }
@@ -3569,6 +3767,7 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
     {
       DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Can't init status (after loop)\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   ElementStatusValid = 1;
@@ -3582,17 +3781,17 @@ int DLT448ElementStatus(int DeviceFD, int InitStatus)
  * it seemes that for the STE Elements ASC/ASCQ is not set
  * on an error, only the except bit is set
 */
-int SDXElementStatus(int DeviceFD, int InitStatus)
+int
+SDXElementStatus(
+    int                DeviceFD,
+    int                InitStatus)
 {
-  int MTEError = 0;
-  int STEError = 0;
-  int IEEError = 0;
-  int DTEError = 0;
-
   int error = 0;   /* If set do an INIT ELEMENT STATUS */
-  int x;           /* The standard loop counter :-) */
+  size_t x;        /* The standard loop counter :-) */
   int loop = 2;    /* Redo it if an error has been reset */
 
+  (void)InitStatus;    /* Quiet unused parameter warning */
+
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START SDXElementStatus\n");
 
   if (pEAAPage == NULL)
@@ -3604,11 +3803,8 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
        */
       if (pModePage == NULL && LibModeSenseValid == 0)
         {
-          if ((pModePage = malloc(0xff)) == NULL)
-            {
-              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"SDXElementStatus : malloc failed\n");
-              return(-1);
-            }
+          pModePage = alloc(0xff);
+
          if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
            {
              LibModeSenseValid = 1;
@@ -3620,24 +3816,22 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
         }
     }
 
-  if (GetElementStatus(DeviceFD) == 0 && loop)
+  while (GetElementStatus(DeviceFD) == 0 && loop--)
     {
-      loop--;
       error = 0;
       for (x = 0; x < MTE; x++)
        {
          if (pMTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (char *)&pMTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (RequestSense_T *)&pMTE[x]))
                {
                case SENSE_IES:
-                 MTEError = 1;
                  error = 1;
                  break;
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on MTE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3646,16 +3840,15 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
        {
          if (pIEE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&pIEE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (RequestSense_T *)&pIEE[x]))
                {
                case SENSE_IES:
-                 IEEError = 1;
                  error = 1;
                  break;
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on IEE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3663,23 +3856,17 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
 
       for (x = 0; x < STE; x++)
        {
-         if (pSTE[x].except != 0)
-           {
-             STEError = 1;
-           }
-
          if (pSTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (char *)&pSTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (RequestSense_T *)&pSTE[x]))
                {
                case SENSE_IES:
-                 STEError = 1;
                  error = 1;
                  break;
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on IES\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3688,10 +3875,9 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
        {
          if (pDTE[x].ASC > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (RequestSense_T *)&pDTE[x]))
                {
                case SENSE_IES:
-                 DTEError = 1;
                  /*
                  error = 1;
                  */
@@ -3699,7 +3885,7 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
                case SENSE_ABORT:
                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on DTE\n");
                  return(-1);
-                 break;
+                 /*NOTREACHED*/
                }
            }
        }
@@ -3716,6 +3902,7 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
              ElementStatusValid = 0;
              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Can't init status\n");
              return(-1);
+             /*NOTREACHED*/
            }
        }
 
@@ -3726,6 +3913,7 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
     {
       DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Can't init status\n");
       return(-1);
+      /*NOTREACHED*/
     }
 
   ElementStatusValid = 1;
@@ -3749,21 +3937,22 @@ int SDXElementStatus(int DeviceFD, int InitStatus)
  *
  * TODO:
  */
-int GetElementStatus(int DeviceFD)
+int
+GetElementStatus(
+    int DeviceFD)
 {
-  unsigned char *DataBuffer = NULL;
-  int DataBufferLength;
+  u_char *DataBuffer = NULL;
+  size_t DataBufferLength;
   ElementStatusData_T *ElementStatusData;
   ElementStatusPage_T *ElementStatusPage;
   MediumTransportElementDescriptor_T *MediumTransportElementDescriptor;
   StorageElementDescriptor_T *StorageElementDescriptor;
   DataTransferElementDescriptor_T *DataTransferElementDescriptor;
   ImportExportElementDescriptor_T *ImportExportElementDescriptor;
-  int x = 0;
-  int offset = 0;
-  int length = 0;      /* Length of an Element */
-  int barcode = 0;      /* To store the result of the BarCode function */
-  int NoOfElements;
+  size_t x;
+  size_t offset;
+  size_t length;       /* Length of an Element */
+  size_t NoOfElements;
 
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### START GetElementStatus\n");
 
@@ -3778,35 +3967,31 @@ int GetElementStatus(int DeviceFD)
       /* First the Medim Transport*/
       if (V2(pEAAPage->NoMediumTransportElements)  > 0)
         {
-          free(pMTE);
           MTE = V2(pEAAPage->NoMediumTransportElements) ;
-          if ((pMTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * MTE)) == NULL)
-            {
-               DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-               return(-1);
-            }
-          memset(pMTE, 0, sizeof(ElementInfo_T) * MTE);
+          pMTE = alloc(SIZEOF(ElementInfo_T) * MTE);
+          memset(pMTE, 0, SIZEOF(ElementInfo_T) * MTE);
 
           if (SCSI_ReadElementStatus(DeviceFD,
                                      CHANGER,
                                      0,
-                                     barcode,
+                                     (u_char)barcode,
                                      V2(pEAAPage->MediumTransportElementAddress),
-                                     MTE+1,
-                                    sizeof(MediumTransportElementDescriptor_T),
-                                     (char **)&DataBuffer) != 0)
+                                     (MTE + (size_t)1),
+                                    SIZEOF(MediumTransportElementDescriptor_T),
+                                     &DataBuffer) != 0)
             {
-             free(pMTE);
-             free(DataBuffer);
               ChgExit("genericElementStatus","Can't read MTE status", FATAL);
+             /*NOTREACHED*/
             }
-          ElementStatusData = (ElementStatusData_T *)DataBuffer;
-          offset = sizeof(ElementStatusData_T);
+          // ElementStatusData = (ElementStatusData_T *)DataBuffer;
+          offset = SIZEOF(ElementStatusData_T);
 
           ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
-          offset = offset + sizeof(ElementStatusPage_T);
+          offset = offset + SIZEOF(ElementStatusPage_T);
          length = V2(ElementStatusPage->length);
-          DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"MTE Length %d(%d)\n",length,sizeof(MediumTransportElementDescriptor_T));
+
+          DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"MTE Length %d(%d)\n", length,
+                       SIZEOF(MediumTransportElementDescriptor_T));
 
           for (x = 0; x < MTE; x++)
             {
@@ -3823,8 +4008,13 @@ int GetElementStatus(int DeviceFD)
               pMTE[x].type = ElementStatusPage->type;
               pMTE[x].address = V2(MediumTransportElementDescriptor->address);
               pMTE[x].except = MediumTransportElementDescriptor->except;
-              pMTE[x].status = (MediumTransportElementDescriptor->full > 0) ? 'F':'E';
               pMTE[x].full = MediumTransportElementDescriptor->full;
+             if (MediumTransportElementDescriptor->full > 0)
+               {
+                  pMTE[x].status = 'F';
+               } else {
+                  pMTE[x].status = 'E';
+               }
 
              if (length >= 5)
                {
@@ -3853,6 +4043,8 @@ int GetElementStatus(int DeviceFD)
                }
              offset = offset + length;
             }
+           free(DataBuffer);
+           DataBuffer = NULL;
         }
       /*
        * Storage Elements
@@ -3861,32 +4053,28 @@ int GetElementStatus(int DeviceFD)
         {
           free(pSTE);
           STE = V2(pEAAPage->NoStorageElements);
-          if ((pSTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * STE)) == NULL)
-            {
-              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-             free(pMTE);
-              return(-1);
-            }
-          memset(pSTE, 0, sizeof(ElementInfo_T) * STE);
+          pSTE = alloc(SIZEOF(ElementInfo_T) * STE);
+          memset(pSTE, 0, SIZEOF(ElementInfo_T) * STE);
 
           if (SCSI_ReadElementStatus(DeviceFD,
                                      STORAGE,
                                      0,
-                                     barcode,
+                                     (u_char)barcode,
                                      V2(pEAAPage->FirstStorageElementAddress),
                                      STE,
-                                    sizeof(StorageElementDescriptor_T),
-                                     (char **)&DataBuffer) != 0)
+                                    SIZEOF(StorageElementDescriptor_T),
+                                     &DataBuffer) != 0)
             {
-             free(DataBuffer);
               ChgExit("GetElementStatus", "Can't read STE status", FATAL);
+             /*NOTREACHED*/
             }
+         assert(DataBuffer != NULL);
 
-          ElementStatusData = (ElementStatusData_T *)DataBuffer;
-          offset = sizeof(ElementStatusData_T);
+          // ElementStatusData = (ElementStatusData_T *)DataBuffer;
+          offset = SIZEOF(ElementStatusData_T);
 
           ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
-          offset = offset + sizeof(ElementStatusPage_T);
+          offset = offset + SIZEOF(ElementStatusPage_T);
          length = V2(ElementStatusPage->length);
           DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"STE Length %d\n",length);
 
@@ -3905,8 +4093,13 @@ int GetElementStatus(int DeviceFD)
               pSTE[x].type = ElementStatusPage->type;
               pSTE[x].address = V2(StorageElementDescriptor->address);
               pSTE[x].except = StorageElementDescriptor->except;
-              pSTE[x].status = (StorageElementDescriptor->full > 0) ? 'F':'E';
               pSTE[x].full = StorageElementDescriptor->full;
+              if (StorageElementDescriptor->full > 0)
+               {
+                 pSTE[x].status = 'F';
+               } else {
+                 pSTE[x].status = 'E';
+               }
 
              if (length >= 5)
                {
@@ -3936,7 +4129,8 @@ int GetElementStatus(int DeviceFD)
 
               offset = offset + length;
             }
-
+           free(DataBuffer);
+           DataBuffer = NULL;
         }
       /*
        * Import/Export Elements
@@ -3945,35 +4139,28 @@ int GetElementStatus(int DeviceFD)
         {
           free(pIEE);
           IEE = V2(pEAAPage->NoImportExportElements);
-          if ((pIEE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * IEE)) == NULL)
-            {
-                DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-               free(DataBuffer);
-                return(-1);
-            }
-          memset(pIEE, 0, sizeof(ElementInfo_T) * IEE);
+          pIEE = alloc(SIZEOF(ElementInfo_T) * IEE);
+          memset(pIEE, 0, SIZEOF(ElementInfo_T) * IEE);
 
           if (SCSI_ReadElementStatus(DeviceFD,
                                      IMPORT,
                                      0,
-                                     barcode,
+                                     (u_char)barcode,
                                      V2(pEAAPage->FirstImportExportElementAddress),
                                      IEE,
-                                    sizeof(ImportExportElementDescriptor_T),
-                                     (char **)&DataBuffer) != 0)
+                                    SIZEOF(ImportExportElementDescriptor_T),
+                                     &DataBuffer) != 0)
             {
-              if (DataBuffer != 0)
-               {
-                 free(DataBuffer);
-               }
               ChgExit("GetElementStatus", "Can't read IEE status", FATAL);
+             /*NOTREACHED*/
             }
+         assert(DataBuffer != NULL);
 
-          ElementStatusData = (ElementStatusData_T *)DataBuffer;
-          offset = sizeof(ElementStatusData_T);
+          // ElementStatusData = (ElementStatusData_T *)DataBuffer;
+          offset = SIZEOF(ElementStatusData_T);
 
           ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
-          offset = offset + sizeof(ElementStatusPage_T);
+          offset = offset + SIZEOF(ElementStatusPage_T);
          length = V2(ElementStatusPage->length);
           DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"IEE Length %d\n",length);
 
@@ -3990,8 +4177,13 @@ int GetElementStatus(int DeviceFD)
               pIEE[x].type = ElementStatusPage->type;
               pIEE[x].address = V2(ImportExportElementDescriptor->address);
               pIEE[x].except = ImportExportElementDescriptor->except;
-              pIEE[x].status = (ImportExportElementDescriptor->full > 0) ? 'F':'E';
               pIEE[x].full = ImportExportElementDescriptor->full;
+             if (ImportExportElementDescriptor->full > 0)
+               {
+                 pIEE[x].status = 'F';
+               } else {
+                 pIEE[x].status = 'E';
+               }
 
              if (length >= 5)
                {
@@ -4021,7 +4213,8 @@ int GetElementStatus(int DeviceFD)
 
               offset = offset + length;
             }
-
+           free(DataBuffer);
+           DataBuffer = NULL;
         }
       /*
        * Data Transfer Elements
@@ -4030,32 +4223,28 @@ int GetElementStatus(int DeviceFD)
         {
          free(pDTE);
           DTE = V2(pEAAPage->NoDataTransferElements) ;
-          if ((pDTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * DTE)) == NULL)
-            {
-              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-             free(DataBuffer);
-              return(-1);
-            }
-          memset(pDTE, 0, sizeof(ElementInfo_T) * DTE);
+          pDTE = alloc(SIZEOF(ElementInfo_T) * DTE);
+          memset(pDTE, 0, SIZEOF(ElementInfo_T) * DTE);
 
           if (SCSI_ReadElementStatus(DeviceFD,
                                      TAPETYPE,
                                      0,
-                                     barcode,
+                                     (u_char)barcode,
                                      V2(pEAAPage->FirstDataTransferElementAddress),
                                      DTE,
-                                    sizeof(DataTransferElementDescriptor_T),
-                                     (char **)&DataBuffer) != 0)
+                                    SIZEOF(DataTransferElementDescriptor_T),
+                                     &DataBuffer) != 0)
             {
-             free(DataBuffer);
               ChgExit("GenericElementStatus", "Can't read DTE status", FATAL);
+             /*NOTREACHED*/
             }
+         assert(DataBuffer != NULL);
 
-          ElementStatusData = (ElementStatusData_T *)DataBuffer;
-          offset = sizeof(ElementStatusData_T);
+          // ElementStatusData = (ElementStatusData_T *)DataBuffer;
+          offset = SIZEOF(ElementStatusData_T);
 
           ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
-          offset = offset + sizeof(ElementStatusPage_T);
+          offset = offset + SIZEOF(ElementStatusPage_T);
          length = V2(ElementStatusPage->length);
           DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"DTE Length %d\n",length);
 
@@ -4073,8 +4262,13 @@ int GetElementStatus(int DeviceFD)
              pDTE[x].address = V2(DataTransferElementDescriptor->address);
               pDTE[x].except = DataTransferElementDescriptor->except;
               pDTE[x].scsi = DataTransferElementDescriptor->scsi;
-              pDTE[x].status = (DataTransferElementDescriptor->full > 0) ? 'F':'E';
               pDTE[x].full = DataTransferElementDescriptor->full;
+              if (DataTransferElementDescriptor->full > 0)
+               {
+                 pDTE[x].status = 'F';
+               } else {
+                 pDTE[x].status = 'E';
+               }
 
              if (length >= 5)
              {
@@ -4104,6 +4298,8 @@ int GetElementStatus(int DeviceFD)
 
               offset = offset + length;
             }
+           free(DataBuffer);
+           DataBuffer = NULL;
         }
     } else {
       /*
@@ -4113,36 +4309,27 @@ int GetElementStatus(int DeviceFD)
       if (SCSI_ReadElementStatus(DeviceFD,
                                  0,
                                  0,
-                                 barcode,
+                                 (u_char)barcode,
                                  0,
-                                 0xff,
-                                0x7f,
-                                 (char **)&DataBuffer) != 0)
+                                 (size_t)0xff,
+                                (size_t)0x7f,
+                                 &DataBuffer) != 0)
         {
-         if (DataBuffer != 0)
-           {
-             free(DataBuffer);
-           }
           ChgExit("GenericElementStatus","Can't get ElementStatus", FATAL);
+         /*NOTREACHED*/
         }
+      assert(DataBuffer != NULL);
 
       ElementStatusData = (ElementStatusData_T *)DataBuffer;
       DataBufferLength = V3(ElementStatusData->count);
 
-      offset = sizeof(ElementStatusData_T);
-
-      if (DataBufferLength <= 0)
-        {
-          DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"DataBufferLength %d\n",DataBufferLength);
-         free(DataBuffer);
-          return(1);
-        }
+      offset = SIZEOF(ElementStatusData_T);
 
       while (offset < DataBufferLength)
         {
           ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
           NoOfElements = V3(ElementStatusPage->count) / V2(ElementStatusPage->length);
-          offset = offset + sizeof(ElementStatusPage_T);
+          offset = offset + SIZEOF(ElementStatusPage_T);
          length = V2(ElementStatusPage->length);
 
           switch (ElementStatusPage->type)
@@ -4150,13 +4337,8 @@ int GetElementStatus(int DeviceFD)
             case CHANGER:
              free(pMTE);
               MTE = NoOfElements;
-              if ((pMTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * MTE)) == NULL)
-                {
-                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-                 free(DataBuffer);
-                  return(-1);
-                }
-              memset(pMTE, 0, sizeof(ElementInfo_T) * MTE);
+              pMTE = alloc(SIZEOF(ElementInfo_T) * MTE);
+              memset(pMTE, 0, SIZEOF(ElementInfo_T) * MTE);
 
               for (x = 0; x < NoOfElements; x++)
                 {
@@ -4171,9 +4353,13 @@ int GetElementStatus(int DeviceFD)
                   pMTE[x].type = ElementStatusPage->type;
                   pMTE[x].address = V2(MediumTransportElementDescriptor->address);
                   pMTE[x].except = MediumTransportElementDescriptor->except;
-                  pMTE[x].status = (MediumTransportElementDescriptor->full > 0) ? 'F':'E';
                   pMTE[x].full = MediumTransportElementDescriptor->full;
-
+                 if (MediumTransportElementDescriptor->full > 0)
+                   {
+                     pMTE[x].status = 'F';
+                   } else {
+                     pMTE[x].status = 'E';
+                   }
 
                  if (length >= 5)
                    {
@@ -4207,13 +4393,8 @@ int GetElementStatus(int DeviceFD)
             case STORAGE:
              free(pSTE);
               STE = NoOfElements;
-              if ((pSTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * STE)) == NULL)
-                {
-                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-                 free(DataBuffer);
-                  return(-1);
-                }
-              memset(pSTE, 0, sizeof(ElementInfo_T) * STE);
+              pSTE = alloc(SIZEOF(ElementInfo_T) * STE);
+              memset(pSTE, 0, SIZEOF(ElementInfo_T) * STE);
 
               for (x = 0; x < NoOfElements; x++)
                 {
@@ -4229,8 +4410,13 @@ int GetElementStatus(int DeviceFD)
                   pSTE[x].type = ElementStatusPage->type;
                   pSTE[x].address = V2(StorageElementDescriptor->address);
                   pSTE[x].except = StorageElementDescriptor->except;
-                  pSTE[x].status = (StorageElementDescriptor->full > 0) ? 'F':'E';
                   pSTE[x].full = StorageElementDescriptor->full;
+                 if (StorageElementDescriptor->full > 0)
+                   {
+                     pSTE[x].status = 'F';
+                   } else {
+                     pSTE[x].status = 'E';
+                   }
 
                  if (length >= 5)
                    {
@@ -4264,13 +4450,8 @@ int GetElementStatus(int DeviceFD)
             case IMPORT:
              free(pIEE);
               IEE = NoOfElements;
-              if ((pIEE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * IEE)) == NULL)
-                {
-                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-                 free(DataBuffer);
-                  return(-1);
-                }
-              memset(pIEE, 0, sizeof(ElementInfo_T) * IEE);
+              pIEE = alloc(SIZEOF(ElementInfo_T) * IEE);
+              memset(pIEE, 0, SIZEOF(ElementInfo_T) * IEE);
 
               for (x = 0; x < NoOfElements; x++)
                 {
@@ -4286,8 +4467,13 @@ int GetElementStatus(int DeviceFD)
                   pIEE[x].type = ElementStatusPage->type;
                   pIEE[x].address = V2(ImportExportElementDescriptor->address);
                   pIEE[x].except = ImportExportElementDescriptor->except;
-                  pIEE[x].status = (ImportExportElementDescriptor->full > 0) ? 'F':'E';
                   pIEE[x].full = ImportExportElementDescriptor->full;
+                 if (ImportExportElementDescriptor->full > 0)
+                   {
+                     pIEE[x].status = 'F';
+                   } else {
+                     pIEE[x].status = 'E';
+                   }
 
                  if (length >= 5)
                    {
@@ -4321,13 +4507,8 @@ int GetElementStatus(int DeviceFD)
             case TAPETYPE:
              free(pDTE);
               DTE = NoOfElements;
-              if ((pDTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * DTE)) == NULL)
-                {
-                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
-                 free(DataBuffer);
-                  return(-1);
-                }
-              memset(pDTE, 0, sizeof(ElementInfo_T) * DTE);
+              pDTE = alloc(SIZEOF(ElementInfo_T) * DTE);
+              memset(pDTE, 0, SIZEOF(ElementInfo_T) * DTE);
 
               for (x = 0; x < NoOfElements; x++)
                 {
@@ -4343,8 +4524,13 @@ int GetElementStatus(int DeviceFD)
                   pDTE[x].address = V2(DataTransferElementDescriptor->address);
                   pDTE[x].except = DataTransferElementDescriptor->except;
                   pDTE[x].scsi = DataTransferElementDescriptor->scsi;
-                  pDTE[x].status = (DataTransferElementDescriptor->full > 0) ? 'F':'E';
                   pDTE[x].full = DataTransferElementDescriptor->full;
+                 if (DataTransferElementDescriptor->full > 0)
+                   {
+                     pDTE[x].status = 'F';
+                   } else {
+                     pDTE[x].status = 'E';
+                   }
 
                  if (length >= 5)
                    {
@@ -4381,6 +4567,7 @@ int GetElementStatus(int DeviceFD)
               break;
             }
         }
+       free(DataBuffer);
     }
 
   DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\n\n\tMedia Transport Elements (robot arms) :\n");
@@ -4413,7 +4600,6 @@ int GetElementStatus(int DeviceFD)
 
 
 
-  free(DataBuffer);
   return(0);
 }
 
@@ -4424,7 +4610,11 @@ int GetElementStatus(int DeviceFD)
  *
  * TODO
  */
-int RequestSense(int DeviceFD, ExtendedRequestSense_T *ExtendedRequestSense, int ClearErrorCounters )
+int
+RequestSense(
+    int                                DeviceFD,
+    ExtendedRequestSense_T *   ExtendedRequestSense,
+    int                                ClearErrorCounters)
 {
   CDB_T CDB;
   int ret;
@@ -4435,21 +4625,23 @@ int RequestSense(int DeviceFD, ExtendedRequestSense_T *ExtendedRequestSense, int
   CDB[1] = 0;                                  /* Logical Unit Number = 0, Reserved */
   CDB[2] = 0;                                  /* Reserved */
   CDB[3] = 0;                                  /* Reserved */
-  CDB[4] = sizeof(ExtendedRequestSense_T);     /* Allocation Length */
-  CDB[5] = (ClearErrorCounters << 7) & 0x80;                 /*  */
+  CDB[4] = (u_char)sizeof(ExtendedRequestSense_T);   /* Allocation Length */
+  CDB[5] = (u_char)((ClearErrorCounters << 7) & 0x80); /*  */
 
-  memset(ExtendedRequestSense, 0, sizeof(ExtendedRequestSense_T));
+  memset(ExtendedRequestSense, 0, SIZEOF(ExtendedRequestSense_T));
 
   ret = SCSI_Run(DeviceFD, Input, CDB, 6,
                 (char *) ExtendedRequestSense,
-                sizeof(ExtendedRequestSense_T),
-                (char *) ExtendedRequestSense, sizeof(ExtendedRequestSense_T));
+                SIZEOF(ExtendedRequestSense_T),
+                (RequestSense_T *) ExtendedRequestSense,
+                SIZEOF(ExtendedRequestSense_T));
 
 
   if (ret < 0)
     {
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (%d)\n",ret);
       return(ret);
+      /*NOTREACHED*/
     }
 
   if ( ret > 0)
@@ -4457,9 +4649,12 @@ int RequestSense(int DeviceFD, ExtendedRequestSense_T *ExtendedRequestSense, int
       DecodeExtSense(ExtendedRequestSense, "RequestSense : ",debug_file);
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (%d)\n", ExtendedRequestSense->SenseKey);
       return(ExtendedRequestSense->SenseKey);
+      /*NOTREACHED*/
     }
 
-  dump_hex((char *)ExtendedRequestSense , sizeof(ExtendedRequestSense_T) , DEBUG_INFO, SECTION_SCSI);
+  dump_hex((u_char *)ExtendedRequestSense ,
+          SIZEOF(ExtendedRequestSense_T),
+          DEBUG_INFO, SECTION_SCSI);
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (0)\n");
   return(0);
 }
@@ -4470,9 +4665,11 @@ int RequestSense(int DeviceFD, ExtendedRequestSense_T *ExtendedRequestSense, int
  */
 
 
-ElementInfo_T *LookupElement(int address)
+ElementInfo_T *
+LookupElement(
+    int                address)
 {
-  int x;
+  size_t x;
 
   dbprintf(("##### START LookupElement\n"));
 
@@ -4484,6 +4681,7 @@ ElementInfo_T *LookupElement(int address)
          {
             dbprintf(("##### STOP LookupElement (DTE)\n"));
             return(&pDTE[x]);
+           /*NOTREACHED*/
          }
         }
     }
@@ -4496,6 +4694,7 @@ ElementInfo_T *LookupElement(int address)
          {
             dbprintf(("##### STOP LookupElement (MTE)\n"));
             return(&pMTE[x]);
+           /*NOTREACHED*/
          }
         }
     }
@@ -4508,6 +4707,7 @@ ElementInfo_T *LookupElement(int address)
          {
             dbprintf(("##### STOP LookupElement (STE)\n"));
             return(&pSTE[x]);
+           /*NOTREACHED*/
          }
         }
     }
@@ -4520,11 +4720,13 @@ ElementInfo_T *LookupElement(int address)
          {
             dbprintf(("##### STOP LookupElement (IEE)\n"));
             return(&pIEE[x]);
+           /*NOTREACHED*/
          }
         }
     }
   return(NULL);
 }
+
 /*
  * Here comes everything what decode the log Pages
  *
@@ -4532,7 +4734,9 @@ ElementInfo_T *LookupElement(int address)
  * Fix the result handling from TestUnitReady
  *
  */
-int LogSense(DeviceFD)
+int
+LogSense(
+    int                DeviceFD)
 {
   extern OpenFiles_T *pDev;
   CDB_T CDB;
@@ -4543,26 +4747,23 @@ int LogSense(DeviceFD)
   int found;
   extern char *tapestatfile;
   int i;
-  int ParameterCode;
-  unsigned int value;
-  int length;
+  unsigned ParameterCode;
+  unsigned value;
+  size_t length;
   int count;
-  char *buffer;
-  char *logpages;
-  int nologpages;
-  int size = 128;
+  u_char *buffer;
+  u_char *logpages;
+  size_t nologpages;
+  size_t size = 128;
+
+  (void)DeviceFD;      /* Quiet unused parameter warning */
 
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START LogSense\n");
 
   if ((tapestatfile != NULL) && (pDev[INDEX_TAPECTL].SCSI == 1) &&
       ((StatFile = fopen(tapestatfile,"a")) != NULL))
     {
-      if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-        {
-          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
-             fclose(StatFile);
-              return(-1);
-        }
+      pRequestSense = alloc(SIZEOF(RequestSense_T));
 
       if (GenericRewind(INDEX_TAPECTL) < 0)
         {
@@ -4570,6 +4771,7 @@ int LogSense(DeviceFD)
           free(pRequestSense);
          fclose(StatFile);
           return(0);
+         /*NOTREACHED*/
         }
       /*
        * Try to read the tape label
@@ -4589,13 +4791,7 @@ int LogSense(DeviceFD)
            }
        }
 
-      if ((buffer = (char *)malloc(size)) == NULL)
-        {
-          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
-          free(pRequestSense);
-         fclose(StatFile);
-          return(-1);
-        }
+      buffer = alloc(size);
       memset(buffer, 0, size);
       /*
        * Get the known log pages
@@ -4611,38 +4807,32 @@ int LogSense(DeviceFD)
       MSB2(&CDB[7], size);
       CDB[9] = 0;
 
-            if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
+      if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
                               buffer,
                               size,
-                              (char *)pRequestSense,
-                              sizeof(RequestSense_T)) != 0)
+                              pRequestSense,
+                              SIZEOF(RequestSense_T)) != 0)
         {
           DecodeSense(pRequestSense, "LogSense : ",debug_file);
           free(pRequestSense);
           free(buffer);
          fclose(StatFile);
           return(0);
+         /*NOTREACHED*/
         }
 
       LogSenseHeader = (LogSenseHeader_T *)buffer;
       nologpages = V2(LogSenseHeader->PageLength);
-      if ((logpages = (char *)malloc(nologpages)) == NULL)
-        {
-          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
-          free(pRequestSense);
-         free(buffer);
-         fclose(StatFile);
-          return(-1);
-        }
+      logpages = alloc(nologpages);
 
-      memcpy(logpages, buffer + sizeof(LogSenseHeader_T), nologpages);
+      memcpy(logpages, buffer + SIZEOF(LogSenseHeader_T), nologpages);
 
-      for (count = 0; count < nologpages; count++) {
+      for (count = 0; count < (int)nologpages; count++) {
         if (logpages[count] != 0  ) {
           memset(buffer, 0, size);
           CDB[0] = SC_COM_LOG_SENSE;
           CDB[1] = 0;
-          CDB[2] = 0x40 | logpages[count];    /* 0x40 for current values */
+          CDB[2] = (u_char)(0x40 | logpages[count]);/* 0x40 for current values */
           CDB[3] = 0;
           CDB[4] = 0;
           CDB[5] = 0;
@@ -4653,8 +4843,8 @@ int LogSense(DeviceFD)
           if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
                                   buffer,
                                   size,
-                                  (char *)pRequestSense,
-                                  sizeof(RequestSense_T)) != 0)
+                                  pRequestSense,
+                                  SIZEOF(RequestSense_T)) != 0)
             {
               DecodeSense(pRequestSense, "LogSense : ",debug_file);
               free(pRequestSense);
@@ -4662,17 +4852,18 @@ int LogSense(DeviceFD)
               free(buffer);
              fclose(StatFile);
               return(0);
+             /*NOTREACHED*/
             }
           LogSenseHeader = (LogSenseHeader_T *)buffer;
           length = V2(LogSenseHeader->PageLength);
-          LogParameter = (LogParameter_T *)(buffer + sizeof(LogSenseHeader_T));
+          LogParameter = (LogParameter_T *)(buffer + SIZEOF(LogSenseHeader_T));
           /*
            * Decode the log pages
            */
           p = (struct LogPageDecode *)&DecodePages;
           found = 0;
 
-         dump_hex((char *)LogParameter, 64, DEBUG_INFO, SECTION_SCSI);
+         dump_hex((u_char *)LogParameter, 64, DEBUG_INFO, SECTION_SCSI);
 
           while(p->ident != NULL) {
             if ((strcmp(pDev[INDEX_TAPECTL].ident, p->ident) == 0 ||strcmp("*", p->ident) == 0)  && p->LogPage == logpages[count]) {
@@ -4687,34 +4878,34 @@ int LogSense(DeviceFD)
           if (!found) {
             fprintf(StatFile, "Logpage No %d = %x\n", count ,logpages[count]);
 
-            while ((char *)LogParameter < (buffer + length)) {
+            while ((u_char *)LogParameter < (buffer + length)) {
               i = LogParameter->ParameterLength;
               ParameterCode = V2(LogParameter->ParameterCode);
               switch (i) {
               case 1:
-                value = V1((char *)LogParameter + sizeof(LogParameter_T));
+                value = V1((u_char *)LogParameter + SIZEOF(LogParameter_T));
                 fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
                 break;
               case 2:
-                value = V2((char *)LogParameter + sizeof(LogParameter_T));
+                value = V2((u_char *)LogParameter + SIZEOF(LogParameter_T));
                 fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
                 break;
               case 3:
-                value = V3((char *)LogParameter + sizeof(LogParameter_T));
+                value = V3((u_char *)LogParameter + SIZEOF(LogParameter_T));
                 fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
                 break;
               case 4:
-                value = V4((char *)LogParameter + sizeof(LogParameter_T));
+                value = V4((u_char *)LogParameter + SIZEOF(LogParameter_T));
                 fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
                 break;
               case 5:
-                value = V5((char *)LogParameter + sizeof(LogParameter_T));
+                value = V5((u_char *)LogParameter + SIZEOF(LogParameter_T));
                 fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
                 break;
               default:
                 fprintf(StatFile, "ParameterCode %02X size %d\n", ParameterCode, i);
               }
-              LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+              LogParameter = (LogParameter_T *)((u_char *)LogParameter +  SIZEOF(LogParameter_T) + i);
             }
             fprintf(StatFile, "\n");
           }
@@ -4736,40 +4927,48 @@ int LogSense(DeviceFD)
       CDB[8] = 0;
       CDB[9] = 0;
 
-            if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
+      if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
                               buffer,
                               size,
-                              (char *)pRequestSense,
-                              sizeof(RequestSense_T)) != 0)
+                              pRequestSense,
+                              SIZEOF(RequestSense_T)) != 0)
         {
           DecodeSense(pRequestSense, "LogSense : ",debug_file);
           free(pRequestSense);
          free(logpages);
+         /*@ignore@*/
           free(buffer);
+         /*@end@*/
          fclose(StatFile);
           return(0);
+         /*NOTREACHED*/
         }
 
       free(pRequestSense);
       free(logpages);
+      /*@ignore@*/
       free(buffer);
+      /*@end@*/
       fclose(StatFile);
     }
   DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP LogSense\n");
   return(0);
 }
 
-void WriteErrorCountersPage(LogParameter_T *buffer, int length)
+void
+WriteErrorCountersPage(
+    LogParameter_T *   buffer,
+    size_t             length)
 {
   int i;
-  int value;
+  unsigned value;
   LogParameter_T *LogParameter;
-  int ParameterCode;
+  unsigned ParameterCode;
   LogParameter = buffer;
 
   fprintf(StatFile, "\tWrite Error Counters Page\n");
 
-  while ((char *)LogParameter < ((char *)buffer + length)) {
+  while ((u_char *)LogParameter < ((u_char *)buffer + length)) {
     i = LogParameter->ParameterLength;
     ParameterCode = V2(LogParameter->ParameterCode);
 
@@ -4810,24 +5009,28 @@ void WriteErrorCountersPage(LogParameter_T *buffer, int length)
     } else {
       fprintf(StatFile, "Error decoding Result\n");
     }
-    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+    LogParameter = (LogParameter_T *)((u_char *)LogParameter +  SIZEOF(LogParameter_T) + i);
   }
 }
 
-void ReadErrorCountersPage(LogParameter_T *buffer, int length)
+void
+ReadErrorCountersPage(
+    LogParameter_T *   buffer,
+    size_t             length)
 {
   int i;
-  int value;
+  unsigned value;
   LogParameter_T *LogParameter;
-  int ParameterCode;
+  unsigned ParameterCode;
   LogParameter = buffer;
 
   fprintf(StatFile, "\tRead Error Counters Page\n");
 
-  while ((char *)LogParameter < ((char *)buffer + length)) {
+  while ((u_char *)LogParameter < ((u_char *)buffer + length)) {
     i = LogParameter->ParameterLength;
     ParameterCode = V2(LogParameter->ParameterCode);
 
+    value = 0;
     if (Decode(LogParameter, &value) == 0) {
       switch (ParameterCode) {
       case 2:
@@ -4864,24 +5067,28 @@ void ReadErrorCountersPage(LogParameter_T *buffer, int length)
     } else {
       fprintf(StatFile, "Error decoding Result\n");
     }
-    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+    LogParameter = (LogParameter_T *)((u_char *)LogParameter +  SIZEOF(LogParameter_T) + i);
   }
 }
 
-void C1553APage30(LogParameter_T *buffer, int length)
+void
+C1553APage30(
+    LogParameter_T *   buffer,
+    size_t             length)
 {
   int i;
-  int value;
+  unsigned value;
   LogParameter_T *LogParameter;
-  int ParameterCode;
+  unsigned ParameterCode;
   LogParameter = buffer;
 
   fprintf(StatFile, "\tData compression transfer Page\n");
 
-  while ((char *)LogParameter < ((char *)buffer + length)) {
+  while ((u_char *)LogParameter < ((u_char *)buffer + length)) {
     i = LogParameter->ParameterLength;
     ParameterCode = V2(LogParameter->ParameterCode);
 
+    value = 0;
     if (Decode(LogParameter, &value) == 0) {
       switch (ParameterCode) {
       default:
@@ -4891,24 +5098,28 @@ void C1553APage30(LogParameter_T *buffer, int length)
         break;
       }
     }
-    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+    LogParameter = (LogParameter_T *)((u_char *)LogParameter +  SIZEOF(LogParameter_T) + i);
   }
 }
 
-void C1553APage37(LogParameter_T *buffer, int length)
+void
+C1553APage37(
+    LogParameter_T *   buffer,
+    size_t             length)
 {
   int i;
-  int value;
+  unsigned value;
   LogParameter_T *LogParameter;
-  int ParameterCode;
+  unsigned ParameterCode;
   LogParameter = buffer;
 
   fprintf(StatFile, "\tDrive Counters Page\n");
 
-  while ((char *)LogParameter < ((char *)buffer + length)) {
+  while ((u_char *)LogParameter < ((unsigned char *)buffer + length)) {
     i = LogParameter->ParameterLength;
     ParameterCode = V2(LogParameter->ParameterCode);
 
+    value = 0;
     if (Decode(LogParameter, &value) == 0) {
       switch (ParameterCode) {
       case 1:
@@ -4933,24 +5144,28 @@ void C1553APage37(LogParameter_T *buffer, int length)
         break;
       }
     }
-    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+    LogParameter = (LogParameter_T *)((u_char *)LogParameter +  SIZEOF(LogParameter_T) + i);
   }
 }
 
-void EXB85058HEPage39(LogParameter_T *buffer, int length)
+void
+EXB85058HEPage39(
+    LogParameter_T *   buffer,
+    size_t             length)
 {
   int i;
-  int value;
+  unsigned value;
   LogParameter_T *LogParameter;
-  int ParameterCode;
+  unsigned ParameterCode;
   LogParameter = buffer;
 
   fprintf(StatFile, "\tData Compression Page\n");
 
-  while ((char *)LogParameter < ((char *)buffer + length)) {
+  while ((u_char *)LogParameter < ((unsigned char *)buffer + length)) {
     i = LogParameter->ParameterLength;
     ParameterCode = V2(LogParameter->ParameterCode);
 
+    value = 0;
     if (Decode(LogParameter, &value) == 0) {
       switch (ParameterCode) {
       case 5:
@@ -4970,24 +5185,28 @@ void EXB85058HEPage39(LogParameter_T *buffer, int length)
         break;
       }
     }
-    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+    LogParameter = (LogParameter_T *)((u_char *)LogParameter +  SIZEOF(LogParameter_T) + i);
   }
 }
 
-void EXB85058HEPage3c(LogParameter_T *buffer, int length)
+void
+EXB85058HEPage3c(
+    LogParameter_T *   buffer,
+    size_t             length)
 {
   int i;
-  int value;
+  unsigned value;
   LogParameter_T *LogParameter;
-  int ParameterCode;
+  unsigned ParameterCode;
   LogParameter = buffer;
 
   fprintf(StatFile, "\tDrive Usage Information Page\n");
 
-  while ((char *)LogParameter < ((char *)buffer + length)) {
+  while ((u_char *)LogParameter < ((unsigned char *)buffer + length)) {
     i = LogParameter->ParameterLength;
     ParameterCode = V2(LogParameter->ParameterCode);
 
+    value = 0;
     if (Decode(LogParameter, &value) == 0) {
       switch (ParameterCode) {
       case 1:
@@ -5037,46 +5256,55 @@ void EXB85058HEPage3c(LogParameter_T *buffer, int length)
         break;
       }
     }
-    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+    LogParameter = (LogParameter_T *)((u_char *)LogParameter +  SIZEOF(LogParameter_T) + i);
   }
 }
 
-int Decode(LogParameter_T *LogParameter, int *value)
+int
+Decode(
+    LogParameter_T *   LogParameter,
+    unsigned *         value)
 {
 
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START Decode\n");
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"Decode Parameter with length %d\n", LogParameter->ParameterLength);
+
+  *value = 0;
   switch (LogParameter->ParameterLength) {
   case 1:
-    *value = V1((char *)LogParameter + sizeof(LogParameter_T));
+    *value = V1((u_char *)LogParameter + SIZEOF(LogParameter_T));
     break;
   case 2:
-    *value = V2((char *)LogParameter + sizeof(LogParameter_T));
+    *value = V2((u_char *)LogParameter + SIZEOF(LogParameter_T));
     break;
   case 3:
-    *value = V3((char *)LogParameter + sizeof(LogParameter_T));
+    *value = V3((u_char *)LogParameter + SIZEOF(LogParameter_T));
     break;
   case 4:
-    *value = V4((char *)LogParameter + sizeof(LogParameter_T));
+    *value = V4((u_char *)LogParameter + SIZEOF(LogParameter_T));
     break;
   case 5:
-    *value = V5((char *)LogParameter + sizeof(LogParameter_T));
+    *value = V5((u_char *)LogParameter + SIZEOF(LogParameter_T));
     break;
   case 6:
-    *value = V6((char *)LogParameter + sizeof(LogParameter_T));
+    *value = V6((u_char *)LogParameter + SIZEOF(LogParameter_T));
     break;
   default:
     fprintf(StatFile, "Can't decode ParameterCode %02X size %d\n",
             V2(LogParameter->ParameterCode), LogParameter->ParameterLength);
     DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP Decode (1)\n");
     return(1);
+    /*NOTREACHED*/
   }
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"Result = %d\n", *value);
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP Decode(0)\n");
   return(0);
 }
 
-void DumpDev(OpenFiles_T *p, char *device)
+void
+DumpDev(
+    OpenFiles_T *      p,
+    char *             device)
 {
        if (p != NULL)
        {
@@ -5090,21 +5318,31 @@ void DumpDev(OpenFiles_T *p, char *device)
        printf("\n");
 }
 
-void ChangerReplay(char *option)
+void
+ChangerReplay(
+    char *     option)
 {
-    char buffer[1024];
+    u_char buffer[1024];
     FILE *ip;
-    int x = 0, bufferx;
+    int x;
+    unsigned bufferx;
+
+    (void)option;      /* Quiet unused parameter warning */
 
     if ((ip=fopen("/tmp/chg-scsi-trace", "r")) == NULL)
       {
        exit(1);
       }
 
-    while (fscanf(ip, "%2x", &bufferx) != EOF)
+    for (x = 0; x < 1024; x++)
       {
-       buffer[x] = bufferx;
-       x++;
+        if (fscanf(ip, "%2x", &bufferx) == EOF) 
+         {
+           break;
+           /*NOTREACHED*/
+         }
+        buffer[x] = (u_char)bufferx;
+        x++;
       }
 
     DecodeModeSense(&buffer[0], 12, "DLT448ElementStatus :", 0, debug_file);
@@ -5114,35 +5352,35 @@ void ChangerReplay(char *option)
 /*
  * Display all Information we can get about the library....
  */
-void ChangerStatus(char *option, char * labelfile, int HasBarCode, char *changer_file, char *changer_dev, char *tape_device)
+void
+ChangerStatus(
+    char *     option,
+    char *     labelfile,
+    int                HasBarCode,
+    char *     changer_file,
+    char *     changer_dev,
+    char *     tape_device)
 {
   extern OpenFiles_T *pDev;
-  int x;
+  size_t x;
   FILE *out;
   ExtendedRequestSense_T ExtRequestSense;
   MBC_T *pbarcoderes;
 
   ChangerCMD_T *p = (ChangerCMD_T *)&ChangerIO;
-  if ((pbarcoderes = malloc(sizeof(MBC_T))) == NULL)
-    {
-      printf("malloc failed \n");
-      return;
-    }
-  memset(pbarcoderes, 0, sizeof(MBC_T));
+  pbarcoderes = alloc(SIZEOF(MBC_T));
+  memset(pbarcoderes, 0, SIZEOF(MBC_T));
 
-  if ((pModePage == NULL) && ((pModePage = (char *)malloc(0xff)) == NULL))
-    {
-      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### malloc failed (-1)\n");
-      printf("malloc failed \n");
-      free(pbarcoderes);
-      return;
-    }
+  if (pModePage == NULL) {
+        pModePage = alloc(0xff);
+  }
 
   if ((out = fdopen(1 , "w")) == NULL)
     {
       printf("Error fdopen stdout\n");
       free(pbarcoderes);
       return;
+      /*NOTREACHED*/
     }
 
   if (strcmp("types", option) == 0 || strcmp("all", option) == 0)
@@ -5165,6 +5403,7 @@ void ChangerStatus(char *option, char * labelfile, int HasBarCode, char *changer
                free(pbarcoderes);
                fclose(out);
                 return;
+               /*NOTREACHED*/
               }
           }
         /*      0123456789012345678901234567890123456789012 */
@@ -5187,7 +5426,8 @@ void ChangerStatus(char *option, char * labelfile, int HasBarCode, char *changer
          if (pMTE[x].full == 1)
            {
              pbarcoderes->action = BARCODE_BARCODE;
-             strcpy(pbarcoderes->data.barcode, pMTE[x].VolTag);
+             strncpy(pbarcoderes->data.barcode, pMTE[x].VolTag,
+                     SIZEOF(pbarcoderes->data.barcode));
 
              if (MapBarCode(labelfile, pbarcoderes) == 0 )
                {
@@ -5215,7 +5455,8 @@ void ChangerStatus(char *option, char * labelfile, int HasBarCode, char *changer
          if (pSTE[x].full == 1)
            {
              pbarcoderes->action = BARCODE_BARCODE;
-             strcpy(pbarcoderes->data.barcode, pSTE[x].VolTag);
+             strncpy(pbarcoderes->data.barcode, pSTE[x].VolTag,
+                     SIZEOF(pbarcoderes->data.barcode));
 
              if (MapBarCode(labelfile, pbarcoderes) == 0 )
                {
@@ -5243,7 +5484,8 @@ void ChangerStatus(char *option, char * labelfile, int HasBarCode, char *changer
          if (pDTE[x].full == 1)
            {
              pbarcoderes->action = BARCODE_BARCODE;
-             strcpy(pbarcoderes->data.barcode, pDTE[x].VolTag);
+             strncpy(pbarcoderes->data.barcode, pDTE[x].VolTag,
+                     SIZEOF(pbarcoderes->data.barcode));
 
              if (MapBarCode(labelfile, pbarcoderes) == 0 )
                {
@@ -5271,7 +5513,8 @@ void ChangerStatus(char *option, char * labelfile, int HasBarCode, char *changer
          if (pIEE[x].full == 1)
            {
              pbarcoderes->action = BARCODE_BARCODE;
-             strcpy(pbarcoderes->data.barcode, pIEE[x].VolTag);
+             strncpy(pbarcoderes->data.barcode, pIEE[x].VolTag,
+                     SIZEOF(pbarcoderes->data.barcode));
 
              if (MapBarCode(labelfile, pbarcoderes) == 0 )
                {
@@ -5355,24 +5598,29 @@ void ChangerStatus(char *option, char * labelfile, int HasBarCode, char *changer
   fclose(out);
 }
 
-void dump_hex(char *p, int size, int level, int section)
+void
+dump_hex(
+    u_char *   p,
+    size_t     size,
+    int                level,
+    int                section)
 {
-    int row_count = 0;
-    int x = 0;
+    size_t row_count = 0;
+    int x;
 
     while (row_count < size)
     {
-        DebugPrint(level, section,"%02X ", (unsigned char)p[row_count]);
-        if (((row_count + 1) % 16) == 0 )
+        DebugPrint(level, section,"%02X ", (u_char)p[row_count]);
+        if (((row_count + 1) % 16) == 0)
           {
             dbprintf(("   "));
-            for (x = 16; x>0;x--)
+            for (x = 16; x > 0; x--)
               {
-            if (isalnum((unsigned char)p[row_count - x + 1 ]))
-              DebugPrint(level, section,"%c",(unsigned char)p[row_count - x + 1]);
-            else
-              DebugPrint(level, section,".");
-              }
+               if (isalnum((u_char)p[row_count - x + 1 ]))
+                 DebugPrint(level, section,"%c",(u_char)p[row_count - x + 1]);
+               else
+                 DebugPrint(level, section,".");
+             }
             DebugPrint(level, section,"\n");
           }
        row_count++;
@@ -5380,16 +5628,25 @@ void dump_hex(char *p, int size, int level, int section)
     DebugPrint(level, section,"\n");
 }
 
-void TerminateString(char *string, int length)
+void
+TerminateString(
+    char *     string,
+    size_t     length)
 {
-  int x;
+  ssize_t x;
 
-  for (x = length; x >= 0 && !isalnum((int)string[x]); x--)
+  for (x = (ssize_t)length; x >= 0 && !isalnum((int)string[x]); x--)
     string[x] = '\0';
 }
 
-void ChgExit(char *where, char *reason, int level)
+void
+ChgExit(
+    char *     where,
+    char *     reason,
+    int level)
 {
+    (void)level;       /* Quiet unused parameter warning */
+
    dbprintf(("ChgExit in %s, reason %s\n", where, reason));
    fprintf(stderr,"%s\n",reason);
    exit(2);
@@ -5406,20 +5663,26 @@ void ChgExit(char *where, char *reason, int level)
  * is ready for accepting commands, and if this is true send
  * the command
  */
-int SCSI_Run(int DeviceFD,
-            Direction_T Direction,
-            CDB_T CDB,
-            int CDB_Length,
-            void *DataBuffer,
-            int DataBufferLength,
-            char *pRequestSense,
-            int RequestSenseLength)
+int
+SCSI_Run(
+    int                        DeviceFD,
+    Direction_T                Direction,
+    CDB_T              CDB,
+    size_t             CDB_Length,
+    void *             DataBuffer,
+    size_t             DataBufferLength,
+    RequestSense_T *   pRequestSense,
+    size_t             RequestSenseLength)
 {
   int ret = 0;
   int ok = 0;
   int maxtries = 0;
   RequestSense_T *pRqS;
 
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
   pRqS = (RequestSense_T *)pRequestSense;
 
   DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Run TestUnitReady\n");
@@ -5433,7 +5696,7 @@ int SCSI_Run(int DeviceFD,
          ok=1;
          break;
        case SCSI_SENSE:
-         switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRequestSense))
+         switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRqS))
            {
            case SENSE_NO:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_NO\n");
@@ -5450,7 +5713,7 @@ int SCSI_Run(int DeviceFD,
            case SENSE_ABORT:
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_ABORT\n");
              return(-1);
-             break;
+             /*NOTREACHED*/
            case SENSE_RETRY:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_RETRY\n");
              break;
@@ -5463,7 +5726,7 @@ int SCSI_Run(int DeviceFD,
        case SCSI_ERROR:
          DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run (TestUnitReady) SCSI_ERROR\n");
          return(-1);
-         break;
+         /*NOTREACHED*/
        case SCSI_BUSY:
          DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SCSI_BUSY\n");
          break;
@@ -5487,6 +5750,7 @@ int SCSI_Run(int DeviceFD,
     {
       DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run Exit %d\n",ret);
       return(-1);
+      /*NOTREACHED*/
     }
 
   ok = 0;
@@ -5509,7 +5773,7 @@ int SCSI_Run(int DeviceFD,
          ok=1;
          break;
        case SCSI_SENSE:
-         switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRequestSense))
+         switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRqS))
            {
            case SENSE_NO:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SENSE_NO\n");
@@ -5526,7 +5790,7 @@ int SCSI_Run(int DeviceFD,
            case SENSE_ABORT:
              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run SENSE_ABORT\n");
              return(-1);
-             break;
+             /*NOTREACHED*/
            case SENSE_RETRY:
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SENSE_RETRY\n");
              break;
@@ -5539,7 +5803,7 @@ int SCSI_Run(int DeviceFD,
        case SCSI_ERROR:
          DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run SCSI_ERROR\n");
          return(-1);
-         break;
+         /*NOTREACHED*/
        case SCSI_BUSY:
          DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SCSI_BUSY\n");
          break;
@@ -5557,30 +5821,31 @@ int SCSI_Run(int DeviceFD,
   if (ok == 1)
     {
       return(0);
-    } else {
-      return(-1);
+      /*NOTREACHED*/
     }
+  return(-1);
 }
 
 /*
  * This a vendor specific command !!!!!!
  * First seen at AIT :-)
  */
-int SCSI_AlignElements(int DeviceFD, int AE_MTE, int AE_DTE, int AE_STE)
+int
+SCSI_AlignElements(
+    int                DeviceFD,
+    size_t     AE_MTE,
+    size_t     AE_DTE,
+    size_t     AE_STE)
 {
   RequestSense_T *pRequestSense;
   int retry;
   CDB_T CDB;
-  int ret = -1;
+  int ret;
   int i;
 
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_AlignElements\n");
 
-  if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-    {
-      DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : malloc failed\n");
-      return(-1);
-    }
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
 
   for (retry = 0; retry < MAX_RETRIES; retry++)
     {
@@ -5595,7 +5860,7 @@ int SCSI_AlignElements(int DeviceFD, int AE_MTE, int AE_DTE, int AE_STE)
       CDB[11] = 0;
 
       ret = SCSI_Run(DeviceFD, Input, CDB, 12,
-                                NULL, 0, (char *)pRequestSense, sizeof(RequestSense_T));
+                                NULL, 0, pRequestSense, SIZEOF(RequestSense_T));
 
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : SCSI_Run = %d\n", ret);
       DecodeSense(pRequestSense, "SCSI_AlignElements :",debug_file);
@@ -5603,41 +5868,43 @@ int SCSI_AlignElements(int DeviceFD, int AE_MTE, int AE_DTE, int AE_STE)
       if (ret < 0)
         {
           DebugPrint(DEBUG_ERROR, SECTION_SCSI,"%s: Request Sense[Inquiry]: %02X",
-                    "chs", ((unsigned char *) &pRequestSense)[0]);
-          for (i = 1; i < sizeof(RequestSense_T); i++)
-            DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((unsigned char *) &pRequestSense)[i]);
+                    "chs", ((u_char *) &pRequestSense)[0]);
+          for (i = 1; i < (int)sizeof(RequestSense_T); i++)
+            DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((u_char *) &pRequestSense)[i]);
           DebugPrint(DEBUG_ERROR, SECTION_SCSI,"\n");
           return(ret);
+         /*NOTREACHED*/
         }
       if ( ret > 0)
         {
-          switch(SenseHandler(DeviceFD, 0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+          switch(SenseHandler(DeviceFD, 0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
             {
             case SENSE_IGNORE:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : SENSE_IGNORE\n");
               return(0);
-              break;
+              /*NOTREACHED*/
             case SENSE_RETRY:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : SENSE_RETRY no %d\n", retry);
               break;
             case SENSE_ABORT:
               DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_AlignElements : SENSE_ABORT\n");
               return(-1);
-              break;
+              /*NOTREACHED*/
             case SENSE_TAPE_NOT_UNLOADED:
               DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_AlignElements : Tape still loaded, eject failed\n");
               return(-1);
-              break;
+              /*NOTREACHED*/
             default:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : end %d\n", pRequestSense->SenseKey);
               return(pRequestSense->SenseKey);
-              break;
+              /*NOTREACHED*/
             }
         }
       if (ret == 0)
         {
           DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : end %d\n", ret);
           return(ret);
+         /*NOTREACHED*/
         }
     }
   DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_AlignElements :"
@@ -5646,7 +5913,12 @@ int SCSI_AlignElements(int DeviceFD, int AE_MTE, int AE_DTE, int AE_STE)
 }
 
 
-int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to)
+int
+SCSI_Move(
+    int                DeviceFD,
+    u_char     chm,
+    int                from,
+    int                to)
 {
   RequestSense_T *pRequestSense;
   int retry;
@@ -5656,11 +5928,7 @@ int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to)
 
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_Move\n");
 
-  if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-    {
-      DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Move : malloc failed\n");
-      return(-1);
-    }
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
 
   for (retry = 0; (ret != 0) && (retry < MAX_RETRIES); retry++)
     {
@@ -5676,7 +5944,7 @@ int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to)
       CDB[11] = 0;
 
       ret = SCSI_Run(DeviceFD, Input, CDB, 12,
-                                NULL, 0, (char *)pRequestSense, sizeof(RequestSense_T));
+                                NULL, 0, pRequestSense, SIZEOF(RequestSense_T));
 
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Move : SCSI_Run = %d\n", ret);
       DecodeSense(pRequestSense, "SCSI_Move :",debug_file);
@@ -5684,35 +5952,36 @@ int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to)
       if (ret < 0)
         {
           DebugPrint(DEBUG_ERROR, SECTION_SCSI,"%s: Request Sense[Inquiry]: %02X",
-                    "chs", ((unsigned char *) &pRequestSense)[0]);
-          for (i = 1; i < sizeof(RequestSense_T); i++)
-            DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((unsigned char *) &pRequestSense)[i]);
+                    "chs", ((u_char *) &pRequestSense)[0]);
+          for (i = 1; i < (int)sizeof(RequestSense_T); i++)
+            DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((u_char *) &pRequestSense)[i]);
           DebugPrint(DEBUG_INFO, SECTION_SCSI,"\n");
           return(ret);
+         /*NOTREACHED*/
         }
       if ( ret > 0)
         {
-          switch(SenseHandler(DeviceFD,  0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+          switch(SenseHandler(DeviceFD,  0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
             {
             case SENSE_IGNORE:
               dbprintf(("SCSI_Move : SENSE_IGNORE\n"));
               return(0);
-              break;
+              /*NOTREACHED*/
             case SENSE_RETRY:
               dbprintf(("SCSI_Move : SENSE_RETRY no %d\n", retry));
               break;
             case SENSE_ABORT:
               dbprintf(("SCSI_Move : SENSE_ABORT\n"));
               return(-1);
-              break;
+              /*NOTREACHED*/
             case SENSE_TAPE_NOT_UNLOADED:
               dbprintf(("SCSI_Move : Tape still loaded, eject failed\n"));
               return(-1);
-              break;
+              /*NOTREACHED*/
             default:
               dbprintf(("SCSI_Move : end %d\n", pRequestSense->SenseKey));
               return(pRequestSense->SenseKey);
-              break;
+              /*NOTREACHED*/
             }
         }
     }
@@ -5720,7 +5989,12 @@ int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to)
   return(ret);
 }
 
-int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, unsigned char byte1, unsigned char load)
+int
+SCSI_LoadUnload(
+    int                        DeviceFD,
+    RequestSense_T *   pRequestSense,
+    u_char             byte1,
+    u_char             load)
 {
   CDB_T CDB;
   int ret;
@@ -5737,19 +6011,23 @@ int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, unsigned char b
 
   ret = SCSI_Run(DeviceFD, Input, CDB, 6,
                             NULL, 0,
-                            (char *) pRequestSense,
-                            sizeof(RequestSense_T));
+                            pRequestSense,
+                            SIZEOF(RequestSense_T));
 
   if (ret < 0)
     {
       dbprintf(("SCSI_Unload : failed %d\n", ret));
       return(-1);
+      /*NOTREACHED*/
     }
 
   return(ret);
 }
 
-int SCSI_TestUnitReady(int DeviceFD, RequestSense_T *pRequestSense)
+int
+SCSI_TestUnitReady(
+    int                        DeviceFD,
+    RequestSense_T *   pRequestSense)
 {
   CDB_T CDB;
   int ret;
@@ -5764,9 +6042,9 @@ int SCSI_TestUnitReady(int DeviceFD, RequestSense_T *pRequestSense)
   CDB[5] = 0;
 
   ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 6,
-                      NULL, 0,
-                      (char *) pRequestSense,
-                      sizeof(RequestSense_T));
+                      NULL, (size_t)0,
+                      pRequestSense,
+                      SIZEOF(RequestSense_T));
 
   /*
    * We got an error, so let the calling function handle this
@@ -5775,6 +6053,7 @@ int SCSI_TestUnitReady(int DeviceFD, RequestSense_T *pRequestSense)
     {
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP SCSI_TestUnitReady (1)\n");
       return(ret);
+      /*NOTREACHED*/
     }
 
   /*
@@ -5785,6 +6064,7 @@ int SCSI_TestUnitReady(int DeviceFD, RequestSense_T *pRequestSense)
     {
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP SCSI_TestUnitReady (1)\n");
       return(0);
+      /*NOTREACHED*/
     }
 
   /*
@@ -5795,57 +6075,51 @@ int SCSI_TestUnitReady(int DeviceFD, RequestSense_T *pRequestSense)
 }
 
 
-int SCSI_ModeSelect(int DeviceFD, char *buffer, unsigned char length, unsigned char save, unsigned char mode, unsigned char lun)
+int
+SCSI_ModeSelect(
+    int                DeviceFD,
+    u_char *   buffer,
+    u_char     length,
+    u_char     save,
+    u_char     mode,
+    u_char     lun)
 {
   CDB_T CDB;
   RequestSense_T *pRequestSense;
   int ret = -1;
-  int retry = 1;
-  char *sendbuf;
+  int retry;
+  u_char *sendbuf;
 
   dbprintf(("##### START SCSI_ModeSelect\n"));
 
-  dbprintf(("SCSI_ModeSelect start length = %d:\n", length));
-  if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-      {
-          dbprintf(("SCSI_ModeSelect : malloc failed\n"));
-          return(-1);
-      }
-
-
-  if ((sendbuf = (char *)malloc(length + 4)) == NULL)
-    {
-      dbprintf(("SCSI_ModeSelect : malloc failed\n"));
-      free(pRequestSense);
-      return(-1);
-    }
-
-  memset(sendbuf, 0 , length + 4);
+  dbprintf(("SCSI_ModeSelect start length = %u:\n", (unsigned)length));
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
+  sendbuf = alloc((size_t)length + 4);
+  memset(sendbuf, 0 , (size_t)length + 4);
 
-  memcpy(&sendbuf[4], buffer, length);
-  dump_hex(sendbuf, length+4, DEBUG_INFO, SECTION_SCSI);
+  memcpy(&sendbuf[4], buffer, (size_t)length);
+  dump_hex(sendbuf, (size_t)length+4, DEBUG_INFO, SECTION_SCSI);
 
   for (retry = 0; (ret != 0) && (retry < MAX_RETRIES); retry++)
     {
-      memset(pRequestSense, 0, sizeof(RequestSense_T));
+      memset(pRequestSense, 0, SIZEOF(RequestSense_T));
 
       CDB[0] = SC_COM_MODE_SELECT;
-      CDB[1] = ((lun << 5) & 0xF0) | ((mode << 4) & 0x10) | (save & 1);
+      CDB[1] = (u_char)(((lun << 5) & 0xF0) | ((mode << 4) & 0x10) | (save & 1));
       CDB[2] = 0;
       CDB[3] = 0;
-      CDB[4] = length + 4;
+      CDB[4] = (u_char)(length + 4);
       CDB[5] = 0;
       ret = SCSI_Run(DeviceFD, Output, CDB, 6,
                                 sendbuf,
-                                length + 4,
-                                (char *) pRequestSense,
-                                sizeof(RequestSense_T));
+                                (size_t)length + 4,
+                                pRequestSense,
+                                SIZEOF(RequestSense_T));
       if (ret < 0)
         {
           dbprintf(("SCSI_ModeSelect : ret %d\n", ret));
-         free(pRequestSense);
-         free(sendbuf);
-          return(ret);
+         goto done;
+          /*NOTREACHED*/
         }
 
       if ( ret > 0)
@@ -5853,27 +6127,27 @@ int SCSI_ModeSelect(int DeviceFD, char *buffer, unsigned char length, unsigned c
           switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey,
                              pRequestSense->AdditionalSenseCode,
                              pRequestSense->AdditionalSenseCodeQualifier,
-                             (char *)pRequestSense))
+                             pRequestSense))
             {
             case SENSE_IGNORE:
               dbprintf(("SCSI_ModeSelect : SENSE_IGNORE\n"));
-             free(pRequestSense);
-             free(sendbuf);
-              return(0);
-              break;
+             goto done;
+              /*NOTREACHED*/
+
             case SENSE_RETRY:
               dbprintf(("SCSI_ModeSelect : SENSE_RETRY no %d\n", retry));
               break;
+
             default:
-              dbprintf(("SCSI_ModeSelect : end %d\n", pRequestSense->SenseKey));
-             free(pRequestSense);
-             free(sendbuf);
-              return(pRequestSense->SenseKey);
-              break;
+             ret = pRequestSense->SenseKey;
+             goto end;
             }
         }
     }
+end:
   dbprintf(("SCSI_ModeSelect end: %d\n", ret));
+
+done:
   free(pRequestSense);
   free(sendbuf);
   return(ret);
@@ -5881,7 +6155,13 @@ int SCSI_ModeSelect(int DeviceFD, char *buffer, unsigned char length, unsigned c
 
 
 
-int SCSI_ModeSense(int DeviceFD, char *buffer, u_char size, u_char byte1, u_char byte2)
+int
+SCSI_ModeSense(
+    int                DeviceFD,
+    u_char *   buffer,
+    u_char     size,
+    u_char     byte1,
+    u_char     byte2)
 {
   CDB_T CDB;
   RequestSense_T *pRequestSense;
@@ -5891,15 +6171,11 @@ int SCSI_ModeSense(int DeviceFD, char *buffer, u_char size, u_char byte1, u_char
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_ModeSense\n");
 
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense start length = %d:\n", size);
-  if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-      {
-          DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_ModeSense : malloc failed\n");
-          return(-1);
-      }
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
 
   while (ret && retry < MAX_RETRIES)
     {
-      memset(pRequestSense, 0, sizeof(RequestSense_T));
+      memset(pRequestSense, 0, SIZEOF(RequestSense_T));
       memset(buffer, 0, size);
 
       CDB[0] = SC_COM_MODE_SENSE;
@@ -5911,28 +6187,29 @@ int SCSI_ModeSense(int DeviceFD, char *buffer, u_char size, u_char byte1, u_char
       ret = SCSI_Run(DeviceFD, Input, CDB, 6,
                                 buffer,
                                 size,
-                                (char *) pRequestSense,
-                                sizeof(RequestSense_T));
+                                pRequestSense,
+                                SIZEOF(RequestSense_T));
       if (ret < 0)
         {
           return(ret);
+         /*NOTREACHED*/
         }
 
       if ( ret > 0)
         {
-          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
             {
             case SENSE_IGNORE:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
               return(0);
-              break;
+              /*NOTREACHED*/
             case SENSE_RETRY:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_RETRY no %d\n", retry);
               break;
             default:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : end %d\n", pRequestSense->SenseKey);
               return(pRequestSense->SenseKey);
-              break;
+              /*NOTREACHED*/
             }
         }
       retry++;
@@ -5942,23 +6219,25 @@ int SCSI_ModeSense(int DeviceFD, char *buffer, u_char size, u_char byte1, u_char
   return(ret);
 }
 
-int SCSI_Inquiry(int DeviceFD, SCSIInquiry_T *buffer, u_char size)
+int
+SCSI_Inquiry(
+    int                        DeviceFD,
+    SCSIInquiry_T *    buffer,
+    size_t             size)
 {
   CDB_T CDB;
   RequestSense_T *pRequestSense;
   int i;
-  int ret;
+  int ret = -1;
   int retry = 1;
 
+  assert(size <= UCHAR_MAX);
+
   DebugPrint(DEBUG_INFO, SECTION_SCSI, "##### START SCSI_Inquiry\n");
 
   DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Inquiry start length = %d:\n", size);
 
-  if ((pRequestSense = (RequestSense_T *)malloc(size)) == NULL)
-      {
-          DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Inquiry : malloc failed\n");
-          return(-1);
-      }
+  pRequestSense = alloc((size_t)size);
 
   while (retry > 0 && retry < MAX_RETRIES)
     {
@@ -5967,47 +6246,49 @@ int SCSI_Inquiry(int DeviceFD, SCSIInquiry_T *buffer, u_char size)
       CDB[1] = 0;
       CDB[2] = 0;
       CDB[3] = 0;
-      CDB[4] = size;
+      CDB[4] = (u_char)size;
       CDB[5] = 0;
 
       ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 6,
                                 buffer,
                                 size,
-                                (char *) pRequestSense,
-                            sizeof(RequestSense_T));
+                                pRequestSense,
+                                SIZEOF(RequestSense_T));
       if (ret < 0)
         {
           DebugPrint(DEBUG_ERROR, SECTION_SCSI,"%s: Request Sense[Inquiry]: %02X",
-                    "chs", ((unsigned char *) pRequestSense)[0]);
-          for (i = 1; i < sizeof(RequestSense_T); i++)
-            DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((unsigned char *) pRequestSense)[i]);
+                    "chs", ((u_char *) pRequestSense)[0]);
+          for (i = 1; i < (int)sizeof(RequestSense_T); i++)
+            DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((u_char *) pRequestSense)[i]);
           DebugPrint(DEBUG_ERROR, SECTION_SCSI, "\n");
-      DebugPrint(DEBUG_ERROR, SECTION_SCSI, "Inquiry end: %d\n", ret);
-      return(ret);
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI, "Inquiry end: %d\n", ret);
+         return(ret);
+         /*NOTRACHED*/
         }
       if ( ret > 0)
         {
-          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
             {
             case SENSE_IGNORE:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Inquiry : SENSE_IGNORE\n");
               return(0);
-              break;
+              /*NOTREACHED*/
             case SENSE_RETRY:
               DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Inquiry : SENSE_RETRY no %d\n", retry);
               break;
             default:
               DebugPrint(DEBUG_ERROR, SECTION_SCSI, "SCSI_Inquiry : end %d\n", pRequestSense->SenseKey);
               return(pRequestSense->SenseKey);
-              break;
+              /*NOTREACHED*/
             }
         }
       retry++;
       if (ret == 0)
         {
-          dump_hex((char *)buffer, size, DEBUG_INFO, SECTION_SCSI);
+          dump_hex((u_char *)buffer, size, DEBUG_INFO, SECTION_SCSI);
           DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Inquiry : end %d\n", ret);
           return(ret);
+         /*NOTRACHED*/
         }
     }
 
@@ -6026,17 +6307,19 @@ int SCSI_Inquiry(int DeviceFD, SCSIInquiry_T *buffer, u_char size)
  * 3. do again an Read Element Status with the result from 2.
  *
  */
-int SCSI_ReadElementStatus(int DeviceFD,
-                           unsigned char type,
-                           unsigned char lun,
-                           unsigned char VolTag,
-                           int StartAddress,
-                           int NoOfElements,
-                          int DescriptorSize,
-                           char **data)
+int
+SCSI_ReadElementStatus(
+    int                DeviceFD,
+    u_char     type,
+    u_char     lun,
+    u_char     VolTag,
+    int                StartAddress,
+    size_t     NoOfElements,
+    size_t     DescriptorSize,
+    u_char **  data)
 {
   CDB_T CDB;
-  int DataBufferLength;
+  size_t DataBufferLength;
   ElementStatusData_T *ElementStatusData;
   RequestSense_T *pRequestSense;
   int retry = 1;
@@ -6044,47 +6327,35 @@ int SCSI_ReadElementStatus(int DeviceFD,
 
   DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_ReadElementStatus\n");
 
-  if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
-    {
-      DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus : malloc failed\n");
-      ChgExit("SCSI_ReadElementStatus","malloc failed", FATAL);
-    }
+  pRequestSense = alloc(SIZEOF(RequestSense_T));
 
   /*
    * How many elements, if <= 0 than exit with an fatal error
    */
-  if (NoOfElements <= 0)
+  if (NoOfElements == 0)
     {
       ChgExit("SCSI_ReadElementStatus","No of Elements passed are le 0",FATAL);
+      /*NOTREACHED*/
     }
 
-  VolTag = (VolTag << 4) & 0x10;
-  type = type & 0xf;
-  lun = (lun << 5) & 0xe0;
-
+  VolTag = (u_char)((VolTag << 4) & 0x10);
+  type = (u_char)(type & 0xf);
+  lun = (u_char)((lun << 5) & 0xe0);
 
   /* if  DescriptorSize == 0
    * try to get the allocation length for the second call
    */
   if (DescriptorSize == 0)
     {
-      if (*data != NULL)
-       {
-         *data = realloc(*data, 8);
-       } else {
-         *data = malloc(8);
-       }
-
+      *data = newalloc(*data, 8);
       memset(*data, 0, 8);
 
-
-
       while (retry > 0 && retry < MAX_RETRIES)
        {
-         memset(pRequestSense, 0, sizeof(RequestSense_T) );
+         memset(pRequestSense, 0, SIZEOF(RequestSense_T) );
 
          CDB[0] = SC_COM_RES;          /* READ ELEMENT STATUS */
-         CDB[1] = VolTag | type | lun; /* Element Type Code , VolTag, LUN */
+         CDB[1] = (u_char)(VolTag | type | lun); /* Element Type Code , VolTag, LUN */
          MSB2(&CDB[2], StartAddress);  /* Starting Element Address */
          MSB2(&CDB[4], NoOfElements);  /* Number Of Element */
          CDB[6] = 0;                             /* Reserved */
@@ -6094,8 +6365,7 @@ int SCSI_ReadElementStatus(int DeviceFD,
 
          ret = SCSI_Run(DeviceFD, Input, CDB, 12,
                         *data, 8,
-                        (char *)pRequestSense, sizeof(RequestSense_T));
-
+                        pRequestSense, SIZEOF(RequestSense_T));
 
          DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus : (1) SCSI_Run %d\n", ret);
          if (ret < 0)
@@ -6103,10 +6373,11 @@ int SCSI_ReadElementStatus(int DeviceFD,
              DecodeSense(pRequestSense, "SCSI_ReadElementStatus :",debug_file);
              DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
              return(ret);
+             /*NOTRACHED*/
            }
          if ( ret > 0)
            {
-             switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+             switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
                {
                case SENSE_IGNORE:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
@@ -6119,7 +6390,7 @@ int SCSI_ReadElementStatus(int DeviceFD,
                default:
                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : end %d\n", pRequestSense->SenseKey);
                  return(pRequestSense->SenseKey);
-                 break;
+                 /*NOTREACHED*/
                }
            }
          retry++;
@@ -6132,6 +6403,7 @@ int SCSI_ReadElementStatus(int DeviceFD,
        {
          DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
          return(ret);
+         /*NOTRACHED*/
        }
 
       ElementStatusData = (ElementStatusData_T *)*data;
@@ -6145,16 +6417,16 @@ int SCSI_ReadElementStatus(int DeviceFD,
     }
 
   DataBufferLength = DataBufferLength + 8;
-  *data = realloc(*data, DataBufferLength);
+  *data = newalloc(*data, DataBufferLength);
   memset(*data, 0, DataBufferLength);
   retry = 1;
 
   while (retry > 0 && retry < MAX_RETRIES)
     {
-      memset(pRequestSense, 0, sizeof(RequestSense_T) );
+      memset(pRequestSense, 0, SIZEOF(RequestSense_T) );
 
       CDB[0] = SC_COM_RES;           /* READ ELEMENT STATUS */
-      CDB[1] = VolTag | type | lun;  /* Element Type Code, VolTag, LUN */
+      CDB[1] = (u_char)(VolTag | type | lun);  /* Element Type Code, VolTag, LUN */
       MSB2(&CDB[2], StartAddress);   /* Starting Element Address */
       MSB2(&CDB[4], NoOfElements);   /* Number Of Element */
       CDB[6] = 0;                              /* Reserved */
@@ -6164,7 +6436,7 @@ int SCSI_ReadElementStatus(int DeviceFD,
 
       ret = SCSI_Run(DeviceFD, Input, CDB, 12,
                                 *data, DataBufferLength,
-                                (char *)pRequestSense, sizeof(RequestSense_T));
+                                pRequestSense, SIZEOF(RequestSense_T));
 
 
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus : (2) SCSI_Run %d\n", ret);
@@ -6173,10 +6445,11 @@ int SCSI_ReadElementStatus(int DeviceFD,
           DecodeSense(pRequestSense, "SCSI_ReadElementStatus :",debug_file);
          DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
           return(ret);
+         /*NOTRACHED*/
         }
       if ( ret > 0)
         {
-          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
             {
             case SENSE_IGNORE:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
@@ -6189,7 +6462,7 @@ int SCSI_ReadElementStatus(int DeviceFD,
             default:
               DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : end %d\n", pRequestSense->SenseKey);
               return(pRequestSense->SenseKey);
-              break;
+              /*NOTREACHED*/
             }
         }
       retry++;
@@ -6203,6 +6476,7 @@ int SCSI_ReadElementStatus(int DeviceFD,
     {
       DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
       return(ret);
+      /*NOTRACHED*/
     }
 
   dump_hex(*data, DataBufferLength, DEBUG_INFO, SECTION_SCSI);
@@ -6214,22 +6488,25 @@ printf_arglist_function2(void DebugPrint, int, level, int, section, char *, fmt)
 {
   va_list argp;
   char buf[1024];
-  extern changer_t chg;
-  int dlevel,dsection;
+  int dlevel;
+  int dsection = -1;
+  time_t ti = time(NULL);
 
-  time_t ti;
-
-  time(&ti);
-  if (chg.debuglevel)
+  if (changer->debuglevel)
     {
-      sscanf(chg.debuglevel,"%d:%d", &dlevel, &dsection);
+      if (sscanf(changer->debuglevel,"%d:%d", &dlevel, &dsection) != 2) {
+       dbprintf(("Parse error: line is '%s' expected [0-9]*:[0-9]*\n",
+                 changer->debuglevel));
+        dlevel=1;
+        dsection=1;
+      }
     } else {
       dlevel=1;
       dsection=1;
     }
 
   arglist_start(argp, fmt);
-  vsnprintf(buf, sizeof(buf), fmt, argp);
+  vsnprintf(buf, SIZEOF(buf), fmt, argp);
   if (dlevel >= level)
     {
       if (section == dsection || dsection == 0)
index fd8d3ee524bb0a7527f3ee26a15ef8be32d597f5..87c6157e824efad237911615d295e877f710bb07 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: scsi-chio.c,v 1.13 2000/06/25 18:48:11 ant Exp $
+ *     $Id: scsi-chio.c,v 1.14 2006/05/25 01:47:07 johnfranks Exp $
  *
  *     scsi-chio.c -- library routines to handle the changer
  *                     support for chio based systems
@@ -12,6 +12,7 @@
 
 #include "config.h"
 #include "amanda.h"
+#include "scsi-defs.h"
 
 #if (defined(HAVE_CHIO_H) || defined(HAVE_SYS_CHIO_H)) \
     && !defined(HAVE_CAMLIB_H)
@@ -305,6 +306,7 @@ int CloseDevice (char *device, int DeviceFD)
 {
    int ret;
 
+   dbprintf(("%s: CloseDevice(%s)\n", device, get_pname()));
    ret = close(DeviceFD);
 
    return ret;
index 3b8a36c10a7acf784a51200b7a980d1e8379ed72..b32a180b2f08a17153fcf8b493dfa940d826f1c8 100644 (file)
@@ -2,6 +2,9 @@
 /*
  * Copyright (c) 1998 T.Hepper
  */
+#ifndef SCSIDEFS_H
+#define SCSIDEFS_H
+
 #ifndef WORDS_BIGENDIAN
 #define LITTLE_ENDIAN_BITFIELDS
 #endif
@@ -53,7 +56,7 @@ typedef unsigned char PackedBit;
 
 #define MAX_RETRIES 100
 
-#define INQUIRY_SIZE sizeof(SCSIInquiry_T)
+#define INQUIRY_SIZE SIZEOF(SCSIInquiry_T)
 
 /*
  * Return values from the OS dependent part
@@ -134,10 +137,10 @@ typedef unsigned char PackedBit;
 
 /* macros for building scsi msb array parameter lists */
 #ifndef B
-#define B(s,i) ((unsigned char)((s) >> i))
+#define B(s,i) ((unsigned char)(((s) >> (i)) & 0xff))
 #endif
 #ifndef B1
-#define B1(s)                           ((unsigned char)(s))
+#define B1(s)  ((unsigned char)((s) & 0xff))
 #endif
 #define B2(s)                       B((s),8),   B1(s)
 #define B3(s)            B((s),16), B((s),8),   B1(s)
@@ -152,10 +155,10 @@ typedef unsigned char PackedBit;
 #define V6(s) (((((((((((s)[0] << 8) | (s)[1]) << 8) | (s)[2]) << 8) | (s)[3]) << 8) | (s)[4]) << 8) | (s)[5])
 
 /* macros for converting binary into scsi msb array */
-#define MSB1(s,v)                                               *(s)=B1(v)
-#define MSB2(s,v)                                *(s)=B(v,8), (s)[1]=B1(v)
-#define MSB3(s,v)               *(s)=B(v,16),  (s)[1]=B(v,8), (s)[2]=B1(v)
-#define MSB4(s,v) *(s)=B(v,24),(s)[1]=B(v,16), (s)[2]=B(v,8), (s)[3]=B1(v)
+#define MSB1(s,v)                                                (s)[0]=B1(v)
+#define MSB2(s,v)                                 (s)[0]=B(v,8), (s)[1]=B1(v)
+#define MSB3(s,v)                 (s)[0]=B(v,16), (s)[1]=B(v,8), (s)[2]=B1(v)
+#define MSB4(s,v) (s)[0]=B(v,24), (s)[1]=B(v,16), (s)[2]=B(v,8), (s)[3]=B1(v)
 
 #define LABEL_DB_VERSION 2
 
@@ -174,17 +177,17 @@ typedef unsigned char PackedBit;
 /*----------------------------------------------------------------------------*/
 /* Some stuff for our own configurationfile */
 typedef struct {  /* The information we can get for any drive (configuration) */
-  int drivenum;      /* Which drive to use in the library */
-  int start;         /* Which is the first slot we may use */
-  int end;           /* The last slot we are allowed to use */
-  int cleanslot;     /* Where the cleaningcartridge stays */
+  int  drivenum;    /* Which drive to use in the library */
+  int  start;       /* Which is the first slot we may use */
+  int  end;         /* The last slot we are allowed to use */
+  int  cleanslot;   /* Where the cleaningcartridge stays */
   char *scsitapedev; /* Where can we send raw SCSI commands to the tape */
   char *device;      /* Which device is associated to the drivenum */
   char *slotfile;    /* Where we should have our memory */   
   char *cleanfile;   /* Where we count how many cleanings we did */
   char *timefile;    /* Where we count the time the tape was used*/
   char *tapestatfile;/* Where can we place some drive stats */
-  char *changerident;/* Config to use foe changer control, ovverride result from inquiry */
+  char *changerident;/* Config to use for changer control, ovverride result from inquiry */
   char *tapeident;   /* Same as above for the tape device */
 }config_t; 
 
@@ -195,7 +198,7 @@ typedef struct {
   int havebarcode;       /* Do we have an barcode reader installed */
   char *debuglevel;      /* How many debug info to print */
   unsigned char emubarcode;    /* Emulate the barcode feature,  used for keeping an inventory of the lib */
-  int sleep;             /* How many seconds to wait for the drive to get ready */
+  time_t sleep;          /* How many seconds to wait for the drive to get ready */
   int cleanmax;          /* How many runs could be done with one cleaning tape */
   char *device;          /* Which device is our changer */
   char *labelfile;       /* Mapping from Barcode labels to volume labels */
@@ -211,10 +214,10 @@ typedef struct {
 typedef struct {
   char voltag[128];              /* Tape volume label */
   char barcode[TAG_SIZE];        /* Barcode of the tape */
-  unsigned int slot;             /* in which slot is the tape */
-  unsigned int from;            /* from where it comes, needed to move
-                                * a tape back to the right slot from the drive
-                                */
+  int slot;                      /* in which slot is the tape */
+  int from;                      /* from where it comes, needed to move a tape
+                                 * back to the right slot from the drive
+                                 */
 
   unsigned int LoadCount;      /* How many times has the tape been loaded */
   unsigned int RecovError;     /* How many recovered errors */
@@ -1053,8 +1056,8 @@ typedef struct ElementInfo
     int from;       /* From where did it come */
     char status;    /* F -> Full, E -> Empty */
     char VolTag[TAG_SIZE+1]; /* Label Info if Barcode reader exsist */
-    int ASC;        /* Additional Sense Code from read element status */
-    int ASCQ;      /* */
+    unsigned char ASC;  /* Additional Sense Code from read element status */
+    unsigned char ASCQ; /* */
     unsigned char scsi; /* if DTE, which scsi address */
 
   PackedBit svalid : 1;
@@ -1076,13 +1079,13 @@ typedef struct {
     int (*function_move)(int, int, int);
     int (*function_status)(int, int);
     int (*function_reset_status)(int);
-    int (*function_free)();
+    int (*function_free)(void);
     int (*function_eject)(char *, int);
     int (*function_clean)(char *);
     int (*function_rewind)(int);
     int (*function_barcode)(int);
-    int (*function_search)();
-    int (*function_error)(int, int, unsigned char, unsigned char, unsigned char, char *);
+    int (*function_search)(void);
+    int (*function_error)(int, unsigned char, unsigned char, unsigned char, unsigned char, RequestSense_T *);
 } ChangerCMD_T ;
 
 typedef struct {
@@ -1112,71 +1115,90 @@ typedef struct OpenFiles {
 typedef struct LogPageDecode {
     int LogPage;
     char *ident;
-    void (*decode)(LogParameter_T *, int);
+    void (*decode)(LogParameter_T *, size_t);
 } LogPageDecode_T;
 
 typedef struct {
-   char *ident;      /* Ident as returned from the inquiry */
-   char *vendor;     /* Vendor as returned from the inquiry */
-   int type;         /* removable .... */
-   int sense;        /* Sense key as returned from the device */
-   int asc;          /* ASC as set in the sense struct */
-   int ascq;         /* ASCQ as set in the sense struct */
-   int  ret;         /* What we think that we should return on this conditon */
-   char text[80];    /* A short text describing this condition */
+   char *ident;        /* Ident as returned from the inquiry */
+   char *vendor;       /* Vendor as returned from the inquiry */
+   unsigned char type; /* removable .... */
+   unsigned char sense;/* Sense key as returned from the device */
+   unsigned char asc;  /* ASC as set in the sense struct */
+   unsigned char ascq; /* ASCQ as set in the sense struct */
+   int  ret;           /* What we think that we should return on this conditon */
+   char text[80];      /* A short text describing this condition */
 } SenseType_T;                                                                                    
 
 /* ======================================================= */
-/* Funktion-Declaration */
+/* Function-Declaration */
 /* ======================================================= */
-int SCSI_OpenDevice(int );
-int OpenDevice(int ,char *DeviceName, char *ConfigName, char *ident);
+int SCSI_OpenDevice(int);
+int OpenDevice(intchar *DeviceName, char *ConfigName, char *ident);
 
 int SCSI_CloseDevice(int DeviceFD); 
-int CloseDevice(int ); 
+int CloseDevice(char *, int); 
 int Tape_Eject(int);
 int Tape_Status(int);
-void DumpSense();
-int Sense2Action(char *ident, unsigned char type, unsigned char ignsense, unsigned char sense, unsigned
-char asc, unsigned char ascq, char **text) ;
+void DumpSense(void);
+int Sense2Action(char *ident,
+                       unsigned char type,
+                       unsigned char ignsense,
+                       unsigned char sense,
+                       unsigned char asc,
+                       unsigned char ascq,
+                       char **text);
 
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *RequestSense,
-                        int RequestSenseLength);
-
-int Tape_Ioctl( int DeviceFD, int command);
-void ChangerStatus(char * option, char * labelfile, int HasBarCode, char *changer_file, char *changer_dev, char *tape_device);
-
-int SCSI_Inquiry(int, SCSIInquiry_T *, unsigned char);
+                        size_t DataBufferLength,
+                        RequestSense_T *RequestSense,
+                        size_t RequestSenseLength);
+
+int Tape_Ioctl(int DeviceFD, int command);
+void ChangerStatus(char * option,
+                       char * labelfile,
+                       int HasBarCode,
+                       char *changer_file,
+                       char *changer_dev,
+                       char *tape_device);
+
+int SCSI_Inquiry(int, SCSIInquiry_T *, size_t);
 int PrintInquiry(SCSIInquiry_T *);
 int DecodeSCSI(CDB_T CDB, char *string);
 
-int RequestSense P((int fd, ExtendedRequestSense_T *s, int ClearErrorCounters));
-int DecodeSense P((RequestSense_T *sense, char *pstring, FILE *out));
-int DecodeExtSense P((ExtendedRequestSense_T *sense, char *pstring, FILE *out));
+int RequestSense(int fd, ExtendedRequestSense_T *s, int ClearErrorCounters);
+int DecodeSense(RequestSense_T *sense, char *pstring, FILE *out);
+int DecodeExtSense(ExtendedRequestSense_T *sense, char *pstring, FILE *out);
 
 void ChgExit(char *, char *, int);
 
 void ChangerReplay(char *option);
-void ChangerStatus(char * option, char * labelfile, int HasBarCode, char *changer_file, char *changer_dev, char *tape_device);
+void ChangerStatus(char *option, char *labelfile, int HasBarCode, char *changer_file, char *changer_dev, char *tape_device);
 int BarCode(int fd);
 int MapBarCode(char *labelfile, MBC_T *);
 
-int Tape_Ready(int fd, int wait_time);
+int Tape_Ready(int fd, time_t wait_time);
 
 void Inventory(char *labelfile, int drive, int eject, int start, int stop, int clean);
-void ChangerDriverVersion();
-void PrintConf();
+void ChangerDriverVersion(void);
+void PrintConf(void);
 int LogSense(int fd);
 int ScanBus(int print);
 void DebugPrint(int level, int section, char * fmt, ...);
 int DecodeSense(RequestSense_T *sense, char *pstring, FILE *out);
-void SCSI_OS_Version();
+void SCSI_OS_Version(void);
+int get_clean_state(char *tapedev);
+int find_empty(int fd, int start, int count);
+int get_slot_count(int fd);
+int get_drive_count(int fd);
+int GetCurrentSlot(int fd, int drive);
+void DumpDev(OpenFiles_T *p, char *device);
+int isempty(int fd, int slot);
+
+#endif /* !SCSIDEFS_H */
 /*
  * Local variables:
  * indent-tabs-mode: nil
index d7ae82fb24a53bb209ea8d333fe3d4cc2530d920..56179b19b58ad69c57b2569c01105f3149c2058f 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-hpux.c,v 1.14 2001/02/08 19:19:08 ant Exp $
+ * $Id: scsi-hpux.c,v 1.15 2006/05/25 01:47:07 johnfranks Exp $
  *
  *     scsi-chio.c -- library routines to handle the changer
  *                     support for chio based systems
@@ -64,7 +64,7 @@ int GetCurrentSlot(int fd)
 
 static int get_changer_info(fd)
 {
-int rc = 0;
+    int rc = 0;
 
     if (!changer_info_init) {
        rc = ioctl(fd, SIOC_ELEMENT_ADDRESSES, &changer_info);
@@ -89,7 +89,7 @@ int get_clean_state(char *dev)
         perror(dev);
         return 0;
     }
-    memset(buffer, 0, sizeof(buffer));
+    memset(buffer, 0, SIZEOF(buffer));
 
     *((int *) buffer) = 0;      /* length of input data */
     *(((int *) buffer) + 1) = 100;     /* length of output buffer */
@@ -168,7 +168,7 @@ int rc;
 /*
  * find the first empty slot 
  */
-int find_empty(int fd)
+int find_empty(int fd, int start, int count)
 {
 struct element_status  es;
 int i, rc;
@@ -326,14 +326,16 @@ int OpenDevice(char * tapedev)
   int DeviceFD;
 
   DeviceFD = open(tapedev, O_RDWR);
+  dbprintf(("%s: OpenDevice(%s) returns %d\n", get_pname(), tapedev, DeviceFD));
   return(DeviceFD);
 }
 
-int CloseDevice(int DeviceFD)
+int CloseDevice(char *device, int DeviceFD)
 {
   int ret;
 
   ret = close(DeviceFD);
+  dbprintf(("%s: CloseDevice(%s) returns %d\n", get_pname(), device, ret));
   return(ret);
 }
 
index c046734b8dc5f63e8a05f6a7078bc4e2b5fc3f07..e96ed4725b9347831a98bede862b10792a9896dc 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-hpux_new.c,v 1.18 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-hpux_new.c,v 1.19 2006/05/25 01:47:08 johnfranks Exp $
  *
  * Interface to execute SCSI commands on an HP-UX Workstation
  *
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
-#ifdef HAVE_SYS_SCSI_H
-#include <sys/scsi.h>
-#endif
 
+#include <sys/scsi.h>
 #include <sys/mtio.h>
 
 #include <scsi-defs.h>
@@ -60,7 +58,7 @@
 void SCSI_OS_Version()
 {
 #ifndef lint
-    static char rcsid[] = "$Id: scsi-hpux_new.c,v 1.18 2005/10/15 13:20:47 martinea Exp $";
+    static char rcsid[] = "$Id: scsi-hpux_new.c,v 1.19 2006/05/25 01:47:08 johnfranks Exp $";
    DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
 #endif
 }
@@ -111,13 +109,11 @@ int SCSI_OpenDevice(int ip)
                   free(pDev[ip].inquiry);
                   return(0);
               }
-            } else {
-              close(DeviceFD);
-              free(pDev[ip].inquiry);
-              pDev[ip].inquiry = NULL;
-              return(1);
             }
-          return(1);
+            close(DeviceFD);
+            free(pDev[ip].inquiry);
+            pDev[ip].inquiry = NULL;
+            return(1);
         }
     } else {
       if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) >= 0)
@@ -144,25 +140,31 @@ int SCSI_CloseDevice(int DeviceFD)
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *RequestSense,
-                        int RequestSenseLength)
+                        size_t DataBufferLength,
+                        RequestSense_T *RequestSenseBuf,
+                        size_t RequestSenseLength)
 {
   extern OpenFiles_T *pDev;
   struct sctl_io sctl_io;
-  extern int errno;
   int Retries = 3;
   int Zero = 0, Result;
   
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
+  /* Clear buffer for cases where sense is not returned */
+  memset(RequestSenseBuf, 0, RequestSenseLength);
+
   if (pDev[DeviceFD].avail == 0)
     {
       return(SCSI_ERROR);
     }
 
 
-  memset(&sctl_io, '\0', sizeof(struct sctl_io));
+  memset(&sctl_io, '\0', SIZEOF(struct sctl_io));
 
   sctl_io.flags = 0;  
   sctl_io.max_msecs = 240000;
@@ -206,18 +208,18 @@ int SCSI_ExecuteCommand(int DeviceFD,
     
     SCSI_CloseDevice(DeviceFD);
 
-    memcpy(RequestSense, sctl_io.sense, RequestSenseLength);
+    memcpy(RequestSenseBuf, sctl_io.sense, RequestSenseLength);
     
     switch(sctl_io.cdb_status)
       {
       case S_GOOD:
         return(SCSI_OK);
+
       case S_CHECK_CONDITION:
         return(SCSI_CHECK);
-        break;
+
       default:
         return(SCSI_ERROR);
-        break;
       }
   }
   return(SCSI_ERROR);
@@ -242,13 +244,14 @@ int Tape_Ioctl( int DeviceFD, int command)
       mtop.mt_op = MTOFFL;
       mtop.mt_count = 1;
       break;
+
     default:
       break;
     }
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
     {
-      dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+      dbprintf(("Tape_Ioctl error ioctl %s\n", strerror(errno)));
       SCSI_CloseDevice(DeviceFD);
       return(-1);
     }
@@ -271,7 +274,7 @@ int Tape_Status( int DeviceFD)
 
   if (ioctl(pDev[DeviceFD].fd, MTIOCGET, &mtget) != 0)
   {
-     dbprintf(("Tape_Status error ioctl %d\n",errno));
+     dbprintf(("Tape_Status error ioctl %s\n", strerror(errno)));
      SCSI_CloseDevice(DeviceFD);
      return(-1);
   }
index b747884d54f7d6d26d8842f9be00505e2a9b91d3..f018cebca0f494cc3f4ee6649266b8be69959bf8 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-irix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-irix.c,v 1.23 2006/05/25 01:47:08 johnfranks Exp $
  *
  * Interface to execute SCSI commands on an SGI Workstation
  *
@@ -62,7 +62,7 @@
 void SCSI_OS_Version()
 {
 #ifndef lint
-   static char rcsid[] = "$Id: scsi-irix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $";
+   static char rcsid[] = "$Id: scsi-irix.c,v 1.23 2006/05/25 01:47:08 johnfranks Exp $";
    DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
 #endif
 }
@@ -116,23 +116,13 @@ int SCSI_OpenDevice(int ip)
                   pDev[ip].avail = 0;
                   return(0);
                 }
-            } else { /* inquiry failed */
-              close(DeviceFD);
-              free(pDev[ip].inquiry);
-              pDev[ip].inquiry = NULL;
-              pDev[ip].avail = 0;
-              return(0);
             }
-
-          /*
-           * Open ok, but no SCSI communication available 
-           */
-
-          free(pDev[ip].inquiry);
-          pDev[ip].inquiry = NULL;
-          close(DeviceFD);
-          pDev[ip].avail = 0;
-          return(0);
+           /* inquiry failed or no SCSI communication available */
+            close(DeviceFD);
+            free(pDev[ip].inquiry);
+            pDev[ip].inquiry = NULL;
+            pDev[ip].avail = 0;
+            return(0);
         }
     } else {
       if ((DeviceFD = open(pDev[ip].dev, O_RDWR | O_EXCL)) >= 0)
@@ -165,11 +155,11 @@ int SCSI_CloseDevice(int DeviceFD)
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *pRequestSense,
-                        int RequestSenseLength)
+                        size_t DataBufferLength,
+                        RequestSense_T *pRequestSense,
+                        size_t RequestSenseLength)
 {
   extern OpenFiles_T *pDev;
   ExtendedRequestSense_T ExtendedRequestSense;
@@ -177,14 +167,21 @@ int SCSI_ExecuteCommand(int DeviceFD,
   int Result;
   int retries = 5;
   
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
+  /* Clear buffer for cases where sense is not returned */
+  memset(pRequestSense, 0, RequestSenseLength);
+
   if (pDev[DeviceFD].avail == 0)
     {
       return(SCSI_ERROR);
     }
   
-  memset(&ds, 0, sizeof(struct dsreq));
+  memset(&ds, 0, SIZEOF(struct dsreq));
   memset(pRequestSense, 0, RequestSenseLength);
-  memset(&ExtendedRequestSense, 0 , sizeof(ExtendedRequestSense_T)); 
+  memset(&ExtendedRequestSense, 0 , SIZEOF(ExtendedRequestSense_T)); 
   
   ds.ds_flags = DSRQ_SENSE|DSRQ_TRACE|DSRQ_PRINT; 
   /* Timeout */
@@ -236,35 +233,28 @@ int SCSI_ExecuteCommand(int DeviceFD,
       {
       case ST_BUSY:                /*  BUSY */
         break;
+
       case STA_RESERV:             /*  RESERV CONFLICT */
         if (retries > 0)
           sleep(2);
         continue;
+
       case ST_GOOD:                /*  GOOD 0x00 */
         switch (RET(&ds))
           {
           case DSRT_SENSE:
             return(SCSI_SENSE);
-            break;
-          case DSRT_SHORT:
-            return(SCSI_OK);
-            break;
-          case DSRT_OK:
-          default:
-            return(SCSI_OK);
           }
+          return(SCSI_OK);
+
       case ST_CHECK:               /*  CHECK CONDITION 0x02 */ 
         switch (RET(&ds))
           {
           case DSRT_SENSE:
             return(SCSI_SENSE);
-            break;
-          default:
-            return(SCSI_CHECK);
-            break;
           }
         return(SCSI_CHECK);
-        break;
+
       case ST_COND_MET:            /*  INTERM/GOOD 0x10 */
       default:
         continue;
@@ -313,7 +303,7 @@ int Tape_Status( int DeviceFD)
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
     {
-      dbprintf(("Tape_Status error ioctl %d\n",errno));
+      dbprintf(("Tape_Status error ioctl %s\n",strerror(errno)));
       SCSI_CloseDevice(DeviceFD);
       return(-1);
     }
index 750bd626cae3acee7fa1190903ac20afab224ccb..9885349fb52161ad4b355974bcbd19b92cf9d584 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-linux.c,v 1.28 2006/03/09 20:06:10 johnfranks Exp $
+ * $Id: scsi-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $
  *
  * Interface to execute SCSI commands on Linux
  *
 
 #include <scsi-defs.h>
 
+extern OpenFiles_T *pDev;
 
-void SCSI_OS_Version()
+void SCSI_OS_Version(void)
 {
 #ifndef lint
-   static char rcsid[] = "$Id: scsi-linux.c,v 1.28 2006/03/09 20:06:10 johnfranks Exp $";
+   static char rcsid[] = "$Id: scsi-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $";
    DebugPrint(DEBUG_ERROR, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
 #endif
 }
 
 int SCSI_CloseDevice(int DeviceFD)
 {
-  extern OpenFiles_T *pDev;
   int ret = 0;
   
   if (pDev[DeviceFD].devopen == 1)
@@ -114,7 +114,6 @@ int SCSI_CloseDevice(int DeviceFD)
 #ifdef LINUX_SG
 int SCSI_OpenDevice(int ip)
 {
-  extern OpenFiles_T *pDev;
   int DeviceFD;
   int i;
   int timeout;
@@ -134,12 +133,12 @@ int SCSI_OpenDevice(int ip)
               if (S_ISLNK(pstat.st_mode) == 1)
                 {
                   DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : is a link, checking destination\n");
-                  if ((buffer = (char *)malloc(512)) == NULL)
+                  if ((buffer = (char *)malloc(513)) == NULL)
                     {
                       DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_OpenDevice : malloc failed\n");
                       return(0);
                     }
-                  memset(buffer, 0, 512);
+                  memset(buffer, 0, 513);
                   if (( i = readlink(pDev[ip].dev, buffer, 512)) == -1)
                     {
                       if (errno == ENAMETOOLONG )
@@ -206,7 +205,7 @@ int SCSI_OpenDevice(int ip)
                 }
             }
           pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
-          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, (u_char)INQUIRY_SIZE) == 0)
             {
               if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
                 {
@@ -288,21 +287,27 @@ int SCSI_OpenDevice(int ip)
   return(0);
 }
 
-#define SCSI_OFF sizeof(struct sg_header)
+#define SCSI_OFF SIZEOF(struct sg_header)
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *pRequestSense,
-                        int RequestSenseLength)
+                        size_t DataBufferLength,
+                        RequestSense_T *pRequestSense,
+                        size_t RequestSenseLength)
 {
-  extern OpenFiles_T *pDev;
   struct sg_header *psg_header;
   char *buffer;
-  int osize = 0;
-  int status;
+  size_t osize = 0;
+  ssize_t status;
+
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
+  /* Clear buffer for cases where sense is not returned */
+  memset(pRequestSense, 0, RequestSenseLength);
 
   if (pDev[DeviceFD].avail == 0)
     {
@@ -337,7 +342,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
       psg_header->twelve_byte = 0;
     }
   psg_header->result = 0;
-  psg_header->reply_len = SCSI_OFF + DataBufferLength;
+  psg_header->reply_len = (int)(SCSI_OFF + DataBufferLength);
   
   switch (Direction)
     {
@@ -352,8 +357,9 @@ int SCSI_ExecuteCommand(int DeviceFD,
   DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
   
   status = write(pDev[DeviceFD].fd, buffer, SCSI_OFF + CDB_Length + osize);
-  if ( status < 0 || status != SCSI_OFF + CDB_Length + osize ||
-       psg_header->result ) 
+  if ( (status < (ssize_t)0) ||
+       (status != (ssize_t)(SCSI_OFF + CDB_Length + osize)) ||
+       (psg_header->result != 0)) 
     {
       dbprintf(("SCSI_ExecuteCommand error send \n"));
       SCSI_CloseDevice(DeviceFD);
@@ -366,8 +372,9 @@ int SCSI_ExecuteCommand(int DeviceFD,
   memset(pRequestSense, 0, RequestSenseLength);
   memcpy(pRequestSense, psg_header->sense_buffer, 16);
   
-  if ( status < 0 || status != SCSI_OFF + DataBufferLength || 
-       psg_header->result ) 
+  if ( (status < 0) ||
+       (status != (ssize_t)(SCSI_OFF + DataBufferLength)) || 
+       (psg_header->result != 0)) 
     { 
       dbprintf(("SCSI_ExecuteCommand error read \n"));
       dbprintf(("Status %d (%d) %2X\n", status, SCSI_OFF + DataBufferLength,psg_header->result ));
@@ -401,7 +408,6 @@ static inline int max(int x, int y)
 
 int SCSI_OpenDevice(int ip)
 {
-  extern OpenFiles_T *pDev;
   int DeviceFD;
   int i;
 
@@ -415,7 +421,7 @@ int SCSI_OpenDevice(int ip)
           pDev[ip].SCSI = 0;
           pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
           dbprintf(("SCSI_OpenDevice : use ioctl interface\n"));
-          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, (u_char)INQUIRY_SIZE) == 0)
             {
               if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
                 {
@@ -457,10 +463,9 @@ int SCSI_ExecuteCommand(int DeviceFD,
                         int CDB_Length,
                         void *DataBuffer,
                         int DataBufferLength,
-                        char *pRequestSense,
+                        RequestSense_T *pRequestSense,
                         int RequestSenseLength)
 {
-  extern OpenFiles_T *pDev;
   unsigned char *Command;
   int Zero = 0, Result;
  
@@ -523,7 +528,6 @@ int SCSI_ExecuteCommand(int DeviceFD,
  */
 int Tape_Ioctl( int DeviceFD, int command)
 {
-  extern OpenFiles_T *pDev;
   struct mtop mtop;
   int ret = 0;
 
@@ -545,7 +549,7 @@ int Tape_Ioctl( int DeviceFD, int command)
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
     {
-      dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+      dbprintf(("Tape_Ioctl error ioctl %s\n",strerror(errno)));
       SCSI_CloseDevice(DeviceFD);
       return(-1);
     }
@@ -556,10 +560,10 @@ int Tape_Ioctl( int DeviceFD, int command)
 
 int Tape_Status( int DeviceFD)
 {
-  extern OpenFiles_T *pDev;
   struct mtget mtget;
   int ret = 0;
 
+  memset(&mtget, 0, SIZEOF(mtget));
   if (pDev[DeviceFD].devopen == 0)
     {
       if (SCSI_OpenDevice(DeviceFD) == 0)
@@ -568,7 +572,8 @@ int Tape_Status( int DeviceFD)
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
   {
-     DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %d\n",errno);
+     DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %s\n",
+               strerror(errno));
      SCSI_CloseDevice(DeviceFD);
      return(-1);
   }
@@ -612,8 +617,6 @@ int ScanBus(int print)
 {
   DIR *dir;
   struct dirent *dirent;
-  extern OpenFiles_T *pDev;
-  extern int errno;
   int count = 0;
 
   if ((dir = opendir("/dev/")) == NULL)
@@ -628,7 +631,8 @@ int ScanBus(int print)
       {
         pDev[count].dev = malloc(10);
         pDev[count].inqdone = 0;
-        sprintf(pDev[count].dev,"/dev/%s", dirent->d_name);
+        snprintf(pDev[count].dev, SIZEOF(pDev[count].dev),
+           "/dev/%s", dirent->d_name);
         if (OpenDevice(count,pDev[count].dev, "Scan", NULL ))
           {
             SCSI_CloseDevice(count);
index 7aa6f865adee7e2419a9d1ca1a195c70b80bf3f0..8f6fd7737820957211a16ab31d91390022006271 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: scsi-proto.c,v 1.3 1998/06/13 06:13:25 oliva Exp $
+ *     $Id: scsi-proto.c,v 1.4 2006/05/25 01:47:10 johnfranks Exp $
  *
  *     scsi-proto.c -- library routines to handle the changer
  *                     Prototype file for customization
@@ -55,7 +55,7 @@ void eject_tape(char *tape)
 /*
  * find the first empty slot 
  */
-int find_empty(int fd)
+int find_empty( int fd, int start, int end)
 {
     /*
      * find an empty slot to insert a tape into (if required)
index c20003fc733d153db79d1d097a5b05a675609796..eb9bd77cfd65f91bc288e247c9c9b43ed6f09725 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: scsi-solaris.c,v 1.25 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-solaris.c,v 1.26 2006/05/25 01:47:10 johnfranks Exp $
  *
  * Interface to execute SCSI commands on an Sun Workstation
  *
@@ -60,7 +60,7 @@
 void SCSI_OS_Version()
 {
 #ifndef lint
-   static char rcsid[] = "$Id: scsi-solaris.c,v 1.25 2005/10/15 13:20:47 martinea Exp $";
+   static char rcsid[] = "$Id: scsi-solaris.c,v 1.26 2006/05/25 01:47:10 johnfranks Exp $";
    DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
 #endif
 }
@@ -82,7 +82,7 @@ int SCSI_OpenDevice(int ip)
           pDev[ip].devopen = 1;
           pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
           
-          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, (unsigned char)INQUIRY_SIZE) == 0)
             {
               if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
                 {
@@ -111,12 +111,10 @@ int SCSI_OpenDevice(int ip)
                   free(pDev[ip].inquiry);
                   return(0);
                 }
-            } else {
-              free(pDev[ip].inquiry);
-              pDev[ip].inquiry = NULL;
-              return(1);
             }
-          return(1);
+            free(pDev[ip].inquiry);
+            pDev[ip].inquiry = NULL;
+            return(1);
         } else {
           dbprintf(("SCSI_OpenDevice %s failed\n", pDev[ip].dev));
           return(0);
@@ -147,11 +145,11 @@ int SCSI_CloseDevice(int DeviceFD)
 int SCSI_ExecuteCommand(int DeviceFD,
                         Direction_T Direction,
                         CDB_T CDB,
-                        int CDB_Length,
+                        size_t CDB_Length,
                         void *DataBuffer,
-                        int DataBufferLength,
-                        char *pRequestSense,
-                        int RequestSenseLength)
+                        size_t DataBufferLength,
+                        RequestSense_T *RequestSense,
+                        size_t RequestSenseLength)
 {
   extern OpenFiles_T *pDev;
   extern FILE * debug_file;
@@ -159,11 +157,15 @@ int SCSI_ExecuteCommand(int DeviceFD,
   int retries = 1;
   extern int errno;
   struct uscsi_cmd Command;
-#if 0
-  ExtendedRequestSense_T pExtendedRequestSense;
-#endif
   static int depth = 0;
 
+  /* Basic sanity checks */
+  assert(CDB_Length <= UCHAR_MAX);
+  assert(RequestSenseLength <= UCHAR_MAX);
+
+  /* Clear buffer for cases where sense is not returned */
+  memset(RequestSense, 0, RequestSenseLength);
+
   if (pDev[DeviceFD].avail == 0)
     {
       return(SCSI_ERROR);
@@ -175,8 +177,8 @@ int SCSI_ExecuteCommand(int DeviceFD,
      SCSI_CloseDevice(DeviceFD);
      return SCSI_ERROR;
   }
-  memset(&Command, 0, sizeof(struct uscsi_cmd));
-  memset(pRequestSense, 0, RequestSenseLength);
+  memset(&Command, 0, SIZEOF(struct uscsi_cmd));
+  memset(RequestSense, 0, RequestSenseLength);
   switch (Direction)
     {
     case Input:
@@ -196,7 +198,7 @@ int SCSI_ExecuteCommand(int DeviceFD,
   /* Set timeout to 5 minutes. */
   Command.uscsi_timeout = 300;
   Command.uscsi_cdb = (caddr_t) CDB;
-  Command.uscsi_cdblen = CDB_Length;
+  Command.uscsi_cdblen = (u_char)CDB_Length;
 
   if (DataBufferLength > 0)
     {  
@@ -211,8 +213,8 @@ int SCSI_ExecuteCommand(int DeviceFD,
         | USCSI_WRITE | USCSI_RQENABLE;
    }
 
-  Command.uscsi_rqbuf = (caddr_t) pRequestSense;
-  Command.uscsi_rqlen = RequestSenseLength;
+  Command.uscsi_rqbuf = (caddr_t)RequestSense;
+  Command.uscsi_rqlen = (u_char)RequestSenseLength;
   DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
   while (retries > 0)
   {
@@ -228,24 +230,19 @@ int SCSI_ExecuteCommand(int DeviceFD,
       ret = Command.uscsi_status;
       break;
     }
-    dbprintf(("ioctl on %d failed, errno %d, ret %d\n",pDev[DeviceFD].fd, errno, ret));
+    dbprintf(("ioctl on %d failed, errno %s, ret %d\n",
+             pDev[DeviceFD].fd, strerror(errno), ret));
 #if 0
     RequestSense(DeviceFD, &pExtendedRequestSense, 0);
 #endif
-    DecodeSense((RequestSense_T *)pRequestSense,
-               "SCSI_ExecuteCommand:", debug_file);
+    DecodeSense(RequestSense, "SCSI_ExecuteCommand:", debug_file);
     retries--;
   }
   --depth;
   SCSI_CloseDevice(DeviceFD);
 
-  switch (ret)
-    {
-    default:
-      DebugPrint(DEBUG_INFO, SECTION_SCSI,"ioctl ret (%d)\n",ret);
-      return(SCSI_OK);
-      break;
-    }
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"ioctl ret (%d)\n",ret);
+  return(SCSI_OK);
 }
 
 /*
@@ -274,7 +271,7 @@ int Tape_Ioctl( int DeviceFD, int command)
 
   if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
     {
-      dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+      dbprintf(("Tape_Ioctl error ioctl %s\n", strerror(errno)));
       SCSI_CloseDevice(DeviceFD);
       return(-1);
     }
@@ -289,13 +286,14 @@ int Tape_Status( int DeviceFD)
   struct mtget mtget;
   int ret = -1;
 
+  memset(&mtget, 0, SIZEOF(mtget));
   if (pDev[DeviceFD].devopen == 0)
       if (SCSI_OpenDevice(DeviceFD) == 0)
           return(-1);
   
   if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
     {
-      dbprintf(("Tape_Status error ioctl %d\n",errno));
+      dbprintf(("Tape_Status error ioctl %s\n", strerror(errno)));
       SCSI_CloseDevice(DeviceFD);
       return(-1);
     }
@@ -326,6 +324,7 @@ int Tape_Status( int DeviceFD)
 
 int ScanBus(int print)
 {
+       (void)print;    /* Quiet unused parameter warning */
        return(-1);
 }
 
index 955084740e3c2616dc8927de1d38134008ed15cd..e5bbc1353bcb78af388b146ed6e3b9562c8a0b87 100644 (file)
@@ -8,7 +8,7 @@
 #include <string.h>
 #endif
 
-#include "scsi-defs.h" 
+#include "scsi-defs.h"
 /*
  Handling of Sense codes which are returned from the device
  At the moment the following status us returned
  * Generic one, this is used if not information is found based on the ident of the device
  */
        { "generic", "", TYPE_TAPE,  SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
-       { "generic", "", TYPE_TAPE,  SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "generic", "", TYPE_TAPE,  SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "generic", "", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
-       { "generic", "", TYPE_TAPE,  SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "generic", "", TYPE_TAPE,  SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
 
        { "generic", "", TYPE_TAPE , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
        { "generic", "", TYPE_TAPE , SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "The drive is not ready, but it is in the process of becoming ready"},
        { "generic", "", TYPE_TAPE , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "generic", "", TYPE_TAPE,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "generic", "", TYPE_TAPE,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "generic", "", TYPE_TAPE , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "generic", "", TYPE_TAPE,  SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "generic", "", TYPE_TAPE,  SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 
        { "generic", "", TYPE_TAPE , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
-       { "generic", "", TYPE_TAPE,  SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "generic", "", TYPE_TAPE,  SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "generic", "", TYPE_TAPE , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "generic", "", TYPE_TAPE,  SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+       { "generic", "", TYPE_TAPE,  SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
 
        { "generic", "", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "generic", "", TYPE_TAPE,  SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+       { "generic", "", TYPE_TAPE,  SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
 
-       { "generic", "", TYPE_TAPE , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "generic", "", TYPE_TAPE , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 
        { "generic", "", TYPE_CHANGER,  SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
-       { "generic", "", TYPE_CHANGER,  SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "generic", "", TYPE_CHANGER,  SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "generic", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
-       { "generic", "", TYPE_CHANGER,  SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "generic", "", TYPE_CHANGER,  SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
 
        { "generic", "", TYPE_CHANGER , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
        { "generic", "", TYPE_CHANGER , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "generic", "", TYPE_CHANGER,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "generic", "", TYPE_CHANGER,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "generic", "", TYPE_CHANGER , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "generic", "", TYPE_CHANGER,  SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "generic", "", TYPE_CHANGER,  SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 
        { "generic", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
-       { "generic", "", TYPE_CHANGER,  SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "generic", "", TYPE_CHANGER,  SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "generic", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "generic", "", TYPE_CHANGER,  SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+       { "generic", "", TYPE_CHANGER,  SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
 
        { "generic", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "generic", "", TYPE_CHANGER,  SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+       { "generic", "", TYPE_CHANGER,  SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
 
-       { "generic", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "generic", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 
-       { "generic", "", TYPE_CHANGER , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
-/* 
+       { "generic", "", TYPE_CHANGER , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+/*
  *
  * ADIC DAT Autochanger
  *
  */
        { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
-       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "DAT AutoChanger", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
-       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
 
        { "DAT AutoChanger", "", TYPE_CHANGER , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
-       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "DAT AutoChanger", "", TYPE_CHANGER , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 
        { "DAT AutoChanger", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
-       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "DAT AutoChanger", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
 
        { "DAT AutoChanger", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
        { "DAT AutoChanger", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x28, 0x01, SENSE_IES, "Door opend"},
-       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
 
-       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "DAT AutoChanger", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 
-       { "DAT AutoChanger", "", TYPE_CHANGER , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "DAT AutoChanger", "", TYPE_CHANGER , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 
 /*
  *
  *     L500 (for the L500 ATL library)
  * */
-       
+
        { "L500", "", TYPE_CHANGER,  SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
-       { "L500", "", TYPE_CHANGER,  SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "L500", "", TYPE_CHANGER,  SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
        { "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0a, 0x0, SENSE_IGNORE, "Error Log overflow"},
        { "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x44, 0xc2, SENSE_IGNORE, "EEPROM Copy 2 bad"},
        { "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x47, 0x0, SENSE_IGNORE, "SCSI parity error"},
        { "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x48, 0x0, SENSE_IGNORE, "SCSI IDE message received"},
-       { "L500", "", TYPE_CHANGER,  SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "L500", "", TYPE_CHANGER,  SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
 
        { "L500", "", TYPE_CHANGER , SENSE_NOT_READY, 0x0, 0x0, SENSE_ABORT, "Scsi port not initialized"},
        { "L500", "", TYPE_CHANGER , SENSE_NOT_READY, 0x04, 0x01, SENSE_RETRY, "Becoming ready, scanning magazines, etc"},
        { "L500", "", TYPE_CHANGER , SENSE_NOT_READY, 0x04, 0x03, SENSE_ABORT, "Unit not ready: manual intervention required: Door Open"},
 /* needed? */
        { "L500", "", TYPE_CHANGER , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "L500", "", TYPE_CHANGER,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "L500", "", TYPE_CHANGER,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
 /*     Not used by L500
        { "L500", "", TYPE_CHANGER , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "L500", "", TYPE_CHANGER,  SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "L500", "", TYPE_CHANGER,  SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 */
        { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x0,  0x0,  SENSE_ABORT, "Hardware Error"},
        { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x3a, 0x80, SENSE_ABORT, "Media not present"},
        { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x83, SENSE_ABORT, "Slot empty during LOAD CARTRIDGE"},
        { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x84, SENSE_ABORT, "Cleaning Tape expired"},
        { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x85, SENSE_ABORT, "Cleaning Failed"},
-       { "L500", "", TYPE_CHANGER,  SENSE_HARDWARE_ERROR,   -1,   -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "L500", "", TYPE_CHANGER,  SENSE_HARDWARE_ERROR,   UCHAR_MAX,   UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x0, 0x0,   SENSE_ABORT, "Illegal Request"},
        { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x1a, 0x0,  SENSE_ABORT, "Parameter length error"},
        { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x53, 0x01, SENSE_ABORT, "Cartridge failed to unload"},
        { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0xf1, 0x0,  SENSE_ABORT, "Command unspecified"},
        { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0xf1, 0x02, SENSE_ABORT, "Unrecognized loader command"},
-       { "L500", "", TYPE_CHANGER,  SENSE_ILLEGAL_REQUEST , -1, -1,    SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+       { "L500", "", TYPE_CHANGER,  SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX,    SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
 
        { "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x0,  0x0,  SENSE_RETRY, "Unit Attention"},
        { "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x28, 0x0,  SENSE_RETRY, "Not ready to Ready transition"},
        { "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x29, 0x0,  SENSE_RETRY, "Reset occured"},
        { "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x2a, 0x01, SENSE_ABORT, "Mode parameters changed"},
        { "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x3f, 0x01, SENSE_ABORT, "Microcode has changed"},
-       { "L500", "", TYPE_CHANGER,  SENSE_UNIT_ATTENTION, -1, -1,     SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+       { "L500", "", TYPE_CHANGER,  SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX,     SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
 
 /*     Not used by L500
-       { "L500", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "L500", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 */
        { "L500", "", TYPE_CHANGER,  SENSE_ABORTED_COMMAND, 0x43, 0x0, SENSE_ABORT, "SCSI message error"},
        { "L500", "", TYPE_CHANGER,  SENSE_ABORTED_COMMAND, 0x47, 0x0, SENSE_ABORT, "SCSI parity error"},
        { "L500", "", TYPE_CHANGER,  SENSE_ABORTED_COMMAND, 0x48, 0x0, SENSE_ABORT, "SCSI IDE message received"},
        { "L500", "", TYPE_CHANGER,  SENSE_ABORTED_COMMAND, 0x49, 0x0, SENSE_ABORT, "SCSI invalid message"},
        { "L500", "", TYPE_CHANGER,  SENSE_ABORTED_COMMAND, 0x4e, 0x0, SENSE_ABORT, "SCSI overlapped commands"},
-       
-       { "L500", "", TYPE_CHANGER,  SENSE_ABORTED_COMMAND, -1, -1, SENSE_ABORT, "Default for SENSE_ABORTED_COMMAND"},
-       { "L500", "", TYPE_CHANGER , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+
+       { "L500", "", TYPE_CHANGER,  SENSE_ABORTED_COMMAND, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ABORTED_COMMAND"},
+       { "L500", "", TYPE_CHANGER , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 
 /*
  * HP C1553A Tape
  */
        { "C1553A", "", TYPE_TAPE,  SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
-       { "C1553A", "", TYPE_TAPE,  SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "C1553A", "", TYPE_TAPE,  SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "C1553A", "", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
-       { "C1553A", "", TYPE_TAPE,  SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "C1553A", "", TYPE_TAPE,  SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
 
        { "C1553A", "", TYPE_TAPE , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
        { "C1553A", "", TYPE_TAPE , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "C1553A", "", TYPE_TAPE,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "C1553A", "", TYPE_TAPE,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "C1553A", "", TYPE_TAPE , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "C1553A", "", TYPE_TAPE,  SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "C1553A", "", TYPE_TAPE,  SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 
        { "C1553A", "", TYPE_TAPE , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
-       { "C1553A", "", TYPE_TAPE,  SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "C1553A", "", TYPE_TAPE,  SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "C1553A", "", TYPE_TAPE , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "C1553A", "", TYPE_TAPE,  SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+       { "C1553A", "", TYPE_TAPE,  SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
 
        { "C1553A", "", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "C1553A", "", TYPE_TAPE,  SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+       { "C1553A", "", TYPE_TAPE,  SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
 
-       { "C1553A", "", TYPE_TAPE , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "C1553A", "", TYPE_TAPE , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 
        { "C1553A", "", TYPE_CHANGER,  SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
-       { "C1553A", "", TYPE_CHANGER,  SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "C1553A", "", TYPE_CHANGER,  SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "C1553A", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
-       { "C1553A", "", TYPE_CHANGER,  SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "C1553A", "", TYPE_CHANGER,  SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
 
        { "C1553A", "", TYPE_CHANGER , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
        { "C1553A", "", TYPE_CHANGER , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "C1553A", "", TYPE_CHANGER,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "C1553A", "", TYPE_CHANGER,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "C1553A", "", TYPE_CHANGER , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "C1553A", "", TYPE_CHANGER,  SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "C1553A", "", TYPE_CHANGER,  SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 
        { "C1553A", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
-       { "C1553A", "", TYPE_CHANGER,  SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "C1553A", "", TYPE_CHANGER,  SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "C1553A", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "C1553A", "", TYPE_CHANGER,  SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-       
+       { "C1553A", "", TYPE_CHANGER,  SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
        { "C1553A", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "C1553A", "", TYPE_CHANGER,  SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
-       { "C1553A", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "C1553A", "", TYPE_CHANGER,  SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
 
-       { "C1553A", "", TYPE_CHANGER , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "C1553A", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+
+       { "C1553A", "", TYPE_CHANGER , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 /*
  * HP C1537A Tape
  */
        { "C1537A", "", TYPE_TAPE,  SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
-       { "C1537A", "", TYPE_TAPE,  SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "C1537A", "", TYPE_TAPE,  SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "C1537A", "", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
-       { "C1537A", "", TYPE_TAPE,  SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "C1537A", "", TYPE_TAPE,  SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
 
        { "C1537A", "", TYPE_TAPE , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
        { "C1537A", "", TYPE_TAPE , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
        { "C1537A", "", TYPE_TAPE , SENSE_NOT_READY, 0x04, 0x0, SENSE_RETRY, "tape is being ejected"},
        { "C1537A", "", TYPE_TAPE , SENSE_NOT_READY, 0x04, 0x01, SENSE_RETRY, "tape is being loaded"},
-       { "C1537A", "", TYPE_TAPE,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "C1537A", "", TYPE_TAPE,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "C1537A", "", TYPE_TAPE , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "C1537A", "", TYPE_TAPE,  SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "C1537A", "", TYPE_TAPE,  SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 
        { "C1537A", "", TYPE_TAPE , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
-       { "C1537A", "", TYPE_TAPE,  SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "C1537A", "", TYPE_TAPE,  SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "C1537A", "", TYPE_TAPE , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "C1537A", "", TYPE_TAPE,  SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-       
+       { "C1537A", "", TYPE_TAPE,  SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
        { "C1537A", "", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
        { "C1537A", "", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x28, 0x0, SENSE_RETRY, "Not Ready to Ready Transition"},
-       { "C1537A", "", TYPE_TAPE,  SENSE_UNIT_ATTENTION , -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
-       
-       { "C1537A", "", TYPE_TAPE,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "C1537A", "", TYPE_TAPE,  SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+
+       { "C1537A", "", TYPE_TAPE,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 
-       { "C1537A", "", TYPE_TAPE , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "C1537A", "", TYPE_TAPE , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 /*
  * Tandberg Tape
  */
        { "TDS 1420", "", TYPE_TAPE, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
-       { "TDS 1420", "", TYPE_TAPE, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "TDS 1420", "", TYPE_TAPE, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "TDS 1420", "", TYPE_TAPE, SENSE_IES, 0x83, 0x0, SENSE_IES, "IES"},
        { "TDS 1420", "", TYPE_TAPE, SENSE_IES, 0x83, 0x1, SENSE_IES, "IES"},
        { "TDS 1420", "", TYPE_TAPE, SENSE_IES, 0x83, 0x4, SENSE_IGNORE, "IES"},
        { "TDS 1420", "", TYPE_TAPE, SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
-       { "TDS 1420", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "TDS 1420", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
 
        { "TDS 1420", "", TYPE_TAPE, SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
        { "TDS 1420", "", TYPE_TAPE, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "TDS 1420", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "TDS 1420", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "TDS 1420", "", TYPE_TAPE, SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "TDS 1420", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "TDS 1420", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 
        { "TDS 1420", "", TYPE_TAPE, SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
-       { "TDS 1420", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "TDS 1420", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "TDS 1420", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "TDS 1420", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-       
+       { "TDS 1420", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
        { "TDS 1420", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "TDS 1420", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
-       { "TDS 1420", "", TYPE_TAPE, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "TDS 1420", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
+       { "TDS 1420", "", TYPE_TAPE, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 /*
  * DLT 8000 Tape
- * 
- * */
+ */
        { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NULL, 0x0, 0x0,   SENSE_NO, "No Sense"},
        { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NULL, 0x0, 0x01,  SENSE_NO, "Unexpected FM encountered"},
        { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NULL, 0x0, 0x02,  SENSE_NO, "EOM encountered"},
        { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NULL, 0x0, 0x04,  SENSE_NO, "BOM encountered"},
        { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NULL, 0x5d, 0x00, SENSE_NO, "Failure prediction threshold exceeded"},
        { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NULL, 0x27, 0x82, SENSE_NO, "Data safety write protect"},
-       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NULL , -1, -1,    SENSE_RETRY, "Default for SENSE_NULL"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NULL , UCHAR_MAX, UCHAR_MAX,    SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x17, SENSE_IGNORE, "Cleaning requested"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x80, 0x02, SENSE_IGNORE, "Cleaning requested"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x80, 0x03, SENSE_IGNORE, "Softe error exceeds threshold"},
 /*     { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x47, 0x0, SENSE_IGNORE, "Scsi Parity Error"}, */
-       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready (this shouldn't happen should it?)"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "The drive is not ready, but it is in the process of becoming ready"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x30,0x02, SENSE_ABORT, "Incompatible tape format"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x30,0x03, SENSE_ABORT, "Cleaning Cartridge in drive"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x5a,0x01, SENSE_ABORT, "Asynchronous eject occurred"},
-       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
-       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
 
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
-       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
 
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
 
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
        { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x28, 0x0, SENSE_RETRY, "Not ready to ready transition"},
-       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE,  SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
 
-       { "DLT8000", "QUANTUM", TYPE_TAPE , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 
 /*
  * DLT 7000 Tape
        { "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
        { "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x2, SENSE_TAPE_NOT_ONLINE, "Logical Unit not ready, in progress becoming ready"},
        { "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
-       { "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "DLT7000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "DLT7000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
+       { "DLT7000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
        { "DLT7000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "DLT7000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-       
-       { "DLT7000", "", TYPE_TAPE, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "DLT7000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
+       { "DLT7000", "", TYPE_TAPE, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 /*
  * DLT 4000 Tape
  */
        { "DLT4000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
        { "DLT4000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x2, SENSE_TAPE_NOT_ONLINE, "Logical Unit not ready, in progress becoming ready"},
        { "DLT4000", "", TYPE_TAPE, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
-       { "DLT4000", "", TYPE_TAPE,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "DLT4000", "", TYPE_TAPE,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "DLT4000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "DLT4000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
+       { "DLT4000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
        { "DLT4000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "DLT4000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-       
-       { "DLT4000", "", TYPE_TAPE, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "DLT4000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
+       { "DLT4000", "", TYPE_TAPE, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 /*
  * AIT VLS DLT Library
  */
        { "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
        { "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x2, SENSE_TAPE_NOT_ONLINE, "Logical Unit not ready, in progress becoming ready"},
        { "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
-       { "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "VLS_DLT", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "VLS_DLT", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
+       { "VLS_DLT", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
        { "VLS_DLT", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "VLS_DLT", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+       { "VLS_DLT", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
+       { "VLS_DLT", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 
-       { "VLS_DLT", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
-       
-       { "VLS_DLT", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "VLS_DLT", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 /*
  * AIT VLS SDX Library
  */
        { "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
        { "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x2, SENSE_TAPE_NOT_ONLINE, "Logical Unit not ready, in progress becoming ready"},
        { "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
-       { "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "VLS_SDX", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "VLS_SDX", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
+       { "VLS_SDX", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
        { "VLS_SDX", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "VLS_SDX", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-       
-       { "VLS_SDX", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "VLS_SDX", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
+       { "VLS_SDX", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 
-       { "VLS_SDX", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "VLS_SDX", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 /*
  * Exabyte 85058 Tape
  */
        { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Logical Unit not ready, in progress becoming ready"},
        { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
        { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "EXB-85058HE-0000", "", TYPE_TAPE,  SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "EXB-85058HE-0000", "", TYPE_TAPE,  SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
+       { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
        { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
-       { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-       { "EXB-85058HE-0000", "", TYPE_TAPE, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+       { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+       { "EXB-85058HE-0000", "", TYPE_TAPE, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
 /*
  * Exabyte 10e Library (Robot)
  */
        { "EXB-10e", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_RETRY, "Retry, no sense"},
        { "EXB-10e", "", TYPE_CHANGER, SENSE_NULL, 0x90, 0x2, SENSE_ABORT, "Illegal Request"},
        { "EXB-10e", "", TYPE_CHANGER, SENSE_NULL , 0x90, 0x3, SENSE_IES, "IES"},
-       { "EXB-10e", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
        { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Logical Unit not ready, in progress becoming ready"},
        { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8E, SENSE_ABORT, "The library is in Sequential mode"},
        { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
        { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
-       { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "EXB-10e", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "EXB-10e", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
        { "EXB-10e", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
        { "EXB-10e", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x91, 0x0, SENSE_CHM_FULL, "CHM full during reset"},
-       { "EXB-10e", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
-       
-       { "EXB-10e", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
+
+       { "EXB-10e", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 
-       { "EXB-10e", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
+       { "EXB-10e", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
 
 /*
  * Exabyte 210 Library (Robot)
        { "EXB-210", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_RETRY, "Retry, no sense"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_NULL, 0x90, 0x2, SENSE_ABORT, "Illegal Request"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_NULL , 0x90, 0x3, SENSE_IES, "IES"},
-       { "EXB-210", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Logical Unit not ready, in progress becoming ready"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8E, SENSE_ABORT, "The library is in Sequential mode"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
-       { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "EXB-210", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "EXB-210", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
+       { "EXB-210", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
        { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x91, 0x0, SENSE_CHM_FULL, "CHM full during reset"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x21, 0x01, SENSE_ABORT, "Invalid element address"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x04, SENSE_ABORT, "Destination magazine no installed"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x05, SENSE_ABORT, "Source tape drive not installed"},
        { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x06, SENSE_ABORT, "Destination tape drive not installed"},
-       
-       { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
-       
+
+       { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
+
        { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, 0x83, 0x0, SENSE_IES, "Label questionable"},
        { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, 0x83, 0x1, SENSE_IGNORE, "Cannot read bar code label"},
        { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, 0x83, 0x2, SENSE_ABORT, "Cartzridge magazine not present"},
        { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, 0x83, 0x8, SENSE_IGNORE, "Bar code label upside down"},
        { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, 0x83, 0x9, SENSE_IGNORE, "No bar code label"},
        { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, 0x83, 0xa, SENSE_IGNORE, ""},
-       { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 
-       { "EXB-210", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
+       { "EXB-210", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
 
 /*
  * Exabyte 230D Library (Robot)
        { "EXB-230D", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_RETRY, "Retry, no sense"},
        { "EXB-230D", "", TYPE_CHANGER, SENSE_NULL, 0x90, 0x2, SENSE_ABORT, "Illegal Request"},
        { "EXB-230D", "", TYPE_CHANGER, SENSE_NULL , 0x90, 0x3, SENSE_IES, "IES"},
-       { "EXB-230D", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
 
        { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
        { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Logical Unit not ready, in progress becoming ready"},
        { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8E, SENSE_ABORT, "The library is in Sequential mode"},
        { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
        { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
-       { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
-       { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
 
        { "EXB-230D", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
-       { "EXB-230D", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-       
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
        { "EXB-230D", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
        { "EXB-230D", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x91, 0x0, SENSE_CHM_FULL, "CHM full during reset"},
-       { "EXB-230D", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
-       
-       { "EXB-230D", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
 
-       { "EXB-230D", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
+       { "EXB-230D", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+
+       { "EXB-230D", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
 /*
  * Spectra TreeFrog  library
  */
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense, Unit Ready"},
-       { "215", "SPECTRA", TYPE_CHANGER, SENSE_NULL, -1, -1, SENSE_NO, "No Sense, Unit Ready"},
-       
+       { "215", "SPECTRA", TYPE_CHANGER, SENSE_NULL, UCHAR_MAX, UCHAR_MAX, SENSE_NO, "No Sense, Unit Ready"},
+
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Unit Not Ready"},
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Unit is Becoming Ready"},
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x83, SENSE_ABORT, "Door is open, Robot is Disabled"},
-       { "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
-       
+       { "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x4C, 0x0, SENSE_ABORT, "Unit Failed Initialization"},
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x84, 0x4, SENSE_ABORT, "DRAM Memory Failure"},
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x84, 0x4, SENSE_ABORT, "Two ore More SCSI ID's in the library are tehe same"},
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x85, 0x2, SENSE_ABORT, "Long Axis Robotics Error"},
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x85, 0x3, SENSE_ABORT, "Short Axis Robotics Error"},
        { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x85, 0x4, SENSE_ABORT, "Ambient Light Detected"},
-       { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
-       
+       { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x1A, 0x0, SENSE_ABORT, "Parameter List Length Error"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x20, 0x0, SENSE_ABORT, "Invalid Command Code"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x21, 0x01, SENSE_ABORT, "Invalid Element Address"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x18, SENSE_ABORT, "Conflict, Element is Reserved"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x81, 0x2, SENSE_ABORT, "Library is Full of Tapes"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x81, 0x3, SENSE_ABORT, "Grip Arm not Empty"},
-       {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, -1 , -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-       
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, UCHAR_MAX , UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x28, 0x0, SENSE_IES, "Inventory possible Altered"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x29, 0x0, SENSE_RETRY, "A Reset Has Occured"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x24, 0x1, SENSE_IGNORE, "Mode Parameter Have CHanged"},
-       {"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, -1, -1, SENSE_IGNORE, "Default for SENSE_UNIT_ATTENTION"},
-       
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_UNIT_ATTENTION"},
+
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x83, 0x00, SENSE_ABORT, "Barcode Label is Unread"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x83, 0x01, SENSE_ABORT, "Problem Reading Barcode"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x83, 0x11, SENSE_ABORT, "Tape in Drive & Unmounted"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x84, 0x03, SENSE_ABORT, "SCSI ID Same as Library's ID"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x84, 0x08,  SENSE_ABORT, "Busy Condition from Target"},
        {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x84, 0x18, SENSE_ABORT, "SCSI Reservation Conflict"},
-       {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC,  -1, -1, SENSE_ABORT, "Default for SENSE_VENDOR_SPECIFIC"},
-        
-       { "215", "SPECTRA", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC,  UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_VENDOR_SPECIFIC"},
+
+       { "215", "SPECTRA", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
 
-       { "215", "SPECTRA", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing found for Spectra/215"},
-       
-       { NULL, "", 0x0, -1, 0x0, 0x0, 0x0, ""},
+       { "215", "SPECTRA", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing found for Spectra/215"},
+
+       { NULL, "", 0x0, UCHAR_MAX, 0x0, 0x0, 0x0, ""},
 
        };
 
 
-void DumpSense()
+void
+DumpSense(void)
 {
        SenseType_T *pwork = (SenseType_T *)&SenseType;
 
-       while (pwork->ident != NULL)    
+       while (pwork->ident != NULL)
        {
-               if (pwork->sense == -1)
+               if (pwork->sense == UCHAR_MAX)
                {
                        printf("\n");
                } else {
@@ -664,17 +664,19 @@ void DumpSense()
  *     ASC is the ASC value returned by the scsi command
  *     ASCQ is the ASCQ value returned by the scsi command
  *     text is a pointer to store the clear text reason from the table.
- *     
+ *
  *     TODO:
- *     
+ *
 */
-int Sense2Action(char *ident,
-               unsigned char type,
-               unsigned char ignsense,
-               unsigned char sense,
-               unsigned char asc,
-               unsigned char ascq,
-               char **text)
+int
+Sense2Action(
+    char *             ident,
+    unsigned char      type,
+    unsigned char      ignsense,
+    unsigned char      sense,
+    unsigned char      asc,
+    unsigned char      ascq,
+    char **            text)
 {
        /*
         * Decode the combination of sense key, ASC, ASCQ and return what to do with this
@@ -692,15 +694,15 @@ int Sense2Action(char *ident,
                sense,
                asc,
                ascq));
-       
-       while (pwork->ident != NULL)    
+
+       while (pwork->ident != NULL)
        {
                if (strcmp(pwork->ident, "generic") == 0 && pwork->type == type && generic == NULL)
                {
                        generic = pwork;
                }
-               
-               if (strcmp(pwork->ident, ident) == 0 && pwork->type == type)
+
+               if (strcmp((char *)pwork->ident, (char *)ident) == 0 && pwork->type == type)
                 {
                        in = 1;
                 } else {
@@ -716,31 +718,31 @@ int Sense2Action(char *ident,
                if (in == 1)
                {
                        /* End of definitions for this device */
-                       if (pwork->sense == -1)
+                       if (pwork->sense == UCHAR_MAX)
                        {
-                               *text = (char *)stralloc(pwork->text);
+                               *text = stralloc(pwork->text);
                                dbprintf(("Sense2Action   END : no match for %s %s\n",
                                        pwork->ident,
                                        pwork->vendor));
                                return(pwork->ret);
                        }
-                       
+
                        if (ignsense)
                        {
                                if (pwork->asc ==  asc && pwork->ascq == ascq)
                                {
-                                       *text = (char *)stralloc(pwork->text);
+                                       *text = stralloc(pwork->text);
                                        dbprintf(("Sense2Action END(IGN) : match for %s %s  return -> %d/%s\n",
                                                pwork->ident,
                                                pwork->vendor,
                                                pwork->ret,
-                                               *text));        
+                                               *text));
                                        return(pwork->ret);
                                }
                                pwork++;
                                continue;
-                       } 
-                       
+                       }
+
                        if (pwork->sense == sense)
                        {
                                /* Matching ASC/ASCQ, if yes return the defined result code */
@@ -751,45 +753,47 @@ int Sense2Action(char *ident,
                                                pwork->ident,
                                                pwork->vendor,
                                                pwork->ret,
-                                               *text));                
+                                               *text));
                                        return(pwork->ret);
                                }
-                               
+
                                /* End of definitions for this sense type, if yes return the default
                                 * for this type
                                 */
-                               if (    pwork->asc == -1 && pwork->ascq == -1)
+                               if (    pwork->asc == UCHAR_MAX && pwork->ascq == UCHAR_MAX)
                                {
                                        *text = (char *)stralloc(pwork->text);
                                        dbprintf(("Sense2Action   END : no match for %s %s  return -> %d/%s\n",
                                                pwork->ident,
                                                pwork->vendor,
                                                pwork->ret,
-                                               *text));        
+                                               *text));
                                        return(pwork->ret);
-                               }                       
+                               }
                        }
                }
                pwork++;
        }
 
-       /* 
+       /*
         * Ok no match found, so lets return the values from the generic table
         */
        dbprintf(("Sense2Action generic start :\n"));
-       while ((generic != NULL) && generic->ident != NULL)
-       {         
-               if (generic->sense == -1)
+       while (generic != NULL) {
+               if (generic->ident == NULL)
+                  break;
+
+               if (generic->sense == UCHAR_MAX)
                {
                        *text = (char *)stralloc(generic->text);
                        dbprintf(("Sense2Action generic END : match for %s %s  return -> %d/%s\n",
                                generic->ident,
                                generic->vendor,
                                generic->ret,
-                               *text));        
+                               *text));
                        return(generic->ret);
                }
-               
+
                if (ignsense)
                {
                        if (generic->asc ==  asc && generic->ascq == ascq)
@@ -799,13 +803,13 @@ int Sense2Action(char *ident,
                                        generic->ident,
                                        generic->vendor,
                                        generic->ret,
-                                       *text));        
+                                       *text));
                                return(generic->ret);
                        }
                        generic++;
                        continue;
-               } 
-                       
+               }
+
                if (generic->sense == sense)
                {
                        /* Matching ASC/ASCQ, if yes return the defined result code */
@@ -816,28 +820,28 @@ int Sense2Action(char *ident,
                                        generic->ident,
                                        generic->vendor,
                                        generic->ret,
-                                       *text));        
+                                       *text));
                                return(generic->ret);
                        }
-                       
+
                        /* End of definitions for this sense type, if yes return the default
                         * for this type
                         */
-                       if (    generic->asc == -1 && generic->ascq == -1)
+                       if (    generic->asc == UCHAR_MAX && generic->ascq == UCHAR_MAX)
                        {
                                *text = (char *)stralloc(generic->text);
                                dbprintf(("Sense2Action generic END : no match for %s %s  return -> %d/%s\n",
                                        generic->ident,
                                        generic->vendor,
                                        generic->ret,
-                                       *text));        
+                                       *text));
                                return(generic->ret);
-                       }                       
+                       }
                        generic++;
                        continue;
                }
                generic++;
-       }       
+       }
 
        dbprintf(("Sense2Action END:\n"));
        *text = (char *)stralloc("No match found");
index a7f5b9147675ddecddaf0c4bc6273b8c5306d631..b479e122e6037bf442d70ad8d04a8738b09e059b 100644 (file)
@@ -1,12 +1,16 @@
 # Makefile for Amanda client programs.
 
 INCLUDES =     -I$(top_builddir)/common-src \
-               -I$(top_srcdir)/common-src
+               -I$(top_srcdir)/common-src \
+               -I$(top_srcdir)/amandad-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
 
 lib_LTLIBRARIES =      libamclient.la
 LIB_EXTENSION = la
 
-libexec_PROGRAMS =     amandad noop calcsize killpgrp rundump runtar selfcheck sendbackup sendsize versionsuffix
+libexec_PROGRAMS =     noop calcsize killpgrp rundump runtar selfcheck sendbackup sendsize versionsuffix
 
 sbin_SCRIPTS =         @CLIENT_SCRIPTS_OPT@
 
@@ -22,7 +26,7 @@ endif
 
 libamclient_la_SOURCES=        amandates.c             getfsent.c      \
                        unctime.c               client_util.c   \
-                       $(samba_sources)
+                       clientconf.c            $(samba_sources)
 
 libamclient_la_LDFLAGS = -release $(VERSION)
 
@@ -34,11 +38,9 @@ libamclient_la_LDFLAGS = -release $(VERSION)
 ###
 
 LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION)
-if WANT_SERVER
-LDADD += ../tape-src/libamtape.$(LIB_EXTENSION)
-endif
-LDADD += ../common-src/libamanda.$(LIB_EXTENSION)
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
 
 SUFFIXES =             .sh .pl
 
@@ -64,11 +66,12 @@ DISTCLEANFILES =    $(EXTRA_SCRIPTS)
 
 EXTRA_DIST =           amhpfixdevs.sh          amsinixfixdevs.sh
 
-sendbackup_SOURCES =   sendbackup.c            sendbackup.h    \
+sendbackup_SOURCES =   sendbackup.c            sendbackup.h      \
                        sendbackup-dump.c       sendbackup-gnutar.c
 
-noinst_HEADERS =       amandad.h       amandates.h     getfsent.h      \
-                       findpass.h      client_util.h
+noinst_HEADERS =       amandates.h     getfsent.h      \
+                       findpass.h      client_util.h   \
+                       clientconf.h
 
 install-exec-hook:
        @list="$(sbin_SCRIPTS)"; \
@@ -101,6 +104,20 @@ if WANT_SETUID_CLIENT
        done
 endif
 
+lint:
+       @ for p in $(libexec_PROGRAMS); do                                      \
+               f="$$p.c $(libamclient_la_SOURCES)";                            \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+
 getfsent_SOURCES = getfsent.test.c
 
 %.test.c: $(srcdir)/%.c
index aa86788f6e5081aa697adf9d9aa2a871cdd3f6d5..f30f2aca84d6443eef7c2c0cb43c7b5df666e7a3 100644 (file)
@@ -42,11 +42,9 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
-libexec_PROGRAMS = amandad$(EXEEXT) noop$(EXEEXT) calcsize$(EXEEXT) \
-       killpgrp$(EXEEXT) rundump$(EXEEXT) runtar$(EXEEXT) \
-       selfcheck$(EXEEXT) sendbackup$(EXEEXT) sendsize$(EXEEXT) \
-       versionsuffix$(EXEEXT)
-@WANT_SERVER_TRUE@am__append_1 = ../tape-src/libamtape.$(LIB_EXTENSION)
+libexec_PROGRAMS = noop$(EXEEXT) calcsize$(EXEEXT) killpgrp$(EXEEXT) \
+       rundump$(EXEEXT) runtar$(EXEEXT) selfcheck$(EXEEXT) \
+       sendbackup$(EXEEXT) sendsize$(EXEEXT) versionsuffix$(EXEEXT)
 EXTRA_PROGRAMS = $(am__EXEEXT_1)
 subdir = client-src
 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
@@ -71,82 +69,84 @@ libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
 libamclient_la_LIBADD =
 am__libamclient_la_SOURCES_DIST = amandates.c getfsent.c unctime.c \
-       client_util.c findpass.c
+       client_util.c clientconf.c findpass.c
 @WANT_SAMBA_TRUE@am__objects_1 = findpass.lo
 am_libamclient_la_OBJECTS = amandates.lo getfsent.lo unctime.lo \
-       client_util.lo $(am__objects_1)
+       client_util.lo clientconf.lo $(am__objects_1)
 libamclient_la_OBJECTS = $(am_libamclient_la_OBJECTS)
 am__EXEEXT_1 = getfsent$(EXEEXT)
 libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(libexec_PROGRAMS)
-amandad_SOURCES = amandad.c
-amandad_OBJECTS = amandad.$(OBJEXT)
-amandad_LDADD = $(LDADD)
-@WANT_SERVER_TRUE@am__DEPENDENCIES_1 =  \
-@WANT_SERVER_TRUE@     ../tape-src/libamtape.$(LIB_EXTENSION)
-amandad_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
 calcsize_SOURCES = calcsize.c
 calcsize_OBJECTS = calcsize.$(OBJEXT)
 calcsize_LDADD = $(LDADD)
 calcsize_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 am_getfsent_OBJECTS = getfsent.test.$(OBJEXT)
 getfsent_OBJECTS = $(am_getfsent_OBJECTS)
 getfsent_LDADD = $(LDADD)
 getfsent_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 killpgrp_SOURCES = killpgrp.c
 killpgrp_OBJECTS = killpgrp.$(OBJEXT)
 killpgrp_LDADD = $(LDADD)
 killpgrp_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 noop_SOURCES = noop.c
 noop_OBJECTS = noop.$(OBJEXT)
 noop_LDADD = $(LDADD)
 noop_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 rundump_SOURCES = rundump.c
 rundump_OBJECTS = rundump.$(OBJEXT)
 rundump_LDADD = $(LDADD)
 rundump_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 runtar_SOURCES = runtar.c
 runtar_OBJECTS = runtar.$(OBJEXT)
 runtar_LDADD = $(LDADD)
 runtar_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 selfcheck_SOURCES = selfcheck.c
 selfcheck_OBJECTS = selfcheck.$(OBJEXT)
 selfcheck_LDADD = $(LDADD)
 selfcheck_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 am_sendbackup_OBJECTS = sendbackup.$(OBJEXT) sendbackup-dump.$(OBJEXT) \
        sendbackup-gnutar.$(OBJEXT)
 sendbackup_OBJECTS = $(am_sendbackup_OBJECTS)
 sendbackup_LDADD = $(LDADD)
 sendbackup_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 sendsize_SOURCES = sendsize.c
 sendsize_OBJECTS = sendsize.$(OBJEXT)
 sendsize_LDADD = $(LDADD)
 sendsize_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 versionsuffix_SOURCES = versionsuffix.c
 versionsuffix_OBJECTS = versionsuffix.$(OBJEXT)
 versionsuffix_LDADD = $(LDADD)
 versionsuffix_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
 libexecSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
@@ -162,10 +162,10 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
 CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libamclient_la_SOURCES) amandad.c calcsize.c \
-       $(getfsent_SOURCES) killpgrp.c noop.c rundump.c runtar.c \
-       selfcheck.c $(sendbackup_SOURCES) sendsize.c versionsuffix.c
-DIST_SOURCES = $(am__libamclient_la_SOURCES_DIST) amandad.c calcsize.c \
+SOURCES = $(libamclient_la_SOURCES) calcsize.c $(getfsent_SOURCES) \
+       killpgrp.c noop.c rundump.c runtar.c selfcheck.c \
+       $(sendbackup_SOURCES) sendsize.c versionsuffix.c
+DIST_SOURCES = $(am__libamclient_la_SOURCES_DIST) calcsize.c \
        $(getfsent_SOURCES) killpgrp.c noop.c rundump.c runtar.c \
        selfcheck.c $(sendbackup_SOURCES) sendsize.c versionsuffix.c
 HEADERS = $(noinst_HEADERS)
@@ -179,11 +179,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -191,6 +194,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -372,8 +377,11 @@ target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
 INCLUDES = -I$(top_builddir)/common-src \
-               -I$(top_srcdir)/common-src
+               -I$(top_srcdir)/common-src \
+               -I$(top_srcdir)/amandad-src
 
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
 lib_LTLIBRARIES = libamclient.la
 LIB_EXTENSION = la
 sbin_SCRIPTS = @CLIENT_SCRIPTS_OPT@
@@ -382,7 +390,7 @@ libexec_SCRIPTS = patch-system
 @WANT_RUNTIME_PSEUDO_RELOC_TRUE@AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
 libamclient_la_SOURCES = amandates.c           getfsent.c      \
                        unctime.c               client_util.c   \
-                       $(samba_sources)
+                       clientconf.c            $(samba_sources)
 
 libamclient_la_LDFLAGS = -release $(VERSION)
 
@@ -393,8 +401,10 @@ libamclient_la_LDFLAGS = -release $(VERSION)
 # routines, and second to pick up any references in the other libraries.
 ###
 LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
-       libamclient.$(LIB_EXTENSION) $(am__append_1) \
+       libamclient.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION)
+
 SUFFIXES = .sh .pl
 
 # these are used for testing only:
@@ -403,11 +413,12 @@ CLEANFILES = *.test.c patch-system
 EXTRA_SCRIPTS = amhpfixdevs            amsinixfixdevs
 DISTCLEANFILES = $(EXTRA_SCRIPTS)
 EXTRA_DIST = amhpfixdevs.sh            amsinixfixdevs.sh
-sendbackup_SOURCES = sendbackup.c              sendbackup.h    \
+sendbackup_SOURCES = sendbackup.c              sendbackup.h      \
                        sendbackup-dump.c       sendbackup-gnutar.c
 
-noinst_HEADERS = amandad.h     amandates.h     getfsent.h      \
-                       findpass.h      client_util.h
+noinst_HEADERS = amandates.h   getfsent.h      \
+                       findpass.h      client_util.h   \
+                       clientconf.h
 
 getfsent_SOURCES = getfsent.test.c
 all: all-am
@@ -502,9 +513,6 @@ clean-libexecPROGRAMS:
          echo " rm -f $$p $$f"; \
          rm -f $$p $$f ; \
        done
-amandad$(EXEEXT): $(amandad_OBJECTS) $(amandad_DEPENDENCIES) 
-       @rm -f amandad$(EXEEXT)
-       $(LINK) $(amandad_LDFLAGS) $(amandad_OBJECTS) $(amandad_LDADD) $(LIBS)
 calcsize$(EXEEXT): $(calcsize_OBJECTS) $(calcsize_DEPENDENCIES) 
        @rm -f calcsize$(EXEEXT)
        $(LINK) $(calcsize_LDFLAGS) $(calcsize_OBJECTS) $(calcsize_LDADD) $(LIBS)
@@ -580,10 +588,10 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amandad.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amandates.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/calcsize.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clientconf.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findpass.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getfsent.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getfsent.test.Po@am__quote@
@@ -849,6 +857,20 @@ install-exec-hook:
 @WANT_SETUID_CLIENT_TRUE@              fi; \
 @WANT_SETUID_CLIENT_TRUE@      done
 
+lint:
+       @ for p in $(libexec_PROGRAMS); do                                      \
+               f="$$p.c $(libamclient_la_SOURCES)";                            \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+
 %.test.c: $(srcdir)/%.c
        echo '#define TEST' >$@
        echo '#include "$<"' >>$@
diff --git a/client-src/amandad.c b/client-src/amandad.c
deleted file mode 100644 (file)
index 9090c30..0000000
+++ /dev/null
@@ -1,1408 +0,0 @@
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1991-1999 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.
- *
- * Authors: the Amanda Development Team.  Its members are listed in a
- * file named AUTHORS, in the root directory of this distribution.
- */
-
-/*
- * $Id: amandad.c,v 1.62.2.2 2006/05/08 11:50:16 martinea Exp $
- *
- * handle client-host side of Amanda network communications, including
- * security checks, execution of the proper service, and acking the
- * master side
- */
-
-/*#define      AMANDAD_DEBUG*/
-
-#include "amanda.h"
-#include "amandad.h"
-#include "clock.h"
-#include "event.h"
-#include "amfeatures.h"
-#include "packet.h"
-#include "version.h"
-#include "queue.h"
-#include "security.h"
-#include "stream.h"
-#include "util.h"
-#include "client_util.h"
-
-#define        REP_TIMEOUT     (6*60*60)       /* secs for service to reply */
-#define        ACK_TIMEOUT     10              /* XXX should be configurable */
-#define        MAX_REP_RETRIES 5
-
-/*
- * These are the actions for entering the state machine
- */
-typedef enum { A_START, A_RECVPKT, A_RECVREP, A_PENDING, A_FINISH, A_CONTINUE,
-    A_SENDNAK, A_TIMEOUT } action_t;
-
-/*
- * This is a state in the state machine.  It is a function pointer to
- * the function that actually implements the state.
- */
-struct active_service;
-typedef action_t (*state_t) P((struct active_service *, action_t, pkt_t *));
-
-/*
- * This structure describes an active running service.
- *
- * An active service is something running that we have received
- * a request for.  This structure holds info on that service, including
- * file descriptors for data, etc, as well as the security handle
- * for communications with the amanda server.
- */
-struct active_service {
-    char *cmd;                         /* name of command we ran */
-    char *arguments;                   /* arguments we sent it */
-    security_handle_t *security_handle;        /* remote server */
-    state_t state;                     /* how far this has progressed */
-    pid_t pid;                         /* pid of subprocess */
-    int send_partial_reply;            /* send PREP packet */
-    int reqfd;                         /* pipe to write requests */
-    int repfd;                         /* pipe to read replies */
-    event_handle_t *ev_repfd;          /* read event handle for repfd */
-    event_handle_t *ev_reptimeout;     /* timeout for rep data */
-    pkt_t rep_pkt;                     /* rep packet we're sending out */
-    char repbuf[MAX_PACKET];           /* buffer to read the rep into */
-    int repbufsize;                    /* length of repbuf */
-    int repretry;                      /* times we'll retry sending the rep */
-    /*
-     * General user streams to the process, and their equivalent
-     * network streams.
-     */
-    struct datafd_handle {
-       int fd;                         /* pipe to child process */
-       event_handle_t *ev_handle;      /* it's read event handle */
-       security_stream_t *netfd;       /* stream to amanda server */
-       struct active_service *as;      /* pointer back to our enclosure */
-    } data[DATA_FD_COUNT];
-    char databuf[NETWORK_BLOCK_BYTES]; /* buffer to relay netfd data in */
-    TAILQ_ENTRY(active_service) tq;    /* queue handle */
-};
-
-/* 
- * Here are the services that we allow.
- */
-static const char *services[] = {
-    "noop",
-    "sendsize",
-    "sendbackup",
-    "selfcheck",
-};
-#define        NSERVICES       (sizeof(services) / sizeof(services[0]))
-
-/*
- * Queue of outstanding requests that we are running.
- */
-static struct {
-    TAILQ_HEAD(, active_service) tailq;
-    int qlength;
-} serviceq = {
-    TAILQ_HEAD_INITIALIZER(serviceq.tailq), 0
-};
-
-/*
- * Data for dbmalloc to check for memory leaks
- */
-#ifdef USE_DBMALLOC
-static struct {
-    struct {
-       unsigned long size, hist;
-    } start, end;
-} dbmalloc_info;
-#endif
-
-int ack_timeout     = ACK_TIMEOUT;
-
-int main P((int argc, char **argv));
-
-static int allocstream P((struct active_service *, int));
-static void exit_check P((void *));
-static void protocol_accept P((security_handle_t *, pkt_t *));
-static void state_machine P((struct active_service *, action_t, pkt_t *));
-
-static action_t s_sendack P((struct active_service *, action_t, pkt_t *));
-static action_t s_repwait P((struct active_service *, action_t, pkt_t *));
-static action_t s_processrep P((struct active_service *, action_t, pkt_t *));
-static action_t s_sendrep P((struct active_service *, action_t, pkt_t *));
-static action_t s_ackwait P((struct active_service *, action_t, pkt_t *));
-
-static void repfd_recv P((void *));
-static void timeout_repfd P((void *));
-static void protocol_recv P((void *, pkt_t *, security_status_t));
-static void process_netfd P((void *));
-static struct active_service *service_new P((security_handle_t *,
-    const char *, const char *));
-static void service_delete P((struct active_service *));
-static int writebuf P((struct active_service *, const void *, size_t));
-static int do_sendpkt P((security_handle_t *handle, pkt_t *pkt));
-
-#ifdef AMANDAD_DEBUG
-static const char *state2str P((state_t));
-static const char *action2str P((action_t));
-#endif
-
-int
-main(argc, argv)
-    int argc;
-    char **argv;
-{
-    int i, in, out;
-    const security_driver_t *secdrv;
-    int no_exit = 0;
-    char *pgm = "amandad";             /* in case argv[0] is not set */
-
-    safe_fd(-1, 0);
-    safe_cd();
-
-    if(argv == NULL) {
-       error("argv == NULL\n");
-    }
-
-    /*
-     * When called via inetd, it is not uncommon to forget to put the
-     * argv[0] value on the config line.  On some systems (e.g. Solaris)
-     * this causes argv and/or argv[0] to be NULL, so we have to be
-     * careful getting our name.
-     */
-    if (argc >= 1 && argv != NULL && argv[0] != NULL) {
-       if((pgm = strrchr(argv[0], '/')) != NULL) {
-           pgm++;
-       } else {
-           pgm = argv[0];
-       }
-    }
-
-    set_pname(pgm);
-
-    /* Don't die when child closes pipe */
-    signal(SIGPIPE, SIG_IGN);
-
-#ifdef USE_DBMALLOC
-    dbmalloc_info.start.size = malloc_inuse(&dbmalloc_info.start.hist);
-#endif
-
-    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
-
-#ifdef FORCE_USERID
-    /* we'd rather not run as root */
-    if (geteuid() == 0) {
-       if(client_uid == (uid_t) -1) {
-           error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
-       }
-       initgroups(CLIENT_LOGIN, client_gid);
-       setgid(client_gid);
-       setegid(client_gid);
-       seteuid(client_uid);
-    }
-#endif /* FORCE_USERID */
-
-    /*
-     * ad-hoc argument parsing
-     *
-     * We accept       -auth=[authentication type]
-     *                 -no-exit
-#ifdef AMANDAD_DEBUG
-     *                 -tcp=[port]
-     *                 -udp=[port]
-#endif
-     */
-    secdrv = NULL;
-    in = 0; out = 1;           /* default to stdin/stdout */
-    for (i = 1; i < argc; i++) {
-       /*
-        * accept -krb4 as an alias for -auth=krb4 (for compatibility)
-        */
-       if (strcmp(argv[i], "-krb4") == 0) {
-           argv[i] = "-auth=krb4";
-           /* FALLTHROUGH */
-       }
-
-       /*
-        * Get a driver for a security type specified after -auth=
-        */
-       if (strncmp(argv[i], "-auth=", strlen("-auth=")) == 0) {
-           argv[i] += strlen("-auth=");
-           secdrv = security_getdriver(argv[i]);
-           if (secdrv == NULL)
-               error("no driver for security type '%s'", argv[i]);
-           continue;
-       }
-
-       /*
-        * If -no-exit is specified, always run even after requests have
-        * been satisfied.
-        */
-       if (strcmp(argv[i], "-no-exit") == 0) {
-           no_exit = 1;
-           continue;
-       }
-
-#ifdef AMANDAD_DEBUG
-       /*
-        * Allow us to directly bind to a udp port for debugging.
-        * This may only apply to some security types.
-        */
-       if (strncmp(argv[i], "-udp=", strlen("-udp=")) == 0) {
-           struct sockaddr_in sin;
-
-           argv[i] += strlen("-udp=");
-           in = out = socket(AF_INET, SOCK_DGRAM, 0);
-           if (in < 0)
-               error("can't create dgram socket: %s\n", strerror(errno));
-           sin.sin_family = AF_INET;
-           sin.sin_addr.s_addr = INADDR_ANY;
-           sin.sin_port = htons(atoi(argv[i]));
-           if (bind(in, (struct sockaddr *)&sin, sizeof(sin)) < 0)
-               error("can't bind to port %d: %s\n", atoi(argv[i]),
-                   strerror(errno));
-       }
-       /*
-        * Ditto for tcp ports.
-        */
-       if (strncmp(argv[i], "-tcp=", strlen("-tcp=")) == 0) {
-           struct sockaddr_in sin;
-           int sock, n;
-
-           argv[i] += strlen("-tcp=");
-           sock = socket(AF_INET, SOCK_STREAM, 0);
-           if (sock < 0)
-               error("can't create tcp socket: %s\n", strerror(errno));
-           n = 1;
-           setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&n, sizeof(n));
-           sin.sin_family = AF_INET;
-           sin.sin_addr.s_addr = INADDR_ANY;
-           sin.sin_port = htons(atoi(argv[i]));
-           if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
-               error("can't bind to port %d: %s\n", atoi(argv[i]),
-                   strerror(errno));
-           listen(sock, 10);
-           n = sizeof(sin);
-           in = out = accept(sock, (struct sockaddr *)&sin, &n);
-       }
-#endif
-    }
-
-    /*
-     * If no security type specified, use BSD
-     */
-    if (secdrv == NULL) {
-       secdrv = security_getdriver("BSD");
-       if (secdrv == NULL)
-           error("no driver for default security type 'BSD'");
-    }
-
-    /* initialize */
-
-    dbopen();
-    {
-       /* this lameness is for error() */
-       int db_fd = dbfd();
-       if(db_fd != -1) {
-           dup2(db_fd, 2);
-       }
-    }
-
-    startclock();
-
-    dbprintf(("%s: version %s\n", get_pname(), version()));
-    for (i = 0; version_info[i] != NULL; i++) {
-       dbprintf(("%s: %s", debug_prefix(NULL), version_info[i]));
-    }
-
-    if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) {
-       dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n",
-                 debug_prefix(NULL)));
-    }
-
-    /*
-     * Schedule to call protocol_accept() when new security handles
-     * are created on stdin.
-     */
-    security_accept(secdrv, in, out, protocol_accept);
-
-    /*
-     * Schedule an event that will try to exit every 30 seconds if there
-     * are no requests outstanding.
-     */
-    (void)event_register(30, EV_TIME, exit_check, &no_exit);
-
-    /*
-     * Call event_loop() with an arg of 0, telling it to block until all
-     * events are completed.
-     */
-    event_loop(0);
-
-    /* NOTREACHED */
-    exit(1);   /* appease gcc/lint */
-}
-
-/*
- * This runs periodically and checks to see if we have any active services
- * still running.  If we don't, then we quit.
- */
-static void
-exit_check(cookie)
-    void *cookie;
-{
-    int no_exit;
-
-    assert(cookie != NULL);
-    no_exit = *(int *)cookie;
-
-    /*
-     * If things are still running, then don't exit.
-     */
-    if (serviceq.qlength > 0)
-       return;
-
-    /*
-     * If the caller asked us to never exit, then we're done
-     */
-    if (no_exit)
-       return;
-
-#ifdef USE_DBMALLOC
-    dbmalloc_info.end.size = malloc_inuse(&dbmalloc_info.end.hist);
-
-    if (dbmalloc_info.start.size != dbmalloc_info.end.size) {
-       malloc_list(dbfd(), dbmalloc_info.start.hist,
-           dbmalloc_info.end.hist);
-    }
-#endif
-
-    dbclose();
-    exit(0);
-}
-
-/*
- * Handles new incoming protocol handles.  This is a callback for
- * security_accept(), which gets called when new handles are detected.
- */
-static void
-protocol_accept(handle, pkt)
-    security_handle_t *handle;
-    pkt_t *pkt;
-{
-    pkt_t pkt_out;
-    struct active_service *as;
-    char *pktbody, *tok, *service, *arguments;
-    int i;
-
-    /*
-     * If pkt is NULL, then there was a problem with the new connection.
-     */
-    if (pkt == NULL) {
-       dbprintf(("%s: accept error: %s\n",
-           debug_prefix_time(NULL), security_geterror(handle)));
-       pkt_init(&pkt_out, P_NAK, "ERROR %s\n", security_geterror(handle));
-       do_sendpkt(handle, &pkt_out);
-       security_close(handle);
-       return;
-    }
-
-    dbprintf(("%s: accept recv %s pkt:\n<<<<<\n%s>>>>>\n",
-       debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
-
-    /*
-     * If this is not a REQ packet, just forget about it.
-     */
-    if (pkt->type != P_REQ) {
-       dbprintf(("%s: received unexpected %s packet:\n<<<<<\n%s>>>>>\n\n",
-           debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
-       security_close(handle);
-       return;
-    }
-
-    pktbody = service = arguments = NULL;
-    as = NULL;
-
-    /*
-     * Parse out the service and arguments
-     */
-
-    pktbody = stralloc(pkt->body);
-
-    tok = strtok(pktbody, " ");
-    if (tok == NULL)
-       goto badreq;
-    if (strcmp(tok, "SERVICE") != 0)
-       goto badreq;
-
-    tok = strtok(NULL, " \n");
-    if (tok == NULL)
-       goto badreq;
-    service = stralloc(tok);
-
-    /* we call everything else 'arguments' */
-    tok = strtok(NULL, "");
-    if (tok == NULL)
-       goto badreq;
-    arguments = stralloc(tok);
-
-    /* see if it's one we allow */
-    for (i = 0; i < NSERVICES; i++)
-       if (strcmp(services[i], service) == 0)
-           break;
-    if (i == NSERVICES) {
-       dbprintf(("%s: %s: invalid service\n",
-           debug_prefix_time(NULL), service));
-       pkt_init(&pkt_out, P_NAK, "ERROR %s: invalid service\n", service);
-       goto send_pkt_out;
-    }
-
-    service = newvstralloc(service,
-                      libexecdir, "/", service, versionsuffix(),
-                      NULL);
-    if (access(service, X_OK) < 0) {
-       dbprintf(("%s: can't execute %s: %s\n",
-           debug_prefix_time(NULL), service, strerror(errno)));
-           pkt_init(&pkt_out, P_NAK, "ERROR execute access to \"%s\" denied\n",
-           service);
-       goto send_pkt_out;
-    }
-
-    /* see if its already running */
-    for (as = TAILQ_FIRST(&serviceq.tailq); as != NULL;
-       as = TAILQ_NEXT(as, tq)) {
-           if (strcmp(as->cmd, service) == 0 &&
-               strcmp(as->arguments, arguments) == 0) {
-                   dbprintf(("%s: %s %s: already running, acking req\n",
-                       debug_prefix_time(NULL), service, arguments));
-                   pkt_init(&pkt_out, P_ACK, "");
-                   goto send_pkt_out;
-           }
-    }
-
-    /*
-     * create a new service instance, and send the arguments down
-     * the request pipe.
-     */
-    dbprintf(("%s: creating new service: %s\n%s\n",
-       debug_prefix_time(NULL), service, arguments));
-    as = service_new(handle, service, arguments);
-    if (writebuf(as, arguments, strlen(arguments)) < 0) {
-       const char *errmsg = strerror(errno);
-       dbprintf(("%s: error sending arguments to %s: %s\n",
-           debug_prefix_time(NULL), service, errmsg));
-       pkt_init(&pkt_out, P_NAK, "ERROR error writing arguments to %s: %s\n",
-           service, errmsg);
-       goto send_pkt_out;
-    }
-    aclose(as->reqfd);
-
-    amfree(pktbody);
-    amfree(service);
-    amfree(arguments);
-
-    /*
-     * Move to the sendack state, and start up the state
-     * machine.
-     */
-    as->state = s_sendack;
-    state_machine(as, A_START, NULL);
-    return;
-
-badreq:
-    pkt_init(&pkt_out, P_NAK, "ERROR invalid REQ\n");
-    dbprintf(("%s: received invalid %s packet:\n<<<<<\n%s>>>>>\n\n",
-       debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
-
-send_pkt_out:
-    amfree(pktbody);
-    amfree(service);
-    amfree(arguments);
-    if(as) service_delete(as);
-    do_sendpkt(handle, &pkt_out);
-    security_close(handle);
-}
-
-/*
- * Handles incoming protocol packets.  Routes responses to the proper
- * running service.
- */
-static void
-state_machine(as, action, pkt)
-    struct active_service *as;
-    action_t action;
-    pkt_t *pkt;
-{
-    action_t retaction;
-    state_t curstate;
-    pkt_t nak;
-
-#ifdef AMANDAD_DEBUG
-    dbprintf(("%s: state_machine: %X entering\n",
-       debug_prefix_time(NULL), (unsigned int)as));
-#endif
-    for (;;) {
-       curstate = as->state;
-#ifdef AMANDAD_DEBUG
-       dbprintf(("%s: state_machine: %X curstate=%s action=%s\n",
-           debug_prefix_time(NULL), (unsigned int)as,
-           state2str(curstate), action2str(action)));
-#endif
-       retaction = (*curstate)(as, action, pkt);
-#ifdef AMANDAD_DEBUG
-       dbprintf(("%s: state_machine: %X curstate=%s returned %s (nextstate=%s)\n",
-           debug_prefix_time(NULL),
-           (unsigned int)as, state2str(curstate), action2str(retaction),
-           state2str(as->state)));
-#endif
-
-       switch (retaction) {
-       /*
-        * State has queued up and is now blocking on input.
-        */
-       case A_PENDING:
-#ifdef AMANDAD_DEBUG
-           dbprintf(("%s: state_machine: %X leaving (A_PENDING)\n",
-               debug_prefix_time(NULL), (unsigned int)as));
-#endif
-           return;
-
-       /*
-        * service has switched states.  Loop.
-        */
-       case A_CONTINUE:
-           break;
-
-       /*
-        * state has determined that the packet it received was bogus.
-        * Send a nak, and return.
-        */
-       case A_SENDNAK:
-           dbprintf(("%s: received unexpected %s packet\n",
-               debug_prefix_time(NULL), pkt_type2str(pkt->type)));
-           dbprintf(("<<<<<\n%s----\n\n", pkt->body));
-           pkt_init(&nak, P_NAK, "ERROR unexpected packet type %s\n",
-               pkt_type2str(pkt->type));
-           do_sendpkt(as->security_handle, &nak);
-#ifdef AMANDAD_DEBUG
-           dbprintf(("%s: state_machine: %X leaving (A_SENDNAK)\n",
-               debug_prefix_time(NULL), (unsigned int)as));
-#endif
-           return;
-
-       /*
-        * Service is done.  Remove it and finish.
-        */
-       case A_FINISH:
-           service_delete(as);
-#ifdef AMANDAD_DEBUG
-           dbprintf(("%s: state_machine: %X leaving (A_FINISH)\n",
-               debug_prefix_time(NULL), (unsigned int)as));
-#endif
-           return;
-
-       default:
-           assert(0);
-           break;
-       }
-    }
-    /* NOTREACHED */
-}
-
-/*
- * This state just sends an ack.  After that, we move to the repwait
- * state to wait for REP data to arrive from the subprocess.
- */
-static action_t
-s_sendack(as, action, pkt)
-    struct active_service *as;
-    action_t action;
-    pkt_t *pkt;
-{
-    pkt_t ack;
-
-    pkt_init(&ack, P_ACK, "");
-    if (do_sendpkt(as->security_handle, &ack) < 0) {
-       dbprintf(("%s: error sending ACK: %s\n",
-           debug_prefix_time(NULL), security_geterror(as->security_handle)));
-       return (A_FINISH);
-    }
-
-    /*
-     * move to the repwait state
-     * Setup a listener for data on the reply fd, but also
-     * listen for packets over the wire, as the server may
-     * poll us if we take a long time.
-     * Setup a timeout that will fire if it takes too long to
-     * receive rep data.
-     */
-    as->state = s_repwait;
-    as->ev_repfd = event_register(as->repfd, EV_READFD, repfd_recv, as);
-    as->ev_reptimeout = event_register(REP_TIMEOUT, EV_TIME,
-       timeout_repfd, as);
-    security_recvpkt(as->security_handle, protocol_recv, as, -1);
-    return (A_PENDING);
-}
-
-/*
- * This is the repwait state.  We have responded to the initial REQ with
- * an ACK, and we are now waiting for the process we spawned to pass us 
- * data to send in a REP.
- */
-static action_t
-s_repwait(as, action, pkt)
-    struct active_service *as;
-    action_t action;
-    pkt_t *pkt;
-{
-    int n;
-
-    /*
-     * We normally shouldn't receive any packets while waiting
-     * for our REP data, but in some cases we do.
-     */
-    if (action == A_RECVPKT) {
-       assert(pkt != NULL);
-       /*
-        * Another req for something that's running.  Just send an ACK
-        * and go back and wait for more data.
-        */
-       if (pkt->type == P_REQ) {
-           dbprintf(("%s: received dup P_REQ packet, ACKing it\n",
-               debug_prefix_time(NULL)));
-           pkt_init(&as->rep_pkt, P_ACK, "");
-           do_sendpkt(as->security_handle, &as->rep_pkt);
-           return (A_PENDING);
-       }
-       /* something unexpected.  Nak it */
-       return (A_SENDNAK);
-    }
-
-    if (action == A_TIMEOUT) {
-       pkt_init(&as->rep_pkt, P_NAK, "ERROR timeout on reply pipe\n");
-       dbprintf(("%s: %s timed out waiting for REP data\n",
-           debug_prefix_time(NULL), as->cmd));
-       do_sendpkt(as->security_handle, &as->rep_pkt);
-       return (A_FINISH);
-    }
-
-    assert(action == A_RECVREP);
-
-    /*
-     * If the read fails, consider the process dead, and remove it.
-     * Always save room for nul termination.
-     */
-    if (as->repbufsize + 1 >= sizeof(as->repbuf)) {
-       dbprintf(("%s: more than %d bytes in reply\n",
-           debug_prefix_time(NULL), sizeof(as->repbuf)));
-       dbprintf(("%s: reply so far:\n%s\n", debug_prefix(NULL), as->repbuf));
-       pkt_init(&as->rep_pkt, P_NAK, "ERROR more than %d bytes in reply\n",
-           sizeof(as->repbuf));
-       do_sendpkt(as->security_handle, &as->rep_pkt);
-       return (A_FINISH);
-    }
-    do {
-       n = read(as->repfd, as->repbuf + as->repbufsize,
-                sizeof(as->repbuf) - as->repbufsize - 1);
-    } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
-    if (n < 0) {
-       const char *errstr = strerror(errno);
-       dbprintf(("%s: read error on reply pipe: %s\n",
-           debug_prefix_time(NULL), errstr));
-       pkt_init(&as->rep_pkt, P_NAK, "ERROR read error on reply pipe: %s\n",
-           errstr);
-       do_sendpkt(as->security_handle, &as->rep_pkt);
-       return (A_FINISH);
-    }
-    /*
-     * If we got some data, go back and wait for more, or EOF.  Nul terminate
-     * the buffer first.
-     */
-    as->repbuf[n + as->repbufsize] = '\0';
-    if (n > 0) {
-       as->repbufsize += n;
-       if(as->send_partial_reply) {
-           pkt_init(&as->rep_pkt, P_PREP, "%s", as->repbuf);
-           do_sendpkt(as->security_handle, &as->rep_pkt);
-           pkt_init(&as->rep_pkt, P_REP, "");
-       }
-       return (A_PENDING);
-    }
-
-    /*
-     * If we got 0, then we hit EOF.  Process the data and release
-     * the timeout.
-     */
-    assert(n == 0);
-
-    assert(as->ev_repfd != NULL);
-    event_release(as->ev_repfd);
-    as->ev_repfd = NULL;
-
-    assert(as->ev_reptimeout != NULL);
-    event_release(as->ev_reptimeout);
-    as->ev_reptimeout = NULL;
-
-    as->state = s_processrep;
-    aclose(as->repfd);
-    return (A_CONTINUE);
-}
-
-/*
- * After we have read in all of the rep data, we process it and send
- * it out as a REP packet.
- */
-static action_t
-s_processrep(as, action, pkt)
-    struct active_service *as;
-    action_t action;
-    pkt_t *pkt;
-{
-    char *tok, *repbuf;
-
-    /*
-     * Copy the rep lines into the outgoing packet.
-     *
-     * If this line is a CONNECT, translate it
-     * Format is "CONNECT <tag> <handle> <tag> <handle> etc...
-     * Example:
-     *
-     *  CONNECT DATA 4 MESG 5 INDEX 6
-     *
-     * The tags are arbitrary.  The handles are in the DATA_FD pool.
-     * We need to map these to security streams and pass them back
-     * to the amanda server.  If the handle is -1, then we don't map.
-     */
-    repbuf = stralloc(as->repbuf);
-    pkt_init(&as->rep_pkt, P_REP, "");
-    tok = strtok(repbuf, " ");
-    if (tok == NULL)
-       goto error;
-    if (strcmp(tok, "CONNECT") == 0) {
-       char *line, *nextbuf;
-
-       /* Save the entire line */
-       line = strtok(NULL, "\n");
-       /* Save the buf following the line */
-       nextbuf = strtok(NULL, "");
-
-       if (line == NULL || nextbuf == NULL)
-           goto error;
-
-       pkt_cat(&as->rep_pkt, "CONNECT");
-
-       /* loop over the id/handle pairs */
-       for (;;) {
-           /* id */
-           tok = strtok(line, " ");
-           line = NULL;        /* keep working from line */
-           if (tok == NULL)
-               break;
-           pkt_cat(&as->rep_pkt, " %s", tok);
-
-           /* handle */
-           tok = strtok(NULL, " \n");
-           if (tok == NULL)
-               goto error;
-           /* convert the handle into something the server can process */
-           pkt_cat(&as->rep_pkt, " %d", allocstream(as, atoi(tok)));
-       }
-       pkt_cat(&as->rep_pkt, "\n%s", nextbuf);
-    } else {
-error:
-       pkt_cat(&as->rep_pkt, "%s", as->repbuf);
-    }
-
-    /*
-     * We've setup our REP packet in as->rep_pkt.  Now move to the transmission
-     * state.
-     */
-    as->state = s_sendrep;
-    as->repretry = MAX_REP_RETRIES;
-    amfree(repbuf);
-    return (A_CONTINUE);
-}
-
-/*
- * This is the state where we send the REP we just collected from our child.
- */
-static action_t
-s_sendrep(as, action, pkt)
-    struct active_service *as;
-    action_t action;
-    pkt_t *pkt;
-{
-
-    /*
-     * Transmit it and move to the ack state.
-     */
-    do_sendpkt(as->security_handle, &as->rep_pkt);
-    security_recvpkt(as->security_handle, protocol_recv, as, ACK_TIMEOUT);
-    as->state = s_ackwait;
-    return (A_PENDING);
-}
-
-/*
- * This is the state in which we wait for the server to ACK the REP
- * we just sent it.
- */
-static action_t
-s_ackwait(as, action, pkt)
-    struct active_service *as;
-    action_t action;
-    pkt_t *pkt;
-{
-    struct datafd_handle *dh;
-    int npipes;
-
-    /*
-     * If we got a timeout, try again, but eventually give up.
-     */
-    if (action == A_TIMEOUT) {
-       if (--as->repretry > 0) {
-           as->state = s_sendrep;
-           return (A_CONTINUE);
-       }
-       dbprintf(("%s: timeout waiting for ACK for our REP\n",
-           debug_prefix_time(NULL)));
-       return (A_FINISH);
-    }
-#ifdef AMANDAD_DEBUG
-    dbprintf(("%s: received ACK, now opening streams\n",
-       debug_prefix_time(NULL)));
-#endif
-
-    assert(action == A_RECVPKT);
-    if (pkt->type != P_ACK)
-       return (A_SENDNAK);
-
-    /*
-     * Got the ack, now open the pipes
-     */
-    for (dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
-       if (dh->netfd == NULL)
-           continue;
-       if (security_stream_accept(dh->netfd) < 0) {
-           dbprintf(("%s: stream %d accept failed: %s\n",
-               debug_prefix_time(NULL),
-               dh - &as->data[0], security_geterror(as->security_handle)));
-           security_stream_close(dh->netfd);
-           dh->netfd = NULL;
-       }
-       /* setup an event for reads from it */
-       dh->ev_handle = event_register(dh->fd, EV_READFD, process_netfd, dh);
-    }
-
-    /*
-     * Pipes are open, so auth them.  Count them at the same time.
-     */
-    for (npipes = 0, dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
-       if (dh->netfd == NULL)
-           continue;
-       if (security_stream_auth(dh->netfd) < 0) {
-           security_stream_close(dh->netfd);
-           dh->netfd = NULL;
-           event_release(dh->ev_handle);
-           dh->ev_handle = NULL;
-       } else {
-           npipes++;
-       }
-    }
-
-    /*
-     * If no pipes are open, then we're done.  Otherwise, just start running.
-     * The event handlers on all of the pipes will take it from here.
-     */
-#ifdef AMANDAD_DEBUG
-    dbprintf(("%s: at end of s_ackwait, npipes is %d\n",
-       debug_prefix_time(NULL), npipes));
-#endif
-    if (npipes == 0)
-       return (A_FINISH);
-    else {
-       security_close(as->security_handle);
-       as->security_handle = NULL;
-       return (A_PENDING);
-    }
-}
-
-/*
- * Called when a repfd has received data
- */
-static void
-repfd_recv(cookie)
-    void *cookie;
-{
-    struct active_service *as = cookie;
-
-    assert(as != NULL);
-    assert(as->ev_repfd != NULL);
-
-    state_machine(as, A_RECVREP, NULL);
-}
-
-/*
- * Called when a repfd has timed out
- */
-static void
-timeout_repfd(cookie)
-    void *cookie;
-{
-    struct active_service *as = cookie;
-
-    assert(as != NULL);
-    assert(as->ev_reptimeout != NULL);
-
-    state_machine(as, A_TIMEOUT, NULL);
-}
-
-/*
- * Called when a handle has received data
- */
-static void
-protocol_recv(cookie, pkt, status)
-    void *cookie;
-    pkt_t *pkt;
-    security_status_t status;
-{
-    struct active_service *as = cookie;
-
-    assert(as != NULL);
-
-    switch (status) {
-    case S_OK:
-       dbprintf(("%s: received %s pkt:\n<<<<<\n%s>>>>>\n",
-           debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
-       state_machine(as, A_RECVPKT, pkt);
-       break;
-    case S_TIMEOUT:
-       dbprintf(("%s: timeout\n", debug_prefix_time(NULL)));
-       state_machine(as, A_TIMEOUT, NULL);
-       break;
-    case S_ERROR:
-       dbprintf(("%s: receive error: %s\n",
-           debug_prefix_time(NULL), security_geterror(as->security_handle)));
-       break;
-    }
-}
-
-/*
- * This is a generic relay function that just reads data from one of
- * the process's pipes and passes it up the equivalent security_stream_t
- */
-static void
-process_netfd(cookie)
-    void *cookie;
-{
-    pkt_t nak;
-    struct datafd_handle *dh = cookie;
-    struct active_service *as = dh->as;
-    int n;
-
-    do {
-       n = read(dh->fd, as->databuf, sizeof(as->databuf));
-    } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
-
-    /*
-     * Process has died.
-     */
-    if (n < 0) {
-       pkt_init(&nak, P_NAK, "ERROR data descriptor %d broken: %s\n",
-           dh->fd, strerror(errno));
-       goto sendnak;
-    }
-    /*
-     * Process has closed the pipe.  Just remove this event handler.
-     * If all pipes are closed, shut down this service.
-     */
-    if (n == 0) {
-       event_release(dh->ev_handle);
-       dh->ev_handle = NULL;
-       security_stream_close(dh->netfd);
-       dh->netfd = NULL;
-       for (dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
-           if (dh->netfd != NULL)
-               return;
-       }
-       service_delete(as);
-       return;
-    }
-    if (security_stream_write(dh->netfd, as->databuf, n) < 0) {
-       /* stream has croaked */
-       pkt_init(&nak, P_NAK, "ERROR write error on stream %d: %s\n",
-           security_stream_id(dh->netfd),
-           security_stream_geterror(dh->netfd));
-       goto sendnak;
-    }
-    return;
-
-sendnak:
-    do_sendpkt(as->security_handle, &nak);
-    service_delete(as);
-}
-
-
-/*
- * Convert a local stream handle (DATA_FD...) into something that
- * can be sent to the amanda server.
- *
- * Returns a number that should be sent to the server in the REP packet.
- */
-static int
-allocstream(as, handle)
-    struct active_service *as;
-    int handle;
-{
-    struct datafd_handle *dh;
-
-    /* if the handle is -1, then we don't bother */
-    if (handle < 0)
-       return (-1);
-
-    /* make sure the handle's kosher */
-    if (handle < DATA_FD_OFFSET || handle >= DATA_FD_OFFSET + DATA_FD_COUNT)
-       return (-1);
-
-    /* get a pointer into our handle array */
-    dh = &as->data[handle - DATA_FD_OFFSET];
-
-    /* make sure we're not already using the net handle */
-    if (dh->netfd != NULL)
-       return (-1);
-
-    /* allocate a stream from the security layer and return */
-    dh->netfd = security_stream_server(as->security_handle);
-    if (dh->netfd == NULL) {
-       dbprintf(("%s: couldn't open stream to server: %s\n",
-           debug_prefix_time(NULL), security_geterror(as->security_handle)));
-       return (-1);
-    }
-
-    /*
-     * convert the stream into a numeric id that can be sent to the
-     * remote end.
-     */
-    return (security_stream_id(dh->netfd));
-}
-
-/*
- * Create a new service instance
- */
-static struct active_service *
-service_new(security_handle, cmd, arguments)
-    security_handle_t *security_handle;
-    const char *cmd, *arguments;
-{
-    int data[DATA_FD_COUNT + 2][2], i;
-    struct active_service *as;
-    pid_t pid;
-    int newfd;
-
-    assert(security_handle != NULL);
-    assert(cmd != NULL);
-    assert(arguments != NULL);
-
-    /* a plethora of pipes */
-    for (i = 0; i < DATA_FD_COUNT + 2; i++)
-       if (pipe(data[i]) < 0)
-           error("pipe: %s", strerror(errno));
-
-    switch(pid = fork()) {
-    case -1:
-       error("could not fork service %s: %s", cmd, strerror(errno));
-    default:
-       /*
-        * The parent.  Close the far ends of our pipes and return.
-        */
-       as = alloc(sizeof(*as));
-       as->cmd = stralloc(cmd);
-       as->arguments = stralloc(arguments);
-       as->security_handle = security_handle;
-       as->state = NULL;
-       as->pid = pid;
-       as->send_partial_reply = 0;
-       if(strcmp(cmd+(strlen(cmd)-8), "sendsize") == 0) {
-           g_option_t *g_options;
-           char *option_str, *p;
-
-           option_str = stralloc(as->arguments+8);
-           p = strchr(option_str,'\n');
-           if(p) *p = '\0';
-
-           g_options = parse_g_options(option_str, 1);
-           if(am_has_feature(g_options->features, fe_partial_estimate)) {
-               as->send_partial_reply = 1;
-           }
-           amfree(g_options);
-           amfree(option_str);
-       }
-
-       /* write to the request pipe */
-       aclose(data[0][0]);
-       as->reqfd = data[0][1];
-
-       /*
-        * read from the reply pipe
-        */
-       as->repfd = data[1][0];
-       aclose(data[1][1]);
-       as->ev_repfd = NULL;
-       as->repbufsize = 0;
-       as->repretry = 0;
-
-       /*
-        * read from the rest of the general-use pipes
-        * (netfds are opened as the client requests them)
-        */
-       for (i = 0; i < DATA_FD_COUNT; i++) {
-           aclose(data[i + 2][1]);
-           as->data[i].fd = data[i + 2][0];
-           as->data[i].ev_handle = NULL;
-           as->data[i].netfd = NULL;
-           as->data[i].as = as;
-       }
-
-       /* add it to the service queue */
-       /* increment the active service count */
-       TAILQ_INSERT_TAIL(&serviceq.tailq, as, tq);
-       serviceq.qlength++;
-
-       return (as);
-    case 0:
-       /*
-        * The child.  Put our pipes in their advertised locations
-        * and start up.
-        */
-#ifdef FORCE_USERID
-       seteuid((uid_t)0);
-       setuid(client_uid);
-#endif
-
-       /*
-        * The data stream is stdin in the new process
-        */
-        if (dup2(data[0][0], 0) < 0) {
-           error("dup %d to %d failed: %s\n", data[0][0], 0,
-               strerror(errno));
-       }
-       aclose(data[0][0]);
-       aclose(data[0][1]);
-
-       /*
-        * The reply stream is stdout
-        */
-        if (dup2(data[1][1], 1) < 0) {
-           error("dup %d to %d failed: %s\n", data[1][1], 1,
-               strerror(errno));
-       }
-        aclose(data[1][0]);
-        aclose(data[1][1]);
-
-       /*
-        * The rest start at the offset defined in amandad.h, and continue
-        * through the internal defined.
-        */
-       for (i = 0; i < DATA_FD_COUNT; i++)
-           aclose(data[i + 2][0]);
-
-       /*
-        *  Make sure they are not open in the range DATA_FD_OFFSET to 
-        *      DATA_FD_OFFSET + DATA_FD_COUNT - 1
-        */
-       for (i = 0; i < DATA_FD_COUNT; i++) {
-           while(data[i + 2][1] >= DATA_FD_OFFSET &&
-                 data[i + 2][1] <= DATA_FD_OFFSET + DATA_FD_COUNT - 1) {
-               newfd = dup(data[i + 2][1]);
-               if(newfd == -1)
-                   error("Can't dup out off DATA_FD range");
-               data[i + 2][1] = newfd;
-           }
-       }
-       for (i = 0; i < DATA_FD_COUNT; i++)
-           close(DATA_FD_OFFSET + i);
-
-       for (i = 0; i < DATA_FD_COUNT; i++) {
-           if (dup2(data[i + 2][1], i + DATA_FD_OFFSET) < 0) {
-               error("dup %d to %d failed: %s\n", data[i + 2][1],
-                   i + DATA_FD_OFFSET, strerror(errno));
-           }
-           aclose(data[i + 2][1]);
-       }
-
-       execle(cmd, cmd, NULL, safe_env());
-       error("could not exec service %s: %s", cmd, strerror(errno));
-    }
-    /* NOTREACHED */
-    return NULL;
-}
-
-/*
- * Unallocate a service instance
- */
-static void
-service_delete(as)
-    struct active_service *as;
-{
-    int i;
-    struct datafd_handle *dh;
-
-#ifdef AMANDAD_DEBUG
-       dbprintf(("%s: closing service: %s\n",
-           debug_prefix_time(NULL), (as->cmd)?as->cmd:"??UNKONWN??"));
-#endif
-
-    assert(as != NULL);
-
-    assert(as->cmd != NULL);
-    amfree(as->cmd);
-
-    assert(as->arguments != NULL);
-    amfree(as->arguments);
-
-    if (as->reqfd != -1)
-       aclose(as->reqfd);
-    if (as->repfd != -1)
-       aclose(as->repfd);
-
-    if (as->ev_repfd != NULL)
-       event_release(as->ev_repfd);
-    if (as->ev_reptimeout != NULL)
-       event_release(as->ev_reptimeout);
-
-    for (i = 0; i < DATA_FD_COUNT; i++) {
-       dh = &as->data[i];
-
-       aclose(dh->fd);
-
-       if (dh->netfd != NULL)
-           security_stream_close(dh->netfd);
-
-       if (dh->ev_handle != NULL)
-           event_release(dh->ev_handle);
-    }
-
-    if (as->security_handle != NULL)
-       security_close(as->security_handle);
-
-    assert(as->pid > 0);
-    kill(as->pid, SIGTERM);
-    waitpid(as->pid, NULL, WNOHANG);
-
-    TAILQ_REMOVE(&serviceq.tailq, as, tq);
-    assert(serviceq.qlength > 0);
-    serviceq.qlength--;
-
-    amfree(as);
-}
-
-/*
- * Like 'fullwrite', but does the work in a child process so pipelines
- * do not hang.
- */
-static int
-writebuf(as, bufp, size)
-    struct active_service *as;
-    const void *bufp;
-    size_t size;
-{
-    int pid;
-
-    switch (pid=fork()) {
-    case -1:
-       return -1;
-
-    default:
-       waitpid(pid, NULL, WNOHANG);
-       return 0;                       /* this is the parent */
-
-    case 0:
-       break;                          /* this is the child */
-    }
-    aclose (as->repfd);                        /* make sure we are not a reader */
-    exit (fullwrite(as->reqfd, bufp, size) != size);
-}
-
-static int
-do_sendpkt(handle, pkt)
-    security_handle_t *handle;
-    pkt_t *pkt;
-{
-    dbprintf(("%s: sending %s pkt:\n<<<<<\n%s>>>>>\n",
-       debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
-    return security_sendpkt(handle, pkt);
-}
-
-#ifdef AMANDAD_DEBUG
-/*
- * Convert a state into a string
- */
-static const char *
-state2str(state)
-    state_t state;
-{
-    static const struct {
-       state_t state;
-       const char str[13];
-    } states[] = {
-#define        X(state)        { state, stringize(state) }
-       X(s_sendack),
-       X(s_repwait),
-       X(s_processrep),
-       X(s_sendrep),
-       X(s_ackwait),
-#undef X
-    };
-    int i;
-
-    for (i = 0; i < sizeof(states) / sizeof(states[0]); i++)
-       if (state == states[i].state)
-           return (states[i].str);
-    return ("INVALID STATE");
-}
-
-/*
- * Convert an action into a string
- */
-static const char *
-action2str(action)
-    action_t action;
-{
-    static const struct {
-       action_t action;
-       const char str[12];
-    } actions[] = {
-#define        X(action)       { action, stringize(action) }
-       X(A_START),
-       X(A_RECVPKT),
-       X(A_RECVREP),
-       X(A_PENDING),
-       X(A_FINISH),
-       X(A_CONTINUE),
-       X(A_SENDNAK),
-       X(A_TIMEOUT),
-#undef X
-    };
-    int i;
-
-    for (i = 0; i < sizeof(actions) / sizeof(actions[0]); i++)
-       if (action == actions[i].action)
-           return (actions[i].str);
-    return ("UNKNOWN ACTION");
-}
-#endif /* AMANDAD_DEBUG */
diff --git a/client-src/amandad.h b/client-src/amandad.h
deleted file mode 100644 (file)
index 054f6bd..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1999 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.
- *
- * Authors: the Amanda Development Team.  Its members are listed in a
- * file named AUTHORS, in the root directory of this distribution.
- */
-/*
- * $Id: amandad.h,v 1.2 1999/04/16 05:12:39 kashmir Exp $
- */
-#ifndef        AMANDAD_H
-#define        AMANDAD_H
-
-/*
- * General-use pipes inherited by sendbackup that are connected to the
- * data, mesg, index, etc connections on the server.  amandad sets these
- * up before calling sendbackup, and will relay data sent on them
- * back to the server.
- */
-#define        DATA_FD_COUNT   3               /* number of general-use pipes */
-#define        DATA_FD_OFFSET  50              /* fd at which they start */
-
-#endif /* AMANDAD_H */
index 3d055bbc162088294dc72ba4df9426b052734779..23e1c7df05a8c958b28b3ef6aadbfb475789f5b0 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amandates.c,v 1.16 2003/10/22 17:43:20 martinea Exp $
+ * $Id: amandates.c,v 1.21 2006/07/25 18:35:21 martinea Exp $
  *
  * manage amandates file, that mimics /var/lib/dumpdates, but stores
  * GNUTAR dates
 
 #include "amanda.h"
 #include "getfsent.h"
+#include "util.h"
 
 #include "amandates.h"
 
 static amandates_t *amandates_list = NULL;
 static FILE *amdf = NULL;
 static int updated, readonly;
-static void import_dumpdates P((amandates_t *));
-static void enter_record P((char *, int , time_t));
-static amandates_t *lookup P((char *name, int import));
-
-int start_amandates(open_readwrite)
-int open_readwrite;
+static char *g_amandates_file = NULL;
+static void import_dumpdates(amandates_t *);
+static void enter_record(char *, int , time_t);
+static amandates_t *lookup(char *name, int import);
+
+int
+start_amandates(
+    char *amandates_file,
+    int          open_readwrite)
 {
-    int rc, level;
-    long ldate;
-    char *line = NULL, *name = NULL;
+    int rc, level = 0;
+    long ldate = 0L;
+    char *line;
+    char *name;
     char *s;
     int ch;
+    char *qname;
+
+    if (amandates_file == NULL)
+       return 0;
 
     /* clean up from previous invocation */
 
@@ -57,6 +66,7 @@ int open_readwrite;
        finish_amandates();
     if(amandates_list != NULL)
        free_amandates();
+    amfree(g_amandates_file);
 
     /* initialize state */
 
@@ -64,37 +74,41 @@ int open_readwrite;
     readonly = !open_readwrite;
     amdf = NULL;
     amandates_list = NULL;
-
+    g_amandates_file = stralloc(amandates_file);
     /* open the file */
 
-    if (access(AMANDATES_FILE,F_OK))
+    if (access(amandates_file,F_OK))
        /* not yet existing */
-       if ( (rc = open(AMANDATES_FILE,(O_CREAT|O_RDWR),0644)) != -1 )
+       if ( (rc = open(amandates_file,(O_CREAT|O_RDWR),0644)) != -1 )
            /* open/create successfull */
            aclose(rc);
 
     if(open_readwrite)
-       amdf = fopen(AMANDATES_FILE, "r+");
+       amdf = fopen(amandates_file, "r+");
     else
-       amdf = fopen(AMANDATES_FILE, "r");
+       amdf = fopen(amandates_file, "r");
 
     /* create it if we need to */
 
     if(amdf == NULL && (errno == EINTR || errno == ENOENT) && open_readwrite)
-       amdf = fopen(AMANDATES_FILE, "w");
+       amdf = fopen(amandates_file, "w");
 
     if(amdf == NULL)
        return 0;
 
     if(open_readwrite)
-       rc = amflock(fileno(amdf), "amandates");
+       rc = amflock(fileno(amdf), amandates_file);
     else
-       rc = amroflock(fileno(amdf), "amandates");
+       rc = amroflock(fileno(amdf), amandates_file);
 
-    if(rc == -1)
-       error("could not lock %s: %s", AMANDATES_FILE, strerror(errno));
+    if(rc == -1) {
+       error("could not lock %s: %s", amandates_file, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     for(; (line = agets(amdf)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        s = line;
        ch = *s++;
 
@@ -102,59 +116,76 @@ int open_readwrite;
        if(ch == '\0') {
            continue;                           /* no name field */
        }
-       name = s - 1;
-       skip_non_whitespace(s, ch);
+       qname = s - 1;
+       skip_quoted_string(s, ch);
        s[-1] = '\0';                           /* terminate the name */
+       name = unquote_string(qname);
 
        skip_whitespace(s, ch);
        if(ch == '\0' || sscanf(s - 1, "%d %ld", &level, &ldate) != 2) {
+           amfree(name);
            continue;                           /* no more fields */
        }
 
        if(level < 0 || level >= DUMP_LEVELS) {
+           amfree(name);
            continue;
        }
 
        enter_record(name, level, (time_t) ldate);
+       amfree(name);
     }
 
-    if(ferror(amdf))
-       error("reading %s: %s", AMANDATES_FILE, strerror(errno));
+    if(ferror(amdf)) {
+       error("reading %s: %s", amandates_file, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     updated = 0;       /* reset updated flag */
     return 1;
 }
 
-void finish_amandates()
+void
+finish_amandates(void)
 {
     amandates_t *amdp;
     int level;
+    char *qname;
 
     if(amdf == NULL)
        return;
 
     if(updated) {
-       if(readonly)
+       if(readonly) {
            error("updated amandates after opening readonly");
+           /*NOTREACHED*/
+       }
 
        rewind(amdf);
        for(amdp = amandates_list; amdp != NULL; amdp = amdp->next) {
            for(level = 0; level < DUMP_LEVELS; level++) {
                if(amdp->dates[level] == EPOCH) continue;
+               qname = quote_string(amdp->name);
                fprintf(amdf, "%s %d %ld\n",
-                       amdp->name, level, (long) amdp->dates[level]);
+                       qname, level, (long) amdp->dates[level]);
+               amfree(qname);
            }
        }
     }
 
-    if(amfunlock(fileno(amdf), "amandates") == -1)
-       error("could not unlock %s: %s", AMANDATES_FILE, strerror(errno));
-    if (fclose(amdf) == EOF)
-       error("error [closing %s: %s]", AMANDATES_FILE, strerror(errno));
+    if(amfunlock(fileno(amdf), g_amandates_file) == -1) {
+       error("could not unlock %s: %s", g_amandates_file, strerror(errno));
+       /*NOTREACHED*/
+    }
+    if (fclose(amdf) == EOF) {
+       error("error [closing %s: %s]", g_amandates_file, strerror(errno));
+       /*NOTREACHED*/
+    }
     amdf = NULL;
 }
 
-void free_amandates()
+void
+free_amandates(void)
 {
     amandates_t *amdp, *nextp;
 
@@ -166,54 +197,70 @@ void free_amandates()
     amandates_list = NULL;
 }
 
-static amandates_t *lookup(name, import)
-char *name;
-int import;
+static amandates_t *
+lookup(
+    char *     name,
+    int                import)
 {
-    amandates_t *prevp, *amdp, *newp;
+    amandates_t *prevp, *amdp;
     int rc, level;
 
+    (void)import;      /* Quiet unused parameter warning */
     rc = 0;
 
-    for(prevp=NULL,amdp=amandates_list;amdp!=NULL;prevp=amdp,amdp=amdp->next)
-       if((rc = strcmp(name, amdp->name)) <= 0)
+    prevp = NULL;
+    amdp = amandates_list;
+    while (amdp != NULL) {
+       if ((rc = strcmp(name, amdp->name)) <= 0)
            break;
-
-    if(amdp && rc == 0)
-       return amdp;
-
-    newp = alloc(sizeof(amandates_t));
-    newp->name = stralloc(name);
-    for(level = 0; level < DUMP_LEVELS; level++)
-       newp->dates[level] = EPOCH;
-    newp->next = amdp;
-    if(prevp) prevp->next = newp;
-    else amandates_list = newp;
-
-    import_dumpdates(newp);
-
-    return newp;
+       prevp = amdp;
+       amdp = amdp->next;
+    }
+    if (!(amdp && (rc == 0))) {
+       amandates_t *newp = alloc(SIZEOF(amandates_t));
+       newp->name = stralloc(name);
+       for (level = 0; level < DUMP_LEVELS; level++)
+           newp->dates[level] = EPOCH;
+       newp->next = amdp;
+       if (prevp != NULL) {
+#ifndef __lint /* Remove complaint about NULL pointer assignment */
+           prevp->next = newp;
+#else
+           (void)prevp;
+#endif
+       } else {
+           amandates_list = newp;
+       }
+       import_dumpdates(newp);
+       return newp;
+    }
+    return amdp;
 }
 
-amandates_t *amandates_lookup(name)
-char *name;
+amandates_t *
+amandates_lookup(
+    char *     name)
 {
     return lookup(name, 1);
 }
 
-static void enter_record(name, level, dumpdate)
-char *name;
-int level;
-time_t dumpdate;
+static void
+enter_record(
+    char *     name,
+    int                level,
+    time_t     dumpdate)
 {
     amandates_t *amdp;
+    char *qname;
 
     amdp = lookup(name, 0);
 
     if(level < 0 || level >= DUMP_LEVELS || dumpdate < amdp->dates[level]) {
+       qname = quote_string(name);
        /* this is not allowed, but we can ignore it */
         dbprintf(("amandates botch: %s lev %d: new dumpdate %ld old %ld\n",
-                 name, level, (long) dumpdate, (long) amdp->dates[level]));
+                 qname, level, (long) dumpdate, (long) amdp->dates[level]));
+       amfree(qname);
        return;
     }
 
@@ -221,12 +268,14 @@ time_t dumpdate;
 }
 
 
-void amandates_updateone(name, level, dumpdate)
-char *name;
-int level;
-time_t dumpdate;
+void
+amandates_updateone(
+    char *     name,
+    int                level,
+    time_t     dumpdate)
 {
     amandates_t *amdp;
+    char *qname;
 
     assert(!readonly);
 
@@ -234,8 +283,10 @@ time_t dumpdate;
 
     if(level < 0 || level >= DUMP_LEVELS || dumpdate < amdp->dates[level]) {
        /* this is not allowed, but we can ignore it */
+       qname = quote_string(name);
        dbprintf(("amandates updateone: %s lev %d: new dumpdate %ld old %ld",
                  name, level, (long) dumpdate, (long) amdp->dates[level]));
+       amfree(qname);
        return;
     }
 
@@ -246,11 +297,14 @@ time_t dumpdate;
 
 /* -------------------------- */
 
-static void import_dumpdates(amdp)
-amandates_t *amdp;
+static void
+import_dumpdates(
+    amandates_t *      amdp)
 {
-    char *devname = NULL, *line = NULL, *fname = NULL;
-    int level;
+    char *devname;
+    char *line;
+    char *fname;
+    int level = 0;
     time_t dumpdate;
     FILE *dumpdf;
     char *s;
@@ -264,6 +318,8 @@ amandates_t *amdp;
     }
 
     for(; (line = agets(dumpdf)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        s = line;
        ch = *s++;
 
index b0b22c2347ef0918f493773bc04082d079ea61f6..8471ca9dfc946c096b98d5ed04e06d25f08abb31 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amandates.h,v 1.3 1998/07/04 00:18:10 oliva Exp $
+ * $Id: amandates.h,v 1.5 2006/07/25 18:35:21 martinea Exp $
  *
  * interface for amandates file
  */
@@ -46,10 +46,10 @@ typedef struct amandates_s {
     time_t dates[DUMP_LEVELS];         /* dump dates */
 } amandates_t;
 
-int  start_amandates P((int open_readwrite));
-void finish_amandates P((void));
-void free_amandates P((void));
-amandates_t *amandates_lookup P((char *name));
-void amandates_updateone P((char *name, int level, time_t dumpdate));
+int  start_amandates (char *amandates_file, int open_readwrite);
+void finish_amandates (void);
+void free_amandates (void);
+amandates_t *amandates_lookup (char *name);
+void amandates_updateone (char *name, int level, time_t dumpdate);
 
 #endif /* ! AMANDATES_H */
index 0f174e8a0e6214b1c7050436e941bdf91d2de576..662dfd0807c6415b3f6fe18bc31804c72978c4a1 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: calcsize.c,v 1.37 2006/03/29 15:45:08 martinea Exp $
+ * $Id: calcsize.c,v 1.44 2006/07/25 18:27:56 martinea Exp $
  *
  * traverse directory tree to get backup size estimates
+ *
+ * argv[0] is the calcsize program name
+ * argv[1] is the config name or NOCONFIG
  */
 #include "amanda.h"
 #include "statfs.h"
+#include "version.h"
 #include "sl.h"
+#include "util.h"
 
 #define ROUND(n,x)     ((x) + (n) - 1 - (((x) + (n) - 1) % (n)))
 
 /*
-static unsigned long round_function(n, x)
-unsigned long n, x;
+static off_t
+round_function(n, x)
+    off_t      n,
+    off_t      x)
 {
   unsigned long remainder = x % n;
   if (remainder)
-    x += n-remainder;
+    x += n - remainder;
   return x;
 }
 */
 
-#define ST_BLOCKS(s)   ((((s).st_blocks * 512) <= (s).st_size) ? (s).st_blocks+1 : ((s).st_size / 512 + (((s).st_size % 512) ? 1 : 0)))
+#define ST_BLOCKS(s)                                                          \
+           (((((off_t)(s).st_blocks * (off_t)512) <= (s).st_size)) ?          \
+             ((off_t)(s).st_blocks + (off_t)1) :                              \
+             ((s).st_size / (off_t)512 +                                      \
+               (off_t)((((s).st_size % (off_t)512) != (off_t)0) ?             \
+               (off_t)1 : (off_t)0)))
 
 #define        FILETYPES       (S_IFREG|S_IFLNK|S_IFDIR)
 
@@ -62,50 +74,57 @@ struct {
     int max_inode;
     int total_dirs;
     int total_files;
-    long total_size;
-    long total_size_name;
+    off_t total_size;
+    off_t total_size_name;
 } dumpstats[MAXDUMPS];
 
 time_t dumpdate[MAXDUMPS];
 int  dumplevel[MAXDUMPS];
 int ndumps;
 
-void (*add_file_name) P((int, char *));
-void (*add_file) P((int, struct stat *));
-long (*final_size) P((int, char *));
+void (*add_file_name)(int, char *);
+void (*add_file)(int, struct stat *);
+off_t (*final_size)(int, char *);
+
 
+int main(int, char **);
+void traverse_dirs(char *, char *);
 
-int main P((int, char **));
-void traverse_dirs P((char *, char *));
 
+void add_file_name_dump(int, char *);
+void add_file_dump(int, struct stat *);
+off_t final_size_dump(int, char *);
 
-void add_file_name_dump P((int, char *));
-void add_file_dump P((int, struct stat *));
-long final_size_dump P((int, char *));
+void add_file_name_star(int, char *);
+void add_file_star(int, struct stat *);
+off_t final_size_star(int, char *);
 
-void add_file_name_gnutar P((int, char *));
-void add_file_gnutar P((int, struct stat *));
-long final_size_gnutar P((int, char *));
+void add_file_name_gnutar(int, char *);
+void add_file_gnutar(int, struct stat *);
+off_t final_size_gnutar(int, char *);
 
-void add_file_name_unknown P((int, char *));
-void add_file_unknown P((int, struct stat *));
-long final_size_unknown P((int, char *));
+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 P((char *filename));
-int calc_check_exclude P((char *filename));
+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;
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
 #ifdef TEST
 /* standalone test to ckeck wether the calculated file size is ok */
     struct stat finfo;
     int i;
-    unsigned long dump_total=0, gtar_total=0;
+    off_t dump_total = (off_t)0;
+    off_t gtar_total = (off_t)0;
     char *d;
     int l, w;
 
@@ -113,6 +132,8 @@ char **argv;
 
     set_pname("calcsize");
 
+    dbopen(NULL);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -126,16 +147,16 @@ char **argv;
            continue;
        }
        printf("%s: st_size=%lu", argv[i],(unsigned long)finfo.st_size);
-       printf(": blocks=%lu\n", (unsigned long)ST_BLOCKS(finfo));
-       dump_total += (ST_BLOCKS(finfo) + 1)/2 + 1;
-       gtar_total += ROUND(4,(ST_BLOCKS(finfo) + 1));
+       printf(": blocks=%llu\n", ST_BLOCKS(finfo));
+       dump_total += (ST_BLOCKS(finfo) + (off_t)1) / (off_t)2 + (off_t)1;
+       gtar_total += ROUND(4,(ST_BLOCKS(finfo) + (off_t)1));
     }
     printf("           gtar           dump\n");
     printf("total      %-9lu         %-9lu\n",gtar_total,dump_total);
     return 0;
 #else
     int i;
-    char *dirname=NULL, *amname=NULL, *filename=NULL;
+    char *dirname=NULL, *amname=NULL, *filename=NULL, *qfilename = NULL;
     unsigned long malloc_hist_1, malloc_size_1;
     unsigned long malloc_hist_2, malloc_size_2;
 
@@ -144,6 +165,9 @@ char **argv;
 
     set_pname("calcsize");
 
+    dbopen(DBG_SUBDIR_CLIENT);
+    dbprintf(("%s: version %s\n", debug_prefix(NULL), version()));
+
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
 #if 0
@@ -154,18 +178,25 @@ char **argv;
 
     /* need at least program, amname, and directory name */
 
-    if(argc < 3) {
-       error("Usage: %s [DUMP|GNUTAR] name dir [-X exclude-file] [-I include-file] [level date]*",
+    if(argc < 4) {
+       error("Usage: %s config [DUMP|GNUTAR] name dir [-X exclude-file] [-I include-file] [level date]*",
              get_pname());
-       return 1;
+        /*NOTREACHED*/
+    }
+
+    dbprintf(("config: %s\n", *argv));
+    if (strcmp(*argv, "NOCONFIG") != 0) {
+       dbrename(*argv, DBG_SUBDIR_CLIENT);
     }
+    argc--;
+    argv++;
 
     /* parse backup program name */
 
     if(strcmp(*argv, "DUMP") == 0) {
 #if !defined(DUMP) && !defined(XFSDUMP)
        error("dump not available on this system");
-       return 1;
+       /*NOTREACHED*/
 #else
        add_file_name = add_file_name_dump;
        add_file = add_file_dump;
@@ -175,7 +206,7 @@ char **argv;
     else if(strcmp(*argv, "GNUTAR") == 0) {
 #ifndef GNUTAR
        error("gnutar not available on this system");
-       return 1;
+       /*NOTREACHED*/
 #else
        add_file_name = add_file_name_gnutar;
        add_file = add_file_gnutar;
@@ -195,47 +226,66 @@ char **argv;
     if (argc > 0) {
        amname = *argv;
        argc--, argv++;
-    } else
+    } else {
        error("missing <name>");
+       /*NOTREACHED*/
+    }
 
     /* the toplevel directory name to search from */
     if (argc > 0) {
        dirname = *argv;
        argc--, argv++;
-    } else
+    } else {
        error("missing <dir>");
+       /*NOTREACHED*/
+    }
 
     if ((argc > 1) && strcmp(*argv,"-X") == 0) {
        argv++;
 
-       if (!use_gtar_excl) {
+       if (!(use_gtar_excl || use_star_excl)) {
          error("exclusion specification not supported");
-         return 1;
+         /*NOTREACHED*/
        }
        
        filename = stralloc(*argv);
+       qfilename = quote_string(filename);
        if (access(filename, R_OK) != 0) {
-           fprintf(stderr,"Cannot open exclude file %s\n",filename);
-           use_gtar_excl = 0;
+           fprintf(stderr,"Cannot open exclude file %s\n", qfilename);
+           use_gtar_excl = use_star_excl = 0;
        } else {
-         exclude_sl = calc_load_file(filename);
+           exclude_sl = calc_load_file(filename);
+           if (!exclude_sl) {
+               fprintf(stderr,"Cannot open exclude file %s: %s\n", qfilename,
+                       strerror(errno));
+               use_gtar_excl = use_star_excl = 0;
+           }
        }
+       amfree(qfilename);
        amfree(filename);
        argc -= 2;
        argv++;
-    } else
-       use_gtar_excl = 0;
+    } else {
+       use_gtar_excl = use_star_excl = 0;
+    }
 
     if ((argc > 1) && strcmp(*argv,"-I") == 0) {
        argv++;
        
        filename = stralloc(*argv);
+       qfilename = quote_string(filename);
        if (access(filename, R_OK) != 0) {
-           fprintf(stderr,"Cannot open include file %s\n",filename);
-           use_gtar_excl = 0;
+           fprintf(stderr,"Cannot open include file %s\n", qfilename);
+           use_gtar_excl = use_star_excl = 0;
        } else {
-         include_sl = calc_load_file(filename);
+           include_sl = calc_load_file(filename);
+           if (!include_sl) {
+               fprintf(stderr,"Cannot open include file %s: %s\n", qfilename,
+                       strerror(errno));
+               use_gtar_excl = use_star_excl = 0;
+           }
        }
+       amfree(qfilename);
        amfree(filename);
        argc -= 2;
        argv++;
@@ -253,8 +303,10 @@ char **argv;
        }
     }
 
-    if(argc)
+    if(argc) {
        error("leftover arg \"%s\", expected <level> and <date>", *argv);
+       /*NOTREACHED*/
+    }
 
     if(is_empty_sl(include_sl)) {
        traverse_dirs(dirname,".");
@@ -275,11 +327,18 @@ char **argv;
 
        amflock(1, "size");
 
-       lseek(1, (off_t)0, SEEK_END);
+       if (fseek(stderr, 0L, SEEK_END) < 0) {
+           dbprintf(("calcsize: warning - seek failed: %s\n",
+                     strerror(errno)));
+       }
 
-       fprintf(stderr, "%s %d SIZE %ld\n",
-              amname, dumplevel[i], final_size(i, dirname));
-       fflush(stdout);
+       dbprintf(("calcsize: %s %d SIZE " OFF_T_FMT "\n",
+              amname, dumplevel[i],
+              (OFF_T_FMT_TYPE)final_size(i, dirname)));
+       fprintf(stderr, "%s %d SIZE " OFF_T_FMT "\n",
+              amname, dumplevel[i],
+              (OFF_T_FMT_TYPE)final_size(i, dirname));
+       fflush(stderr);
 
        amfunlock(1, "size");
     }
@@ -299,10 +358,10 @@ char **argv;
  */
 
 #if !defined(HAVE_BASENAME) && defined(BUILTIN_EXCLUDE_SUPPORT)
-static char *basename P((char *));
 
-static char *basename(file)
-char *file;
+static char *
+basename(
+    char *     file)
 {
     char *cp;
 
@@ -312,27 +371,30 @@ char *file;
 }
 #endif
 
-void push_name P((char *str));
-char *pop_name P((void));
+void push_name(char *str);
+char *pop_name(void);
 
-void traverse_dirs(parent_dir, include)
-char *parent_dir;
-char *include;
+void
+traverse_dirs(
+    char *     parent_dir,
+    char *     include)
 {
     DIR *d;
     struct dirent *f;
     struct stat finfo;
     char *dirname, *newname = NULL;
     char *newbase = NULL;
-    dev_t parent_dev = 0;
+    dev_t parent_dev = (dev_t)0;
     int i;
-    int l;
-    int parent_len;
-    int has_exclude = !is_empty_sl(exclude_sl) && use_gtar_excl;
+    size_t l;
+    size_t parent_len;
+    int has_exclude;
     char *aparent;
 
-    if(parent_dir == NULL || include == NULL) return;
+    if(parent_dir == NULL || include == NULL)
+       return;
 
+    has_exclude = !is_empty_sl(exclude_sl) && (use_gtar_excl || use_star_excl);
     aparent = vstralloc(parent_dir, "/", include, NULL);
 
     if(stat(parent_dir, &finfo) != -1)
@@ -342,7 +404,7 @@ char *include;
 
     push_name(aparent);
 
-    for(dirname = pop_name(); dirname; free(dirname), dirname = pop_name()) {
+    for(; (dirname = pop_name()) != NULL; free(dirname)) {
        if(has_exclude && calc_check_exclude(dirname+parent_len+1)) {
            continue;
        }
@@ -390,7 +452,7 @@ char *include;
                int is_excluded = -1;
                for(i = 0; i < ndumps; i++) {
                    add_file_name(i, newname);
-                   if(is_file && finfo.st_ctime >= dumpdate[i]) {
+                   if(is_file && (time_t)finfo.st_ctime >= dumpdate[i]) {
 
                        if(has_exclude) {
                            if(is_excluded == -1)
@@ -424,19 +486,21 @@ char *include;
     amfree(aparent);
 }
 
-void push_name(str)
-char *str;
+void
+push_name(
+    char *     str)
 {
     Name *newp;
 
-    newp = alloc(sizeof(*newp));
+    newp = alloc(SIZEOF(*newp));
     newp->str = stralloc(str);
 
     newp->next = name_stack;
     name_stack = newp;
 }
 
-char *pop_name()
+char *
+pop_name(void)
 {
     Name *newp = name_stack;
     char *str;
@@ -466,28 +530,35 @@ char *pop_name()
  * requirements for files with holes, nor the dumping of directories that
  * are not themselves modified.
  */
-void add_file_name_dump(level, name)
-int level;
-char *name;
+void
+add_file_name_dump(
+    int                level,
+    char *     name)
 {
+    (void)level;       /* Quiet unused parameter warning */
+    (void)name;                /* Quiet unused parameter warning */
+
     return;
 }
 
-void add_file_dump(level, sp)
-int level;
-struct stat *sp;
+void
+add_file_dump(
+    int                        level,
+    struct stat *      sp)
 {
     /* keep the size in kbytes, rounded up, plus a 1k header block */
     if((sp->st_mode & S_IFMT) == S_IFREG || (sp->st_mode & S_IFMT) == S_IFDIR)
-       dumpstats[level].total_size += (ST_BLOCKS(*sp) + 1)/2 + 1;
+       dumpstats[level].total_size +=
+                       (ST_BLOCKS(*sp) + (off_t)1) / (off_t)2 + (off_t)1;
 }
 
-long final_size_dump(level, topdir)
-int level;
-char *topdir;
+off_t
+final_size_dump(
+    int                level,
+    char *     topdir)
 {
     generic_fs_stats_t stats;
-    int mapsize;
+    off_t mapsize;
     char *s;
 
     /* calculate the map sizes */
@@ -495,15 +566,16 @@ char *topdir;
     s = stralloc2(topdir, "/.");
     if(get_fs_stats(s, &stats) == -1) {
        error("statfs %s: %s", s, strerror(errno));
+       /*NOTREACHED*/
     }
     amfree(s);
 
-    mapsize = (stats.files + 7) / 8;   /* in bytes */
-    mapsize = (mapsize + 1023) / 1024;  /* in kbytes */
+    mapsize = (stats.files + (off_t)7) / (off_t)8;    /* in bytes */
+    mapsize = (mapsize + (off_t)1023) / (off_t)1024;  /* in kbytes */
 
     /* the dump contains three maps plus the files */
 
-    return 3*mapsize + dumpstats[level].total_size;
+    return (mapsize * (off_t)3) + dumpstats[level].total_size;
 }
 
 /*
@@ -517,29 +589,37 @@ char *topdir;
  *
  * As with DUMP, we only need a reasonable estimate, not an exact figure.
  */
-void add_file_name_gnutar(level, name)
-int level;
-char *name;
+void
+add_file_name_gnutar(
+    int                level,
+    char *     name)
 {
-/*    dumpstats[level].total_size_name += strlen(name) + 64;*/
-      dumpstats[level].total_size += 1;
+    (void)name;        /* Quiet unused parameter warning */
+
+/*  dumpstats[level].total_size_name += strlen(name) + 64;*/
+    dumpstats[level].total_size += (off_t)1;
 }
 
-void add_file_gnutar(level, sp)
-int level;
-struct stat *sp;
+void
+add_file_gnutar(
+    int                        level,
+    struct stat *      sp)
 {
     /* the header takes one additional block */
     dumpstats[level].total_size += ST_BLOCKS(*sp);
 }
 
-long final_size_gnutar(level, topdir)
-int level;
-char *topdir;
+off_t
+final_size_gnutar(
+    int                level,
+    char *     topdir)
 {
+    (void)topdir;      /* Quiet unused parameter warning */
+
     /* divide by two to get kbytes, rounded up */
     /* + 4 blocks for security */
-    return (dumpstats[level].total_size + 5 + (dumpstats[level].total_size_name/512)) / 2;
+    return (dumpstats[level].total_size + (off_t)5 +
+               (dumpstats[level].total_size_name/(off_t)512)) / (off_t)2;
 }
 
 /*
@@ -549,42 +629,57 @@ char *topdir;
  * Here we'll just add up the file sizes and output that.
  */
 
-void add_file_name_unknown(level, name)
-int level;
-char *name;
+void
+add_file_name_unknown(
+    int                level,
+    char *     name)
 {
+    (void)level;       /* Quiet unused parameter warning */
+    (void)name;                /* Quiet unused parameter warning */
+
     return;
 }
 
-void add_file_unknown(level, sp)
-int level;
-struct stat *sp;
+void
+add_file_unknown(
+    int                        level,
+    struct stat *      sp)
 {
     /* just add up the block counts */
     if((sp->st_mode & S_IFMT) == S_IFREG || (sp->st_mode & S_IFMT) == S_IFDIR)
        dumpstats[level].total_size += ST_BLOCKS(*sp);
 }
 
-long final_size_unknown(level, topdir)
-int level;
-char *topdir;
+off_t
+final_size_unknown(
+    int                level,
+    char *     topdir)
 {
+    (void)topdir;      /* Quiet unused parameter warning */
+
     /* divide by two to get kbytes, rounded up */
-    return (dumpstats[level].total_size + 1) / 2;
+    return (dumpstats[level].total_size + (off_t)1) / (off_t)2;
 }
 
 /*
  * =========================================================================
  */
-sl_t *calc_load_file(filename)
-char *filename;
+sl_t *
+calc_load_file(
+    char *     filename)
 {
     char pattern[1025];
 
-    sl_t *sl_list = new_sl();
+    sl_t *sl_list;
 
     FILE *file = fopen(filename, "r");
 
+    if (!file) {
+       return NULL;
+    }
+
+    sl_list = new_sl();
+
     while(fgets(pattern, 1025, file)) {
        if(strlen(pattern)>0 && pattern[strlen(pattern)-1] == '\n')
            pattern[strlen(pattern)-1] = '\0';
@@ -595,8 +690,9 @@ char *filename;
     return sl_list;
 }
 
-int calc_check_exclude(filename)
-char *filename;
+int
+calc_check_exclude(
+    char *     filename)
 {
     sle_t *an_exclude;
     if(is_empty_sl(exclude_sl)) return 0;
index f766845f8a2e2001e22a4d7deddedc47ddf8738c..71ce4b4c6443c8152d97fb176b4b10bdfb4b6db4 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: client_util.c,v 1.32 2006/03/09 16:51:41 martinea Exp $
+ * $Id: client_util.c,v 1.34 2006/05/25 01:47:11 johnfranks Exp $
  *
  */
 
+#include "amanda.h"
 #include "client_util.h"
 #include "getfsent.h"
 #include "util.h"
 
 #define MAXMAXDUMPS 16
 
-static char *fixup_relative(name, device)
-char *name;
-char *device;
+static int add_exclude(FILE *file_exclude, char *aexc, int verbose);
+static int add_include(char *disk, char *device, FILE *file_include, char *ainc, int verbose);
+static char *build_name(char *disk, char *exin, int verbose);
+static char *get_name(char *diskname, char *exin, time_t t, int n);
+
+
+char *
+fixup_relative(
+    char *     name,
+    char *     device)
 {
     char *newname;
     if(*name != '/') {
@@ -51,10 +59,12 @@ char *device;
 }
 
 
-static char *get_name(diskname, exin, t, n)
-char *diskname, *exin;
-time_t t;
-int n;
+static char *
+get_name(
+    char *     diskname,
+    char *     exin,
+    time_t     t,
+    int                n)
 {
     char number[NUM_STR_SIZE];
     char *filename;
@@ -64,7 +74,7 @@ int n;
     if(n == 0)
        number[0] = '\0';
     else
-       snprintf(number, sizeof(number), "%03d", n - 1);
+       snprintf(number, SIZEOF(number), "%03d", n - 1);
        
     filename = vstralloc(get_pname(), ".", diskname, ".", ts, number, ".",
                         exin, NULL);
@@ -73,22 +83,25 @@ int n;
 }
 
 
-static char *build_name(disk, exin, verbose)
-char *disk, *exin;
-int verbose;
+static char *
+build_name(
+    char *     disk,
+    char *     exin,
+    int                verbose)
 {
-    int n=0, fd=-1;
+    int n;
+    int fd;
     char *filename = NULL;
     char *afilename = NULL;
     char *diskname;
     time_t curtime;
-    char *dbgdir = NULL;
+    char *dbgdir;
     char *e = NULL;
     DIR *d;
     struct dirent *entry;
-    char *test_name = NULL;
-    int match_len, d_name_len;
-
+    char *test_name;
+    size_t match_len, d_name_len;
+    char *quoted;
 
     time(&curtime);
     diskname = sanitise_filename(disk);
@@ -96,7 +109,8 @@ int verbose;
     dbgdir = stralloc2(AMANDA_TMPDIR, "/");
     if((d = opendir(AMANDA_TMPDIR)) == NULL) {
        error("open debug directory \"%s\": %s",
-       AMANDA_TMPDIR, strerror(errno));
+               AMANDA_TMPDIR, strerror(errno));
+       /*NOTREACHED*/
     }
     test_name = get_name(diskname, exin,
                         curtime - (AMANDA_DEBUG_DAYS * 24 * 60 * 60), 0);
@@ -124,7 +138,7 @@ int verbose;
     do {
        filename = get_name(diskname, exin, curtime, n);
        afilename = newvstralloc(afilename, dbgdir, filename, NULL);
-       if((fd=open(afilename, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0600)) < 0){
+       if((fd=open(afilename, O_WRONLY|O_CREAT|O_APPEND, 0600)) < 0){
            amfree(afilename);
            n++;
        }
@@ -137,11 +151,16 @@ int verbose;
     if(afilename == NULL) {
        filename = get_name(diskname, exin, curtime, 0);
        afilename = newvstralloc(afilename, dbgdir, filename, NULL);
-       dbprintf(("%s: Cannot create '%s'\n", debug_prefix(NULL), afilename));
-       if(verbose)
-           printf("ERROR [cannot create: %s]\n", afilename);
-       amfree(filename);
+       quoted = quote_string(afilename);
+       dbprintf(("%s: Cannot create %s (%s)\n",
+                       debug_prefix(NULL), quoted, strerror(errno)));
+       if(verbose) {
+           printf("ERROR [cannot create %s (%s)]\n",
+                       quoted, strerror(errno));
+       }
+       amfree(quoted);
        amfree(afilename);
+       amfree(filename);
     }
 
     amfree(dbgdir);
@@ -151,54 +170,71 @@ int verbose;
 }
 
 
-static int add_exclude(file_exclude, aexc, verbose)
-FILE *file_exclude;
-char *aexc;
-int verbose;
+static int
+add_exclude(
+    FILE *     file_exclude,
+    char *     aexc,
+    int                verbose)
 {
-    int l;
+    size_t l;
+    char *quoted, *file;
+
+    (void)verbose;     /* Quiet unused parameter warning */
 
     l = strlen(aexc);
     if(aexc[l-1] == '\n') {
        aexc[l-1] = '\0';
        l--;
     }
-    fprintf(file_exclude, "%s\n", aexc);
+    file = quoted = quote_string(aexc);
+    if (*file == '"') {
+       file[strlen(file) - 1] = '\0';
+       file++;
+    }
+    fprintf(file_exclude, "%s\n", file);
+    amfree(quoted);
     return 1;
 }
 
-static int add_include(disk, device, file_include, ainc, verbose)
-char *disk, *device;
-FILE *file_include;
-char *ainc;
-int verbose;
+static int
+add_include(
+    char *     disk,
+    char *     device,
+    FILE *     file_include,
+    char *     ainc,
+    int                verbose)
 {
-    int l;
+    size_t l;
     int nb_exp=0;
+    char *quoted, *file;
+
+    (void)disk;        /* Quiet unused parameter warning */
 
     l = strlen(ainc);
     if(ainc[l-1] == '\n') {
        ainc[l-1] = '\0';
        l--;
     }
-    if(l < 3) {
-       dbprintf(("%s: include must be at least 3 character long: %s\n",
-                 debug_prefix(NULL), ainc));
-       if(verbose)
-           printf("ERROR [include must be at least 3 character long: %s]\n", ainc);
-       return 0;
-    }
-    else if(ainc[0] != '.' && ainc[0] != '\0' && ainc[1] != '/') {
-        dbprintf(("%s: include must start with './': %s\n",
-                 debug_prefix(NULL), ainc));
-       if(verbose)
-           printf("ERROR [include must start with './': %s]\n", ainc);
-       return 0;
+    if (strncmp(ainc, "./", 2) != 0) {
+        quoted = quote_string(ainc);
+        dbprintf(("%s: include must start with './' (%s)\n",
+                 debug_prefix(NULL), quoted));
+       if(verbose) {
+           printf("ERROR [include must start with './' (%s)]\n", quoted);
+       }
+       amfree(quoted);
     }
     else {
        char *incname = ainc+2;
+
        if(strchr(incname, '/')) {
-           fprintf(file_include, "./%s\n", incname);
+            file = quoted = quote_string(ainc);
+           if (*file == '"') {
+               file[strlen(file) - 1] = '\0';
+               file++;
+           }
+           fprintf(file_include, "%s\n", file);
+           amfree(quoted);
            nb_exp++;
        }
        else {
@@ -208,12 +244,13 @@ int verbose;
 
            regex = glob_to_regex(incname);
            if((d = opendir(device)) == NULL) {
-               dbprintf(("%s: Can't open disk '%s']\n",
-                     debug_prefix(NULL), device));
-               if(verbose)
-                   printf("ERROR [Can't open disk '%s']\n", device);
-               amfree(regex);
-               return 0;
+               quoted = quote_string(device);
+               dbprintf(("%s: Can't open disk %s\n",
+                     debug_prefix(NULL), quoted));
+               if(verbose) {
+                   printf("ERROR [Can't open disk %s]\n", quoted);
+               }
+               amfree(quoted);
            }
            else {
                while((entry = readdir(d)) != NULL) {
@@ -221,7 +258,15 @@ int verbose;
                        continue;
                    }
                    if(match(regex, entry->d_name)) {
-                       fprintf(file_include, "./%s\n", entry->d_name);
+                       incname = vstralloc("./", entry->d_name, NULL);
+                       file = quoted = quote_string(incname);
+                       if (*file == '"') {
+                           file[strlen(file) - 1] = '\0';
+                           file++;
+                       }
+                       fprintf(file_include, "%s\n", file);
+                       amfree(quoted);
+                       amfree(incname);
                        nb_exp++;
                    }
                }
@@ -233,17 +278,20 @@ int verbose;
     return nb_exp;
 }
 
-char *build_exclude(disk, device, options, verbose)
-char *disk, *device;
-option_t *options;
-int verbose;
+char *
+build_exclude(
+    char *     disk,
+    char *     device,
+    option_t * options,
+    int                verbose)
 {
     char *filename;
     FILE *file_exclude;
     FILE *exclude;
-    char *aexc = NULL;
+    char *aexc;
     sle_t *excl;
     int nb_exclude = 0;
+    char *quoted;
 
     if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
     if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
@@ -267,6 +315,10 @@ int verbose;
                    char *exclname = fixup_relative(excl->name, device);
                    if((exclude = fopen(exclname, "r")) != NULL) {
                        while ((aexc = agets(exclude)) != NULL) {
+                           if (aexc[0] == '\0') {
+                               amfree(aexc);
+                               continue;
+                           }
                            add_exclude(file_exclude, aexc,
                                        verbose && options->exclude_optional == 0);
                            amfree(aexc);
@@ -274,13 +326,16 @@ int verbose;
                        fclose(exclude);
                    }
                    else {
-                       dbprintf(("%s: Can't open exclude file '%s': %s\n",
+                       quoted = quote_string(exclname);
+                       dbprintf(("%s: Can't open exclude file %s (%s)\n",
                                  debug_prefix(NULL),
-                                 exclname, strerror(errno)));
+                                 quoted, strerror(errno)));
                        if(verbose && (options->exclude_optional == 0 ||
-                                      errno != ENOENT))
-                           printf("ERROR [Can't open exclude file '%s': %s]\n",
-                                  exclname, strerror(errno));
+                                      errno != ENOENT)) {
+                           printf("ERROR [Can't open exclude file %s (%s)]\n",
+                                  quoted, strerror(errno));
+                       }
+                       amfree(quoted);
                    }
                    amfree(exclname);
                }
@@ -288,23 +343,27 @@ int verbose;
             fclose(file_exclude);
        }
        else {
-           dbprintf(("%s: Can't create exclude file '%s': %s\n",
+           quoted = quote_string(filename);
+           dbprintf(("%s: Can't create exclude file %s (%s)\n",
                      debug_prefix(NULL),
-                     filename, strerror(errno)));
-           if(verbose)
-               printf("ERROR [Can't create exclude file '%s': %s]\n", filename,
-                       strerror(errno));
+                     quoted, strerror(errno)));
+           if(verbose) {
+               printf("ERROR [Can't create exclude file %s (%s)]\n",
+                       quoted, strerror(errno));
+           }
+           amfree(quoted);
        }
     }
 
     return filename;
 }
 
-char *build_include(disk, device, options, verbose)
-char *disk;
-char *device;
-option_t *options;
-int verbose;
+char *
+build_include(
+    char *     disk,
+    char *     device,
+    option_t * options,
+    int                verbose)
 {
     char *filename;
     FILE *file_include;
@@ -313,6 +372,7 @@ int verbose;
     sle_t *incl;
     int nb_include = 0;
     int nb_exp = 0;
+    char *quoted;
 
     if(options->include_file) nb_include += options->include_file->nb_element;
     if(options->include_list) nb_include += options->include_list->nb_element;
@@ -327,7 +387,7 @@ int verbose;
                    incl = incl->next) {
                    nb_exp += add_include(disk, device, file_include,
                                  incl->name,
-                                  verbose && options->include_optional == 0);
+                                 verbose && options->include_optional == 0);
                }
            }
 
@@ -337,6 +397,10 @@ int verbose;
                    char *inclname = fixup_relative(incl->name, device);
                    if((include = fopen(inclname, "r")) != NULL) {
                        while ((ainc = agets(include)) != NULL) {
+                           if (ainc[0] == '\0') {
+                               amfree(ainc);
+                               continue;
+                           }
                            nb_exp += add_include(disk, device,
                                                  file_include, ainc,
                                                  verbose && options->include_optional == 0);
@@ -345,13 +409,15 @@ int verbose;
                        fclose(include);
                    }
                    else {
-                       dbprintf(("%s: Can't open include file '%s': %s\n",
-                                 debug_prefix(NULL),
-                                 inclname, strerror(errno)));
+                       quoted = quote_string(inclname);
+                       dbprintf(("%s: Can't open include file %s (%s)\n",
+                                 debug_prefix(NULL), quoted, strerror(errno)));
                        if(verbose && (options->include_optional == 0 ||
-                                      errno != ENOENT))
-                           printf("ERROR [Can't open include file '%s': %s]\n",
-                                  inclname, strerror(errno));
+                                      errno != ENOENT)) {
+                           printf("ERROR [Can't open include file %s (%s)]\n",
+                                  quoted, strerror(errno));
+                       }
+                       amfree(quoted);
                   }
                   amfree(inclname);
                }
@@ -359,27 +425,33 @@ int verbose;
             fclose(file_include);
        }
        else {
-           dbprintf(("%s: Can't create include file '%s': %s\n",
-                     debug_prefix(NULL),
-                     filename, strerror(errno)));
-           if(verbose)
-               printf("ERROR [Can't create include file '%s': %s]\n", filename,
-                       strerror(errno));
+           quoted = quote_string(filename);
+           dbprintf(("%s: Can't create include file %s (%s)\n",
+                     debug_prefix(NULL), quoted, strerror(errno)));
+           if(verbose) {
+               printf("ERROR [Can't create include file %s (%s)]\n",
+                       quoted, strerror(errno));
+           }
+           amfree(quoted);
        }
     }
        
     if(nb_exp == 0) {
-       dbprintf(("%s: No include for '%s'\n", debug_prefix(NULL), disk));
-       if(verbose && options->include_optional == 0)
-           printf("ERROR [No include for '%s']\n", disk);
+       quoted = quote_string(disk);
+       dbprintf(("%s: No include for %s\n", debug_prefix(NULL), quoted));
+       if(verbose && options->include_optional == 0) {
+           printf("ERROR [No include for %s]\n", quoted);
+       }
+       amfree(quoted);
     }
 
     return filename;
 }
 
 
-void init_options(options)
-option_t *options;
+void
+init_options(
+    option_t *options)
 {
     options->str = NULL;
     options->compress = NO_COMPR;
@@ -402,17 +474,24 @@ option_t *options;
 }
 
 
-option_t *parse_options(str, disk, device, fs, verbose)
-char *str;
-char *disk, *device;
-am_feature_t *fs;
-int verbose;
+option_t *
+parse_options(
+    char *str,
+    char *disk,
+    char *device,
+    am_feature_t *fs,
+    int verbose)
 {
     char *exc;
+    char *inc;
     option_t *options;
     char *p, *tok;
+    char *quoted;
+
+    (void)disk;                /* Quiet unused parameter warning */
+    (void)device;      /* Quiet unused parameter warning */
 
-    options = alloc(sizeof(option_t));
+    options = alloc(SIZEOF(option_t));
     init_options(options);
     options->str = stralloc(str);
 
@@ -423,21 +502,23 @@ int verbose;
        if(am_has_feature(fs, fe_options_auth)
           && BSTRNCMP(tok,"auth=") == 0) {
            if(options->auth != NULL) {
-               dbprintf(("%s: multiple auth option \"%s\"\n",
-                         debug_prefix(NULL), tok+5));
+               quoted = quote_string(tok + 5);
+               dbprintf(("%s: multiple auth option %s\n",
+                         debug_prefix(NULL), quoted));
                if(verbose) {
-                   printf("ERROR [multiple auth option \"%s\"\n", tok+5);
+                   printf("ERROR [multiple auth option %s]\n", quoted);
                }
+               amfree(quoted);
            }
            options->auth = stralloc(&tok[5]);
        }
        else if(am_has_feature(fs, fe_options_bsd_auth)
           && BSTRNCMP(tok, "bsd-auth") == 0) {
            if(options->auth != NULL) {
-               dbprintf(("%s: multiple auth option \n",
+               dbprintf(("%s: multiple auth option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple auth option \n");
+                   printf("ERROR [multiple auth option]\n");
                }
            }
            options->auth = stralloc("bsd");
@@ -445,50 +526,50 @@ int verbose;
        else if(am_has_feature(fs, fe_options_krb4_auth)
           && BSTRNCMP(tok, "krb4-auth") == 0) {
            if(options->auth != NULL) {
-               dbprintf(("%s: multiple auth option \n",
+               dbprintf(("%s: multiple auth option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple auth option \n");
+                   printf("ERROR [multiple auth option]\n");
                }
            }
            options->auth = stralloc("krb4");
        }
        else if(BSTRNCMP(tok, "compress-fast") == 0) {
            if(options->compress != NO_COMPR) {
-               dbprintf(("%s: multiple compress option \n",
+               dbprintf(("%s: multiple compress option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple compress option \n");
+                   printf("ERROR [multiple compress option]\n");
                }
            }
            options->compress = COMPR_FAST;
        }
        else if(BSTRNCMP(tok, "compress-best") == 0) {
            if(options->compress != NO_COMPR) {
-               dbprintf(("%s: multiple compress option \n",
+               dbprintf(("%s: multiple compress option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple compress option \n");
+                   printf("ERROR [multiple compress option]\n");
                }
            }
            options->compress = COMPR_BEST;
        }
        else if(BSTRNCMP(tok, "srvcomp-fast") == 0) {
            if(options->compress != NO_COMPR) {
-               dbprintf(("%s: multiple compress option \n",
+               dbprintf(("%s: multiple compress option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple compress option \n");
+                   printf("ERROR [multiple compress option]\n");
                }
            }
            options->compress = COMPR_SERVER_FAST;
        }
        else if(BSTRNCMP(tok, "srvcomp-best") == 0) {
            if(options->compress != NO_COMPR) {
-               dbprintf(("%s: multiple compress option \n",
+               dbprintf(("%s: multiple compress option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple compress option \n");
+                   printf("ERROR [multiple compress option]\n");
                }
            }
            options->compress = COMPR_SERVER_BEST;
@@ -501,7 +582,7 @@ int verbose;
                    printf("ERROR [multiple compress option]\n");
                }
            }
-           options->srvcompprog = stralloc(tok + sizeof("srvcomp-cust=") -1);
+           options->srvcompprog = stralloc(tok + SIZEOF("srvcomp-cust=") -1);
            options->compress = COMPR_SERVER_CUST;
        }
        else if(BSTRNCMP(tok, "comp-cust=") == 0) {
@@ -512,7 +593,7 @@ int verbose;
                    printf("ERROR [multiple compress option]\n");
                }
            }
-           options->clntcompprog = stralloc(tok + sizeof("comp-cust=") -1);
+           options->clntcompprog = stralloc(tok + SIZEOF("comp-cust=") -1);
            options->compress = COMPR_CUST;
            /* parse encryption options */
        } 
@@ -524,7 +605,7 @@ int verbose;
                    printf("ERROR [multiple encrypt option]\n");
                }
            }
-           options->srv_encrypt = stralloc(tok + sizeof("encrypt-serv-cust=") -1);
+           options->srv_encrypt = stralloc(tok + SIZEOF("encrypt-serv-cust=") -1);
            options->encrypt = ENCRYPT_SERV_CUST;
        } 
        else if(BSTRNCMP(tok, "encrypt-cust=") == 0) {
@@ -535,184 +616,86 @@ int verbose;
                    printf("ERROR [multiple encrypt option]\n");
                }
            }
-           options->clnt_encrypt= stralloc(tok + sizeof("encrypt-cust=") -1);
+           options->clnt_encrypt= stralloc(tok + SIZEOF("encrypt-cust=") -1);
            options->encrypt = ENCRYPT_CUST;
        } 
        else if(BSTRNCMP(tok, "server-decrypt-option=") == 0) {
-         options->srv_decrypt_opt = stralloc(tok + sizeof("server-decrypt-option=") -1);
+         options->srv_decrypt_opt = stralloc(tok + SIZEOF("server-decrypt-option=") -1);
        }
        else if(BSTRNCMP(tok, "client-decrypt-option=") == 0) {
-         options->clnt_decrypt_opt = stralloc(tok + sizeof("client-decrypt-option=") -1);
+         options->clnt_decrypt_opt = stralloc(tok + SIZEOF("client-decrypt-option=") -1);
        }
        else if(BSTRNCMP(tok, "no-record") == 0) {
            if(options->no_record != 0) {
-               dbprintf(("%s: multiple no-record option \n",
+               dbprintf(("%s: multiple no-record option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple no-record option \n");
+                   printf("ERROR [multiple no-record option]\n");
                }
            }
            options->no_record = 1;
        }
        else if(BSTRNCMP(tok, "index") == 0) {
            if(options->createindex != 0) {
-               dbprintf(("%s: multiple index option \n",
+               dbprintf(("%s: multiple index option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple index option \n");
+                   printf("ERROR [multiple index option]\n");
                }
            }
            options->createindex = 1;
        }
        else if(BSTRNCMP(tok, "exclude-optional") == 0) {
            if(options->exclude_optional != 0) {
-               dbprintf(("%s: multiple exclude-optional option \n",
+               dbprintf(("%s: multiple exclude-optional option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple exclude-optional option \n");
+                   printf("ERROR [multiple exclude-optional option]\n");
                }
            }
            options->exclude_optional = 1;
        }
        else if(strcmp(tok, "include-optional") == 0) {
            if(options->include_optional != 0) {
-               dbprintf(("%s: multiple include-optional option \n",
+               dbprintf(("%s: multiple include-optional option\n",
                          debug_prefix(NULL)));
                if(verbose) {
-                   printf("ERROR [multiple include-optional option \n");
+                   printf("ERROR [multiple include-optional option]\n");
                }
            }
            options->include_optional = 1;
        }
        else if(BSTRNCMP(tok,"exclude-file=") == 0) {
-           exc = &tok[13];
-           options->exclude_file = append_sl(options->exclude_file,exc);
+           exc = unquote_string(&tok[13]);
+           options->exclude_file = append_sl(options->exclude_file, exc);
+           amfree(exc);
        }
        else if(BSTRNCMP(tok,"exclude-list=") == 0) {
-           exc = &tok[13];
+           exc = unquote_string(&tok[13]);
            options->exclude_list = append_sl(options->exclude_list, exc);
+           amfree(exc);
        }
        else if(BSTRNCMP(tok,"include-file=") == 0) {
-           exc = &tok[13];
-           options->include_file = append_sl(options->include_file,exc);
+           inc = unquote_string(&tok[13]);
+           options->include_file = append_sl(options->include_file, inc);
+           amfree(inc);
        }
        else if(BSTRNCMP(tok,"include-list=") == 0) {
-           exc = &tok[13];
-           options->include_list = append_sl(options->include_list, exc);
-       }
-       else if(strcmp(tok,"|") == 0) {
-       }
-       else {
-           dbprintf(("%s: unknown option \"%s\"\n", debug_prefix(NULL), tok));
+           inc = unquote_string(&tok[13]);
+           options->include_list = append_sl(options->include_list, inc);
+           amfree(inc);
+       }
+       else if(strcmp(tok,"|") != 0) {
+           quoted = quote_string(tok);
+           dbprintf(("%s: unknown option %s\n",
+                       debug_prefix(NULL), quoted));
            if(verbose) {
-               printf("ERROR [unknown option \"%s\"]\n", tok);
+               printf("ERROR [unknown option: %s]\n", quoted);
            }
+           amfree(quoted);
        }
        tok = strtok(NULL, ";");
     }
     amfree(p);
     return options;
 }
-
-
-void init_g_options(g_options)
-g_option_t *g_options;
-{
-    g_options->features = NULL;
-    g_options->hostname = NULL;
-    g_options->maxdumps = 0;
-}
-
-
-g_option_t *parse_g_options(str, verbose)
-char *str;
-int verbose;
-{
-    g_option_t *g_options;
-    char *p, *tok;
-    int new_maxdumps;
-
-    g_options = alloc(sizeof(g_option_t));
-    init_g_options(g_options);
-    g_options->str = stralloc(str);
-
-    p = stralloc(str);
-    tok = strtok(p,";");
-
-    while (tok != NULL) {
-       if(strncmp(tok,"features=", 9) == 0) {
-           if(g_options->features != NULL) {
-               dbprintf(("%s: multiple features option\n", 
-                         debug_prefix(NULL)));
-               if(verbose) {
-                   printf("ERROR [multiple features option]\n");
-               }
-           }
-           if((g_options->features = am_string_to_feature(tok+9)) == NULL) {
-               dbprintf(("%s: bad features value \"%s\n",
-                         debug_prefix(NULL), tok+10));
-               if(verbose) {
-                   printf("ERROR [bad features value \"%s\"]\n", tok+10);
-               }
-           }
-       }
-       else if(strncmp(tok,"hostname=", 9) == 0) {
-           if(g_options->hostname != NULL) {
-               dbprintf(("%s: multiple hostname option\n", 
-                         debug_prefix(NULL)));
-               if(verbose) {
-                   printf("ERROR [multiple hostname option]\n");
-               }
-           }
-           g_options->hostname = stralloc(tok+9);
-       }
-       else if(strncmp(tok,"maxdumps=", 9) == 0) {
-           if(g_options->maxdumps != 0) {
-               dbprintf(("%s: multiple maxdumps option\n", 
-                         debug_prefix(NULL)));
-               if(verbose) {
-                   printf("ERROR [multiple maxdumps option]\n");
-               }
-           }
-           if(sscanf(tok+9, "%d;", &new_maxdumps) == 1) {
-               if (new_maxdumps > MAXMAXDUMPS) {
-                   g_options->maxdumps = MAXMAXDUMPS;
-               }
-               else if (new_maxdumps > 0) {
-                   g_options->maxdumps = new_maxdumps;
-               }
-               else {
-                   dbprintf(("%s: bad maxdumps value \"%s\"\n",
-                             debug_prefix(NULL), tok+9));
-                   if(verbose) {
-                       printf("ERROR [bad maxdumps value \"%s\"]\n",
-                              tok+9);
-                   }
-               }
-           }
-           else {
-               dbprintf(("%s: bad maxdumps value \"%s\"\n",
-                         debug_prefix(NULL), tok+9));
-               if(verbose) {
-                   printf("ERROR [bad maxdumps value \"%s\"]\n",
-                          tok+9);
-               }
-           }
-       }
-       else {
-           dbprintf(("%s: unknown option \"%s\"\n",
-                                  debug_prefix(NULL), tok));
-           if(verbose) {
-               printf("ERROR [unknown option \"%s\"]\n", tok);
-           }
-       }
-       tok = strtok(NULL, ";");
-    }
-    if(g_options->features == NULL) {
-       g_options->features = am_set_default_feature_set();
-    }
-    if(g_options->maxdumps == 0) /* default */
-       g_options->maxdumps = 1;
-    amfree(p);
-    return g_options;
-}
index ef8ef8e3f477a9e02b0585d5f83c48c801ba9ba1..0745a3109574d6ae36fc72c44776b0995dc4e7d4 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: client_util.h,v 1.12 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: client_util.h,v 1.14 2006/05/25 01:47:11 johnfranks Exp $
  *
  */
 
@@ -57,13 +57,6 @@ typedef struct option_s {
     int include_optional;
 } option_t;
 
-typedef struct g_option_s {
-    char *str;
-    am_feature_t *features;
-    char *hostname;
-    int maxdumps;
-} g_option_t;
-
 #define NO_COMPR   0
 #define COMPR_FAST 1
 #define COMPR_BEST 2
@@ -76,16 +69,15 @@ typedef struct g_option_s {
 #define ENCRYPT_CUST         1 /* client-side custom encryption */
 #define ENCRYPT_SERV_CUST    2 /* server-side custom encryption */
 
-char *build_exclude P((char *disk, char *device, option_t *options, int verbose));
-char *build_include P((char *disk, char *device, option_t *options, int verbose));
-void init_options P((option_t *options));
-option_t *parse_options P((char *str,
+char *build_exclude(char *disk, char *device, option_t *options, int verbose);
+char *build_include(char *disk, char *device, option_t *options, int verbose);
+void init_options(option_t *options);
+option_t *parse_options(char *str,
                           char *disk,
                           char *device,
                           am_feature_t *features,
-                          int verbose));
+                          int verbose);
 
-void init_g_options P((g_option_t *g_options));
-g_option_t *parse_g_options P((char *str, int verbose));
+char *fixup_relative(char *name, char *device);
 
 #endif
diff --git a/client-src/clientconf.c b/client-src/clientconf.c
new file mode 100644 (file)
index 0000000..e2a2246
--- /dev/null
@@ -0,0 +1,648 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-2000 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: clientconf.c,v 1.17 2006/07/25 19:36:48 martinea Exp $
+ *
+ * read configuration file
+ */
+/*
+ *
+ * XXX - I'm not happy *at all* with this implementation, but I don't
+ * think YACC would be any easier.  A more table based implementation
+ * would be better.  Also clean up memory leaks.
+ */
+#include "amanda.h"
+#include "arglist.h"
+#include "util.h"
+#include "clientconf.h"
+#include "clock.h"
+
+/* configuration parameters */
+static char *cln_config_dir = NULL;
+
+val_t client_conf[CLN_CLN];
+
+command_option_t *client_options      = NULL;
+int               client_options_size = 0;
+
+/* predeclare local functions */
+
+static void init_defaults(void);
+static void read_conffile_recursively(char *filename);
+
+static int read_confline(void);
+
+keytab_t client_keytab[] = {
+    { "CONF", CONF_CONF },
+    { "INDEX_SERVER", CONF_INDEX_SERVER },
+    { "TAPE_SERVER", CONF_TAPE_SERVER },
+    { "TAPEDEV", CONF_TAPEDEV },
+    { "AUTH", CONF_AUTH },
+    { "SSH_KEYS", CONF_SSH_KEYS },
+    { "AMANDAD_PATH", CONF_AMANDAD_PATH },
+    { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
+    { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR },
+    { "AMANDATES", CONF_AMANDATES },
+    { "INCLUDEFILE", CONF_INCLUDEFILE },
+    { NULL, CONF_UNKNOWN },
+};
+
+t_conf_var client_var [] = {
+   { CONF_CONF           , CONFTYPE_STRING, read_string, CLN_CONF           , NULL },
+   { CONF_INDEX_SERVER   , CONFTYPE_STRING, read_string, CLN_INDEX_SERVER   , NULL },
+   { CONF_TAPE_SERVER    , CONFTYPE_STRING, read_string, CLN_TAPE_SERVER    , NULL },
+   { CONF_TAPEDEV        , CONFTYPE_STRING, read_string, CLN_TAPEDEV        , NULL },
+   { CONF_AUTH           , CONFTYPE_STRING, read_string, CLN_AUTH           , NULL },
+   { CONF_SSH_KEYS       , CONFTYPE_STRING, read_string, CLN_SSH_KEYS       , NULL },
+   { CONF_AMANDAD_PATH   , CONFTYPE_STRING, read_string, CLN_AMANDAD_PATH   , NULL },
+   { CONF_CLIENT_USERNAME, CONFTYPE_STRING, read_string, CLN_CLIENT_USERNAME, NULL },
+   { CONF_GNUTAR_LIST_DIR, CONFTYPE_STRING, read_string, CLN_GNUTAR_LIST_DIR, NULL },
+   { CONF_AMANDATES      , CONFTYPE_STRING, read_string, CLN_AMANDATES      , NULL },
+   { CONF_UNKNOWN        , CONFTYPE_INT   , NULL       , CLN_CLN            , NULL }
+};
+
+static int first_file = 1;
+
+/*
+** ------------------------
+**  External entry points
+** ------------------------
+*/
+
+/* return  0 on success        */
+/* return  1 on error          */
+/* return -1 if file not found */
+
+int read_clientconf(
+    char *filename)
+{
+    if(first_file == 1) {
+       init_defaults();
+       first_file = 0;
+    } else {
+       allow_overwrites = 1;
+    }
+
+    /* We assume that conf_confname & conf are initialized to NULL above */
+    read_conffile_recursively(filename);
+
+    command_overwrite(client_options, client_var, client_keytab, client_conf,
+                     "");
+
+    return got_parserror;
+}
+
+
+char *
+client_getconf_byname(
+    char *     str)
+{
+    static char *tmpstr;
+    char number[NUM_STR_SIZE];
+    t_conf_var *np;
+    keytab_t *kt;
+    char *s;
+    char ch;
+
+    tmpstr = stralloc(str);
+    s = tmpstr;
+    while((ch = *s++) != '\0') {
+       if(islower((int)ch))
+           s[-1] = (char)toupper(ch);
+    }
+
+    for(kt = client_keytab; kt->token != CONF_UNKNOWN; kt++)
+       if(kt->keyword && strcmp(kt->keyword, tmpstr) == 0) break;
+
+    if(kt->token == CONF_UNKNOWN) return NULL;
+
+    for(np = client_var; np->token != CONF_UNKNOWN; np++)
+       if(np->token == kt->token) break;
+
+    if(np->type == CONFTYPE_INT) {
+       snprintf(number, SIZEOF(number), "%d", client_getconf_int(np->parm));
+       tmpstr = newstralloc(tmpstr, number);
+    } else if(np->type == CONFTYPE_BOOL) {
+       if(client_getconf_boolean(np->parm) == 0) {
+           tmpstr = newstralloc(tmpstr, "off");
+       }
+       else {
+           tmpstr = newstralloc(tmpstr, "on");
+       }
+    } else if(np->type == CONFTYPE_REAL) {
+       snprintf(number, SIZEOF(number), "%lf", client_getconf_real(np->parm));
+       tmpstr = newstralloc(tmpstr, number);
+    } else {
+       tmpstr = newstralloc(tmpstr, client_getconf_str(np->parm));
+    }
+
+    return tmpstr;
+}
+
+int
+client_getconf_seen(
+    cconfparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(client_var, parm);
+    return(client_conf[np->parm].seen);
+}
+
+int
+client_getconf_boolean(
+    cconfparm_t        parm)
+{
+    t_conf_var *np;
+    np = get_np(client_var, parm);
+    if (np->type != CONFTYPE_BOOL) {
+       error("client_getconf_boolean: np is not a CONFTYPE_BOOL");
+       /*NOTREACHED*/
+    }
+    return(client_conf[np->parm].v.i != 0);
+}
+
+int
+client_getconf_int(
+    cconfparm_t        parm)
+{
+    t_conf_var *np;
+    np = get_np(client_var, parm);
+    if (np->type != CONFTYPE_INT) {
+       error("client_getconf_int: np is not a CONFTYPE_INT");
+       /*NOTREACHED*/
+    }
+
+    return(client_conf[np->parm].v.i);
+}
+
+off_t
+client_getconf_am64(
+    cconfparm_t        parm)
+{
+    t_conf_var *np;
+    np = get_np(client_var, parm);
+    if (np->type != CONFTYPE_AM64) {
+       error("client_getconf_am64: np is not a CONFTYPE_AM64");
+       /*NOTREACHED*/
+    }
+    return(client_conf[np->parm].v.am64);
+}
+
+double
+client_getconf_real(
+    cconfparm_t        parm)
+{
+    t_conf_var *np;
+    np = get_np(client_var, parm);
+    if (np->type != CONFTYPE_REAL) {
+       error("client_getconf_real: np is not a CONFTYPE_REAL");
+       /*NOTREACHED*/
+    }
+    return(client_conf[np->parm].v.r);
+}
+
+char *
+client_getconf_str(
+    cconfparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(client_var, parm);
+    if (np->type != CONFTYPE_STRING) {
+       error("client_getconf_string: np is not a CONFTYPE_STRING");
+       /*NOTREACHED*/
+    }
+    return(client_conf[np->parm].v.s);
+}
+
+/*
+** ------------------------
+**  Internal routines
+** ------------------------
+*/
+
+
+static void
+init_defaults(void)
+{
+    char *s;
+
+    /* defaults for exported variables */
+
+#ifdef DEFAULT_CONFIG
+    s = DEFAULT_CONFIG;
+#else
+    s = "";
+#endif
+    conf_init_string(&client_conf[CLN_CONF], s);
+
+#ifdef DEFAULT_SERVER
+    s = DEFAULT_SERVER;
+#else
+    s = "";
+#endif
+    conf_init_string(&client_conf[CLN_INDEX_SERVER], s);
+
+
+#ifdef DEFAULT_TAPE_SERVER
+    s = DEFAULT_TAPE_SERVER;
+#else
+#ifdef DEFAULT_SERVER
+    s = DEFAULT_SERVER;
+#else
+    s = "";
+#endif
+#endif
+    conf_init_string(&client_conf[CLN_TAPE_SERVER], s);
+
+#ifdef DEFAULT_TAPE_DEVICE
+    s = DEFAULT_TAPE_DEVICE;
+#else
+    s = NULL;
+#endif
+    conf_init_string(&client_conf[CLN_TAPEDEV], s);
+
+    conf_init_string(&client_conf[CLN_AUTH], "bsd");
+    conf_init_string(&client_conf[CLN_SSH_KEYS], "");
+    conf_init_string(&client_conf[CLN_AMANDAD_PATH], "");
+    conf_init_string(&client_conf[CLN_CLIENT_USERNAME], "");
+#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
+    conf_init_string(&client_conf[CLN_GNUTAR_LIST_DIR],
+                    GNUTAR_LISTED_INCREMENTAL_DIR);
+#else
+    conf_init_string(&client_conf[CLN_GNUTAR_LIST_DIR], NULL);
+#endif
+    conf_init_string(&client_conf[CLN_AMANDATES], "/etc/amandates");
+    /* defaults for internal variables */
+
+    conf_line_num = got_parserror = 0;
+    allow_overwrites = 0;
+    token_pushed = 0;
+
+}
+
+static void
+read_conffile_recursively(
+    char *     filename)
+{
+    /* Save globals used in read_confline(), elsewhere. */
+    int  save_line_num  = conf_line_num;
+    FILE *save_conf     = conf_conf;
+    char *save_confname = conf_confname;
+    int        rc;
+
+    if (*filename == '/' || cln_config_dir == NULL) {
+       conf_confname = stralloc(filename);
+    } else {
+       conf_confname = stralloc2(cln_config_dir, filename);
+    }
+
+    if((conf_conf = fopen(conf_confname, "r")) == NULL) {
+       dbprintf(("Could not open conf file \"%s\": %s\n", conf_confname,
+                 strerror(errno)));
+       amfree(conf_confname);
+       got_parserror = -1;
+       return;
+    }
+    dbprintf(("Reading conf file \"%s\".\n", conf_confname));
+
+    conf_line_num = 0;
+
+    /* read_confline() can invoke us recursively via "includefile" */
+    do {
+       rc = read_confline();
+    } while (rc != 0);
+    afclose(conf_conf);
+
+    amfree(conf_confname);
+
+    /* Restore globals */
+    conf_line_num = save_line_num;
+    conf_conf     = save_conf;
+    conf_confname = save_confname;
+}
+
+
+/* ------------------------ */
+
+
+static int
+read_confline(void)
+{
+    t_conf_var *np;
+
+    keytable = client_keytab;
+
+    conf_line_num += 1;
+    get_conftoken(CONF_ANY);
+    switch(tok) {
+    case CONF_INCLUDEFILE:
+       {
+           char *fn;
+
+           get_conftoken(CONF_STRING);
+           fn = tokenval.v.s;
+           read_conffile_recursively(fn);
+       }
+       break;
+
+    case CONF_NL:      /* empty line */
+       break;
+
+    case CONF_END:     /* end of file */
+       return 0;
+
+    default:
+       {
+           for(np = client_var; np->token != CONF_UNKNOWN; np++)
+               if(np->token == tok) break;
+
+           if(np->token == CONF_UNKNOWN) {
+               conf_parserror("configuration keyword expected");
+           } else {
+               np->read_function(np, &client_conf[np->parm]);
+               if(np->validate)
+                   np->validate(np, &client_conf[np->parm]);
+           }
+       }
+    }
+    if(tok != CONF_NL)
+       get_conftoken(CONF_NL);
+    return 1;
+}
+
+
+
+/* ------------------------ */
+
+#ifdef TEST
+
+static char *cln_config_name = NULL;
+static char *cln_config_dir = NULL;
+
+void
+dump_client_configuration(
+    char *filename)
+{
+    printf("AMANDA CLIENT CONFIGURATION FROM FILE \"%s\":\n\n", filename);
+
+    printf("cln_conf = \"%s\"\n", client_getconf_str(CLN_CONF));
+    printf("cln_index_server = \"%s\"\n", client_getconf_str(CLN_INDEX_SERVER));
+    printf("cln_tape_server = \"%s\"\n", client_getconf_str(CLN_TAPE_SERVER));
+    printf("cln_tapedev = \"%s\"\n", client_getconf_str(CLN_TAPEDEV));
+    printf("cln_auth = \"%s\"\n", client_getconf_str(CLN_AUTH));
+    printf("cln_ssh_keys = \"%s\"\n", client_getconf_str(CLN_SSH_KEYS));
+}
+
+int
+main(
+    int                argc,
+    char **    argv)
+{
+  char *conffile;
+  char *diskfile;
+  disklist_t lst;
+  int result;
+  unsigned long malloc_hist_1, malloc_size_1;
+  unsigned long malloc_hist_2, malloc_size_2;
+
+  safe_fd(-1, 0);
+
+  set_pname("conffile");
+
+  /* Don't die when child closes pipe */
+  signal(SIGPIPE, SIG_IGN);
+
+  malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+  startclock();
+
+  if (argc > 1) {
+    if (argv[1][0] == '/') {
+      cln_config_dir = stralloc(argv[1]);
+      cln_config_name = strrchr(cln_config_dir, '/') + 1;
+      cln_config_name[-1] = '\0';
+      cln_config_dir = newstralloc2(cln_config_dir, cln_config_dir, "/");
+    } else {
+      cln_config_name = stralloc(argv[1]);
+      cln_config_dir = vstralloc(CONFIG_DIR, "/", cln_config_name, "/", NULL);
+    }
+  } else {
+    char my_cwd[STR_SIZE];
+
+    if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
+      error("cannot determine current working directory");
+    }
+    cln_config_dir = stralloc2(my_cwd, "/");
+    if ((cln_config_name = strrchr(my_cwd, '/')) != NULL) {
+      cln_config_name = stralloc(cln_config_name + 1);
+    }
+  }
+
+  conffile = stralloc2(cln_config_dir, CONFFILE_NAME);
+  result = read_conffile(conffile);
+  if (result == 0) {
+      diskfile = client_getconf_str(CNF_DISKFILE);
+      if (diskfile != NULL && access(diskfile, R_OK) == 0) {
+         result = read_diskfile(diskfile, &lst);
+      }
+  }
+  dump_client_configuration(CONFFILE_NAME);
+  amfree(conffile);
+
+  malloc_size_2 = malloc_inuse(&malloc_hist_2);
+
+  if(malloc_size_1 != malloc_size_2) {
+    malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
+  }
+
+  return result;
+}
+
+#endif /* TEST */
+
+char *
+generic_client_get_security_conf(
+    char *     string,
+    void *     arg)
+{
+       (void)arg;      /* Quiet unused parameter warning */
+
+       if(!string || !*string)
+               return(NULL);
+
+       if(strcmp(string, "conf")==0) {
+               return(client_getconf_str(CLN_CONF));
+       } else if(strcmp(string, "index_server")==0) {
+               return(client_getconf_str(CLN_INDEX_SERVER));
+       } else if(strcmp(string, "tape_server")==0) {
+               return(client_getconf_str(CLN_TAPE_SERVER));
+       } else if(strcmp(string, "tapedev")==0) {
+               return(client_getconf_str(CLN_TAPEDEV));
+       } else if(strcmp(string, "auth")==0) {
+               return(client_getconf_str(CLN_AUTH));
+       } else if(strcmp(string, "ssh_keys")==0) {
+               return(client_getconf_str(CLN_SSH_KEYS));
+       } else if(strcmp(string, "amandad_path")==0) {
+               return(client_getconf_str(CLN_AMANDAD_PATH));
+       } else if(strcmp(string, "client_username")==0) {
+               return(client_getconf_str(CLN_CLIENT_USERNAME));
+       } else if(strcmp(string, "gnutar_list_dir")==0) {
+               return(client_getconf_str(CLN_GNUTAR_LIST_DIR));
+       } else if(strcmp(string, "amandates")==0) {
+               return(client_getconf_str(CLN_AMANDATES));
+/*
+       } else if(strcmp(string, "krb5principal")==0) {
+               return(client_getconf_str(CNF_KRB5PRINCIPAL));
+       } else if(strcmp(string, "krb5keytab")==0) {
+               return(client_getconf_str(CNF_KRB5KEYTAB));
+*/
+       }
+       return(NULL);
+}
+
+
+void
+parse_client_conf(
+    int parse_argc,
+    char **parse_argv,
+    int *new_argc,
+    char ***new_argv)
+{
+    int i;
+    char **my_argv;
+    char *myarg, *value;
+    command_option_t *client_option;
+
+    client_options = alloc((size_t)(parse_argc+1) * SIZEOF(*client_options));
+    client_options_size = parse_argc+1;
+    client_option = client_options;
+    client_option->name = NULL;
+
+    my_argv = alloc((size_t)parse_argc * SIZEOF(char *));
+    *new_argv = my_argv;
+    *new_argc = 0;
+    i=0;
+    while(i<parse_argc) {
+       if(strncmp(parse_argv[i],"-o",2) == 0) {
+           if(strlen(parse_argv[i]) > 2)
+               myarg = &parse_argv[i][2];
+           else {
+               i++;
+               if(i >= parse_argc)
+                   error("expect something after -o");
+               myarg = parse_argv[i];
+           }
+           value = index(myarg,'=');
+           if (value == NULL) {
+               conf_parserror("Must specify a value for %s.\n", myarg);
+           } else {
+               *value = '\0';
+               value++;
+               client_option->used = 0;
+               client_option->name = stralloc(myarg);
+               client_option->value = stralloc(value);
+               client_option++;
+               client_option->name = NULL;
+           }
+       }
+       else {
+           my_argv[*new_argc] = stralloc(parse_argv[i]);
+           *new_argc += 1;
+       }
+       i++;
+    }
+}
+
+/* return  0 on success             */
+/* return -1 if it is already there */
+/* return -2 if other failure       */
+int
+add_client_conf(
+    cconfparm_t parm,
+    char *value)
+{
+    t_conf_var *np;
+    keytab_t *kt;
+    command_option_t *command_option;
+    int nb_option;
+
+    for(np = client_var; np->token != CONF_UNKNOWN; np++)
+       if(np->parm == (int)parm) break;
+
+    if(np->token == CONF_UNKNOWN) return -2;
+
+    for(kt = client_keytab; kt->token != CONF_UNKNOWN; kt++)
+       if(kt->token == np->token) break;
+
+    if(kt->token == CONF_UNKNOWN) return -2;
+
+    /* Try to find it */
+    nb_option = 0;
+    for(command_option = client_options; command_option->name != NULL;
+                                                       command_option++) {
+       if(strcasecmp(command_option->name, kt->keyword) == 0) {
+           return -1;
+       }
+       nb_option++;
+    }
+
+    /* Increase size of client_options if needed */
+    if(nb_option >= client_options_size-1) {
+       client_options_size *= 2;
+       client_options = realloc(client_options,
+                               client_options_size * SIZEOF(*client_options));
+       if (client_options == NULL) {
+           error("Can't realloc client_options: %s\n", strerror(errno));
+           /*NOTREACHED*/
+       }
+       for(command_option = client_options; command_option->name != NULL;
+                                                       command_option++) {
+       }
+    }
+
+    /* add it */
+    command_option->used = 0;
+    command_option->name = stralloc(kt->keyword);
+    command_option->value = stralloc(value);
+    command_option++;
+    command_option->name = NULL;
+    return 0;
+}
+
+void
+report_bad_client_arg(void)
+{
+    command_option_t *command_option;
+
+    for(command_option = client_options; command_option->name != NULL;
+                                                       command_option++) {
+       if(command_option->used == 0) {
+           fprintf(stderr,"argument -o%s=%s not used\n",
+                   command_option->name, command_option->value);
+       }
+    }
+}
diff --git a/client-src/clientconf.h b/client-src/clientconf.h
new file mode 100644 (file)
index 0000000..d9157ac
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-2000 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: clientconf.h,v 1.9 2006/07/25 19:06:46 martinea Exp $
+ *
+ * interface for client config file reading code
+ */
+#ifndef CLIENTCONF_H
+#define CLIENTCONF_H
+
+#include "sl.h"
+
+#define CLIENTCONFFILE_NAME "client.conf"
+
+typedef enum conf_e {
+    CLN_CONF,
+    CLN_INDEX_SERVER,
+    CLN_TAPE_SERVER,
+    CLN_TAPEDEV,
+    CLN_AUTH,
+    CLN_SSH_KEYS,
+    CLN_AMANDAD_PATH,
+    CLN_CLIENT_USERNAME,
+    CLN_GNUTAR_LIST_DIR,
+    CLN_AMANDATES,
+    CLN_CLN
+} cconfparm_t;
+
+extern char *config_name;
+extern char *config_dir;
+
+void parse_client_conf(int, char **, int *, char ***);
+int  add_client_conf(cconfparm_t parm, char *value);
+void report_bad_client_arg(void);
+int read_clientconf(char *filename);
+int client_getconf_seen(cconfparm_t parameter);
+int client_getconf_boolean(cconfparm_t parameter);
+int client_getconf_int(cconfparm_t parameter);
+off_t client_getconf_am64(cconfparm_t parameter);
+double client_getconf_real(cconfparm_t parameter);
+char *client_getconf_str(cconfparm_t parameter);
+char *client_getconf_byname(char *confname);
+
+/* this is in securityconf.h */
+char *generic_client_get_security_conf(char *, void *);
+#endif /* ! CONFFILE_H */
index 301c2c15cef37f2862bfb7c0a552801401b3219c..d33e64f6debbebebc96a42df41314310f11c6407 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: findpass.c,v 1.12 2001/08/01 22:37:32 jrjackson Exp $
+ * $Id: findpass.c,v 1.13 2006/05/25 01:47:11 johnfranks Exp $
  *
  * Support routines for Amanda SAMBA support
  */
 
+#include "amanda.h"
 #include "findpass.h"
+#include "util.h"
 
 /*
  * Find the Samba password and optional domain for a given disk.
  * as soon as reasonable.
  */
 
-char *findpass(disk, domain)
-char *disk, **domain;
+char *
+findpass(
+    char *     disk,
+    char **    domain)
 {
   FILE *fp;
   static char *buffer = NULL;
   char *s, *d, *pw = NULL;
   int ch;
+  char *qname;
 
   *domain = NULL;                              /* just to be sure */
   if ( (fp = fopen("/etc/amandapass", "r")) ) {
     amfree(buffer);
     for (; (buffer = agets(fp)) != NULL; free(buffer)) {
+      if (buffer[0] == '\0')
+       continue;
       s = buffer;
       ch = *s++;
       skip_whitespace(s, ch);                  /* find start of disk name */
       if (!ch || ch == '#') {
        continue;
       }
-      d = s-1;                                 /* start of disk name */
-      skip_non_whitespace_cs(s, ch);
+      qname = s-1;                             /* start of disk name */
+      skip_quoted_string(s, ch);
       if (ch && ch != '#') {
        s[-1] = '\0';                           /* terminate disk name */
+       d = unquote_string(qname);
        if ((strcmp(d,"*") == 0) || (strcmp(disk, d) == 0)) {
          skip_whitespace(s, ch);               /* find start of password */
          if (ch && ch != '#') {
@@ -74,8 +82,10 @@ char *disk, **domain;
              *domain = stralloc(*domain);
            }
          }
+         amfree(d);
          break;
        }
+       amfree(d);
       }
     }
     afclose(fp);
@@ -89,12 +99,13 @@ char *disk, **domain;
  * Returns a new name alloc-d that the caller is responsible
  * for free-ing.
  */
-char *makesharename(disk, shell)
-char *disk;
-int shell;
+char *
+makesharename(
+    char *     disk,
+    int                shell)
 {
   char *buffer;
-  int buffer_size;
+  size_t buffer_size;
   char *s;
   int ch;
   
@@ -125,10 +136,11 @@ int shell;
  *
  * the caller is expected to release share & subdir
  */
-void parsesharename (disk, share, subdir)
-char *disk;
-char **share;
-char **subdir;
+void
+parsesharename(
+    char *     disk,
+    char **    share,
+    char **    subdir)
 {
     char *ch=NULL;
     int slashcnt=0;
index 26966993b9935a2e0ff3e2424d9889b4d1be4789..3b5b9077655b4e8898d696cf5a6029f89d1d67c7 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: findpass.h,v 1.6 2001/08/01 22:37:32 jrjackson Exp $
+ * $Id: findpass.h,v 1.7 2006/05/25 01:47:11 johnfranks Exp $
  *
  * interface to findpass module
  */
@@ -33,8 +33,8 @@
 
 #include "amanda.h"
 
-extern char *findpass P((char *disk, char **domain));
-extern char *makesharename P((char *disk, int shell));
-void parsesharename P((char *disk, char **share, char **subdir));
+extern char *findpass(char *disk, char **domain);
+extern char *makesharename(char *disk, int shell);
+void parsesharename(char *disk, char **share, char **subdir);
 
 #endif
index 516cf4eed228abafea1d7b3cabbd4e884c98bac5..d29953bd0efe181d4336ad1da9d13675c0a54adb 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: getfsent.c,v 1.34 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: getfsent.c,v 1.38 2006/07/19 17:41:14 martinea Exp $
  *
  * generic version of code to read fstab
  */
 #ifdef TEST
 #  include <stdio.h>
 #  include <sys/types.h>
-#  undef P
-#  define P(x) x
 #endif
 
 #include "getfsent.h"
 
-static char *dev2rdev P((char *));
-static int samefile P((struct stat[3], struct stat *));
+static char *dev2rdev(char *);
 
 /*
  * You are in a twisty maze of passages, all alike.
@@ -56,19 +53,22 @@ static int samefile P((struct stat[3], struct stat *));
 
 #include <fstab.h>
 
-int open_fstab()
+int
+open_fstab(void)
 {
     return setfsent();
 }
 
-void close_fstab()
+void
+close_fstab(void)
 {
     endfsent();
 }
 
 
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+    generic_fsent_t *  fsent)
 {
     struct fstab *sys_fsent = getfsent();
     static char *xfsname = NULL, *xmntdir = NULL;
@@ -106,24 +106,28 @@ generic_fsent_t *fsent;
 
 static FILE *fstabf = NULL;
 
-int open_fstab()
+int
+open_fstab(void)
 {
     close_fstab();
     return (fstabf = fopen(VFSTAB, "r")) != NULL;
 }
 
-void close_fstab()
+void
+close_fstab(void)
 {
     if(fstabf)
        afclose(fstabf);
     fstabf = NULL;
 }
 
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+    generic_fsent_t *  fsent)
 {
     struct vfstab sys_fsent;
 
+    memset(&sys_fsent, 0, SIZEOF(sys_fsent));
     if(getvfsent(fstabf, &sys_fsent) != 0)
        return 0;
 
@@ -156,7 +160,8 @@ static FILE *fstabf1 = NULL;                /* /proc/mounts */
 static FILE *fstabf2 = NULL;           /* MOUNTED */
 static FILE *fstabf3 = NULL;           /* MNTTAB */
 
-int open_fstab()
+int
+open_fstab(void)
 {
     close_fstab();
 #if defined(HAVE_SETMNTENT)
@@ -175,7 +180,8 @@ int open_fstab()
     return (fstabf1 != NULL || fstabf2 != NULL || fstabf3 != NULL);
 }
 
-void close_fstab()
+void
+close_fstab(void)
 {
     if (fstabf1) {
        AMCLOSE_MNTENT(fstabf1);
@@ -191,8 +197,9 @@ void close_fstab()
     }
 }
 
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+    generic_fsent_t *  fsent)
 {
     struct mntent *sys_fsent = NULL;
 
@@ -245,13 +252,15 @@ generic_fsent_t *fsent;
 
 static FILE *fstabf = NULL;
 
-int open_fstab()
+int
+open_fstab(void)
 {
     close_fstab();
     return (fstabf = fopen(FSTAB, "r")) != NULL;
 }
 
-void close_fstab()
+void
+close_fstab(void)
 {
     if(fstabf)
        afclose(fstabf);
@@ -260,8 +269,9 @@ void close_fstab()
 
 static generic_fsent_t _fsent;
 
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+    generic_fsent_t *  fsent)
 {
     static char *lfsnam = NULL;
     static char *opts = NULL;
@@ -271,6 +281,8 @@ generic_fsent_t *fsent;
 
     amfree(cp);
     for (; (cp = agets(fstabf)) != NULL; free(cp)) {
+       if (cp[0] == '\0')
+           continue;
        fsent->fsname = strtok(cp, " \t");
        if ( fsent->fsname && *fsent->fsname != '#' )
            break;
@@ -303,7 +315,7 @@ generic_fsent_t *fsent;
     fsent->fstype = lfsnam;
 
 #define sc "hs"
-    if (strncmp(fsent->fstype, sc, sizeof(sc)-1) == 0)
+    if (strncmp(fsent->fstype, sc, SIZEOF(sc)-1) == 0)
        fsent->fstype = "iso9660";
 #undef sc
 
@@ -333,13 +345,15 @@ generic_fsent_t *fsent;
 
 static FILE *fstabf = NULL;
 
-int open_fstab()
+int
+open_fstab(void)
 {
     close_fstab();
     return (fstabf = fopen(MNTTAB, "r")) != NULL;
 }
 
-void close_fstab()
+void
+close_fstab(void)
 {
     if(fstabf)
        afclose(fstabf);
@@ -348,22 +362,23 @@ void close_fstab()
 
 static generic_fsent_t _fsent;
 
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+    generic_fsent_t *fsent)
 {
     struct statfs fsd;
     char typebuf[FSTYPSZ];
     static struct mnttab mnt;
     char *dp, *ep;
 
-    if(!fread (&mnt, sizeof mnt, 1, fstabf))
+    if(!fread (&mnt, SIZEOF(mnt), 1, fstabf))
       return 0;
 
     fsent->fsname  = mnt.mt_dev;
     fsent->mntdir  = mnt.mt_filsys;
     fsent->fstype = "";
 
-    if (statfs (fsent->mntdir, &fsd, sizeof fsd, 0) != -1
+    if (statfs (fsent->mntdir, &fsd, SIZEOF(fsd), 0) != -1
         && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) {
        dp = typebuf;
        ep = fsent->fstype = malloc(strlen(typebuf)+2);
@@ -411,8 +426,9 @@ generic_fsent_t *fsent;
  *=====================================================================
  */
 
-static char *dev2rdev(name)
-char *name;
+static char *
+dev2rdev(
+    char *     name)
 {
   char *fname = NULL;
   struct stat st;
@@ -443,7 +459,7 @@ char *name;
     if (ch == '/') {
       s[-1] = '\0';
       fname = newvstralloc(fname, name, "/r", s, NULL);
-      s[-1] = ch;
+      s[-1] = (char)ch;
       if(stat(fname, &st) == 0 && S_ISCHR(st.st_mode)) return fname;
     }
     ch = *s++;
@@ -452,8 +468,13 @@ char *name;
   return stralloc(name);                       /* no match */
 }
 
-static int samefile(stats, estat)
-struct stat stats[3], *estat;
+#ifndef IGNORE_FSTAB
+static int samefile(struct stat[3], struct stat *);
+
+static int
+samefile(
+    struct stat stats[3],
+    struct stat *estat)
 {
   int i;
   for(i = 0; i < 3; ++i) {
@@ -463,16 +484,21 @@ struct stat stats[3], *estat;
   }
   return 0;
 }
+#endif /* !IGNORE_FSTAB */
 
-int search_fstab(name, fsent, check_dev)
-     char *name;
-     generic_fsent_t *fsent;
-     int check_dev;
+int
+search_fstab(
+     char *            name,
+     generic_fsent_t * fsent,
+     int               check_dev)
 {
 #ifdef IGNORE_FSTAB
   /* There is no real mount table so this will always fail and
    * we are using GNU tar so we can just return here.
    */
+  (void)name;          /* Quiet unused parameter warning */
+  (void)fsent;         /* Quiet unused parameter warning */
+  (void)check_dev;     /* Quiet unused parameter warning */
   return 0;
 #else
   struct stat stats[3];
@@ -483,21 +509,22 @@ int search_fstab(name, fsent, check_dev)
   if (!name)
     return 0;
 
-  stats[0].st_dev = stats[1].st_dev = stats[2].st_dev = -1;
+  memset(stats, 0, SIZEOF(stats));
+  stats[0].st_dev = stats[1].st_dev = stats[2].st_dev = (dev_t)-1;
 
   if (stat(name, &stats[0]) == -1)
-    stats[0].st_dev = -1;
+    stats[0].st_dev = (dev_t)-1;
   if (name[0] != '/') {
     fullname = stralloc2(DEV_PREFIX, name);
     if (stat(fullname, &stats[1]) == -1)
-      stats[1].st_dev = -1;
+      stats[1].st_dev = (dev_t)-1;
     fullname = newstralloc2(fullname, RDEV_PREFIX, name);
     if (stat(fullname, &stats[2]) == -1)
-      stats[2].st_dev = -1;
+      stats[2].st_dev = (dev_t)-1;
     amfree(fullname);
   }
   else if (stat((rdev = dev2rdev(name)), &stats[1]) == -1)
-    stats[1].st_dev = -1;
+    stats[1].st_dev = (dev_t)-1;
 
   amfree(rdev);
 
@@ -543,8 +570,9 @@ int search_fstab(name, fsent, check_dev)
 #endif /* !IGNORE_FSTAB */
 }
 
-int is_local_fstype(fsent)
-generic_fsent_t *fsent;
+int
+is_local_fstype(
+    generic_fsent_t *  fsent)
 {
     if(fsent->fstype == NULL)  /* unknown, assume local */
        return 1;
@@ -560,8 +588,9 @@ generic_fsent_t *fsent;
 }
 
 
-char *amname_to_devname(str)
-char *str;
+char *
+amname_to_devname(
+    char *     str)
 {
     generic_fsent_t fsent;
 
@@ -573,8 +602,9 @@ char *str;
     return dev2rdev(str);
 }
 
-char *amname_to_dirname(str)
-char *str;
+char *
+amname_to_dirname(
+    char *     str)
 {
     generic_fsent_t fsent;
 
@@ -586,8 +616,8 @@ char *str;
     return stralloc(str);
 }
 
-char *amname_to_fstype(str)
-char *str;
+char *amname_to_fstype(
+    char *     str)
 {
     generic_fsent_t fsent;
 
@@ -599,9 +629,11 @@ char *str;
 
 #ifdef TEST
 
+void print_entry(generic_fsent_t *fsent);
+
 void
-print_entry(fsent)
-generic_fsent_t *fsent;
+print_entry(
+    generic_fsent_t *  fsent)
 {
 #define nchk(s)        ((s)? (s) : "<NULL>")
     printf("%-20.20s %-14.14s %-7.7s %4d %5d %s\n",
@@ -609,9 +641,10 @@ generic_fsent_t *fsent;
           fsent->freq, fsent->passno, nchk(fsent->mntopts));
 }
 
-int main(argc, argv)
-    int argc;
-    char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     generic_fsent_t fsent;
     char *s;
@@ -623,6 +656,8 @@ int main(argc, argv)
 
     set_pname("getfsent");
 
+    dbopen(NULL);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
index a8b37b00c8d85783023e6d7a95ef0edf14ff05d8..6b857bf3602396ddf2b3b369ad8f71734f2ea1c7 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: getfsent.h,v 1.7 2002/10/27 22:58:33 martinea Exp $
+ * $Id: getfsent.h,v 1.8 2006/05/25 01:47:11 johnfranks Exp $
  *
  * interfaces for obtaining filesystem information
  */
@@ -50,16 +50,16 @@ typedef struct generic_fsent_s {
     int passno;
 } generic_fsent_t;
 
-int open_fstab P((void));
-void close_fstab P((void));
+int open_fstab(void);
+void close_fstab(void);
 
-int get_fstab_nextentry P((generic_fsent_t *fsent));
-int search_fstab P((char *name, generic_fsent_t *fsent, int check_dev));
-int is_local_fstype P((generic_fsent_t *fsent));
+int get_fstab_nextentry(generic_fsent_t *fsent);
+int search_fstab(char *name, generic_fsent_t *fsent, int check_dev);
+int is_local_fstype(generic_fsent_t *fsent);
 
-char *amname_to_devname P((char *str));
-char *amname_to_dirname P((char *str));
+char *amname_to_devname(char *str);
+char *amname_to_dirname(char *str);
 
-char *amname_to_fstype P((char *str));
+char *amname_to_fstype(char *str);
 
 #endif /* ! GETFSENT_H */
index 1837409f96461ab6502601f651ced7cf0977feb4..3777d7d9ef342a7a89ba24ddbb87b9115fb06e5c 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: killpgrp.c,v 1.12 2005/09/20 21:32:25 jrjackson Exp $
+ * $Id: killpgrp.c,v 1.17 2006/07/25 18:27:56 martinea Exp $
  *
  * if it is the process group leader, it kills all processes in its
  * process group when it is killed itself.
+ *
+ * argv[0] is the killpgrp program name
+ * argv[1] is the config name or NOCONFIG
+ *
  */
 #include "amanda.h"
 #include "version.h"
 #define AM_GETPGRP() getpid()
 #endif
  
-int main P((int argc, char **argv));
-static void term_kill_soft P((int sig));
-static void term_kill_hard P((int sig));
+int main(int argc, char **argv);
+static void term_kill_soft(int sig);
+static void term_kill_hard(int sig);
 
-int main(argc, argv)
-int argc;
-char **argv;
+int main(
+    int argc,
+    char **argv)
 {
+    int ch;
     amwait_t status;
 
     safe_fd(-1, 0);
@@ -58,19 +63,30 @@ char **argv;
 
     set_pname("killpgrp");
 
-    dbopen();
-    dbprintf(("%s: version %s\n", argv[0], version()));
+    dbopen(DBG_SUBDIR_CLIENT);
+    if (argc < 2) {
+       error("%s: Need at least 2 arguments\n", debug_prefix(NULL));
+       /*NOTREACHED*/
+    }
+    dbprintf(("%s: version %s\n", debug_prefix(NULL), version()));
+    dbprintf(("config: %s\n", argv[1]));
+    if (strcmp(argv[1], "NOCONFIG") != 0)
+       dbrename(argv[1], DBG_SUBDIR_CLIENT);
 
     if(client_uid == (uid_t) -1) {
        error("error [cannot find user %s in passwd file]", CLIENT_LOGIN);
+       /*NOTREACHED*/
     }
 
 #ifdef FORCE_USERID
-    if (getuid() != client_uid)
+    if (getuid() != client_uid) {
        error("error [must be invoked by %s]", CLIENT_LOGIN);
-
-    if (geteuid() != 0)
+       /*NOTREACHED*/
+    }
+    if (geteuid() != 0) {
        error("error [must be setuid root]");
+       /*NOTREACHED*/
+    }
 #endif /* FORCE_USERID */
 
 #if !defined (DONT_SUID_ROOT)
@@ -79,13 +95,16 @@ char **argv;
 
     if (AM_GETPGRP() != getpid()) {
        error("error [must be the process group leader]");
+       /*NOTREACHED*/
     }
 
+    /* Consume any extranious input */
     signal(SIGTERM, term_kill_soft);
 
-    while (getchar() != EOF) {
+    do {
+       ch = getchar();
        /* wait until EOF */
-    }
+    } while (ch != EOF);
 
     term_kill_soft(0);
 
@@ -94,21 +113,25 @@ char **argv;
            break;
        if (errno != EINTR) {
            error("error [wait() failed: %s]", strerror(errno));
-           return -1;
+           /*NOTREACHED*/
        }
     }
 
+    /*@ignore@*/
     dbprintf(("child process exited with status %d\n", WEXITSTATUS(status)));
 
     return WEXITSTATUS(status);
+    /*@end@*/
 }
 
-static void term_kill_soft(sig)
-int sig;
+static void term_kill_soft(
+    int sig)
 {
     pid_t dumppid = getpid();
     int killerr;
 
+    (void)sig; /* Quiet unused parameter warning */
+
     signal(SIGTERM, SIG_IGN);
     signal(SIGALRM, term_kill_hard);
     alarm(3);
@@ -123,12 +146,14 @@ int sig;
     }
 }
 
-static void term_kill_hard(sig)
-int sig;
+static void term_kill_hard(
+    int sig)
 {
     pid_t dumppid = getpid();
     int killerr;
 
+    (void)sig; /* Quiet unused parameter warning */
+
     dbprintf(("it won\'t die with SIGTERM, but SIGKILL should do\n"));
     dbprintf(("do\'t expect any further output, this will be suicide\n"));
     killerr = kill(-dumppid, SIGKILL);
index 3700852b8753991aa9d81145339842dab3dfa440..a0c4105abcf3e41c958f029a075e50078dc36123 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*
- * $Id: noop.c,v 1.3 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: noop.c,v 1.5 2006/06/01 14:54:39 martinea Exp $
  *
  * send back features.  This was pulled out to it's own program for
  * consistancy and because it's a hell of a lot easier to code in
 #include "amfeatures.h"
 #include "util.h"
 
-int main P((int argc, char **argv));
+int main(int argc, char **argv);
 
 int
-main(argc, argv)
-    int argc;
-    char **argv;
+main(
+    int                argc,
+    char **    argv)
 {
     char ch;
     am_feature_t *our_features = NULL;
     char *our_feature_string = NULL;
     char *options;
-    int n;
+    ssize_t n;
+
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
 
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
+    safe_fd(-1, 0);
     do {
        /* soak up any stdin */
        n = read(0, &ch, 1);
@@ -67,7 +71,11 @@ main(argc, argv)
     our_features = NULL;
     if (fullwrite(1, options, strlen(options)) < 0) {
        error("error sending noop response: %s", strerror(errno));
+       /*NOTREACHED*/
     }
     amfree(options);
-    exit(0);
+    close(0);
+    close(1);
+    close(2);
+    return (0); /* exit */
 }
index a2d7cfbc40c7ba966ffccfd7bb9c8adaedf238b0..f96f72e3a1f83524299b9d516dd048d5934439b4 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! @SHELL@
 #
 # patch inetd.conf and services
 # originally by Axel Zinser (fifi@hiss.han.de)
index 347da0a356e4c27ea914b0125d91e2ef0b616abf..f42ed27803695f0f98894bd88e531a1337a5512c 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: rundump.c,v 1.28 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: rundump.c,v 1.33 2006/07/25 18:27:56 martinea Exp $
  *
  * runs DUMP program as root
+ *
+ * argv[0] is the rundump program name
+ * argv[1] is the config name or NOCONFIG
+ * argv[2] will be argv[0] of the DUMP program
+ * ...
  */
 #include "amanda.h"
 #include "version.h"
 
-int main P((int argc, char **argv));
+int main(int argc, char **argv);
 
 #if defined(VDUMP) || defined(XFSDUMP)
 #  undef USE_RUNDUMP
@@ -48,9 +53,10 @@ int main P((int argc, char **argv));
 #  endif
 #endif
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
 #ifndef ERRMSG
     char *dump_program;
@@ -66,8 +72,13 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-    dbopen();
-    dbprintf(("%s: version %s\n", argv[0], version()));
+    dbopen(DBG_SUBDIR_CLIENT);
+    if (argc < 3) {
+       error("%s: Need at least 3 arguments\n", debug_prefix(NULL));
+       /*NOTREACHED*/
+    }
+
+    dbprintf(("%s: version %s\n", debug_prefix(NULL), version()));
 
 #ifdef ERRMSG                                                  /* { */
 
@@ -80,20 +91,35 @@ char **argv;
 
     if(client_uid == (uid_t) -1) {
        error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+       /*NOTREACHED*/
     }
 
 #ifdef FORCE_USERID
-    if (getuid() != client_uid)
+    if (getuid() != client_uid) {
        error("error [must be invoked by %s]\n", CLIENT_LOGIN);
+       /*NOTREACHED*/
+    }
 
-    if (geteuid() != 0)
+    if (geteuid() != 0) {
        error("error [must be setuid root]\n");
+       /*NOTREACHED*/
+    }
 #endif /* FORCE_USERID */
 
 #if !defined (DONT_SUID_ROOT)
     setuid(0);
 #endif
 
+    /* skip argv[0] */
+    argc--;
+    argv++;
+
+    dbprintf(("config: %s\n", argv[0]));
+    if (strcmp(argv[0], "NOCONFIG") != 0)
+       dbrename(argv[0], DBG_SUBDIR_CLIENT);
+    argc--;
+    argv++;
+
 #ifdef XFSDUMP
 
     if (strcmp(argv[0], "xfsdump") == 0)
index d24352bd907f7a31c1dc195f21f59e80e3ce8c39..5d46111850c967efd9f1ed562b5d088e46ffde1c 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: runtar.c,v 1.17 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: runtar.c,v 1.24 2006/08/25 11:41:31 martinea Exp $
  *
  * runs GNUTAR program as root
+ *
+ * argv[0] is the runtar program name
+ * argv[1] is the config name or NOCONFIG
+ * argv[2] will be argv[0] of the gtar program
+ * ...
  */
 #include "amanda.h"
 #include "version.h"
+#include "util.h"
 
-int main P((int argc, char **argv));
+int main(int argc, char **argv);
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
 #ifdef GNUTAR
     int i;
@@ -51,8 +58,19 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-    dbopen();
-    dbprintf(("%s: version %s\n", argv[0], version()));
+    dbopen(DBG_SUBDIR_CLIENT);
+    if (argc < 3) {
+       error("%s: Need at least 3 arguments\n", debug_prefix(NULL));
+       /*NOTREACHED*/
+    }
+
+    dbprintf(("%s: version %s\n", debug_prefix(NULL), version()));
+
+    if (strcmp(argv[3], "--create") != 0) {
+       error("%s: Can only be used to create tar archives\n",
+             debug_prefix(NULL));
+       /*NOTREACHED*/
+    }
 
 #ifndef GNUTAR
 
@@ -63,25 +81,68 @@ char **argv;
 
 #else
 
+    /*
+     * Print out version information for tar.
+     */
+    do {
+       FILE *  version_file;
+       char    version_buf[80];
+
+       if ((version_file = popen(GNUTAR " --version 2>&1", "r")) != NULL) {
+           if (fgets(version_buf, (int)sizeof(version_buf), version_file) != NULL) {
+               dbprintf((GNUTAR " version: %s\n", version_buf));
+           } else {
+               if (ferror(version_file)) {
+                   dbprintf((GNUTAR " version: Read failure: %s\n", strerror(errno)));
+               } else {
+                   dbprintf((GNUTAR " version: Read failure; EOF\n"));
+               }
+           }
+       } else {
+           dbprintf((GNUTAR " version: unavailable: %s\n", strerror(errno)));
+       }
+    } while(0);
+
     if(client_uid == (uid_t) -1) {
        error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+       /*NOTREACHED*/
     }
 
 #ifdef FORCE_USERID
-    if (getuid() != client_uid)
+    if (getuid() != client_uid) {
        error("error [must be invoked by %s]\n", CLIENT_LOGIN);
+       /*NOTREACHED*/
+    }
 
-    if (geteuid() != 0)
+    if (geteuid() != 0) {
        error("error [must be setuid root]\n");
+       /*NOTREACHED*/
+    }
 #endif
 
 #if !defined (DONT_SUID_ROOT)
     setuid(0);
 #endif
 
+    /* skip argv[0] */
+    argc--;
+    argv++;
+
+    dbprintf(("config: %s\n", argv[0]));
+    if (strcmp(argv[0], "NOCONFIG") != 0)
+       dbrename(argv[0], DBG_SUBDIR_CLIENT);
+    argc--;
+    argv++;
+
+
     dbprintf(("running: %s: ",GNUTAR));
-    for (i=0; argv[i]; i++)
-       dbprintf(("%s ", argv[i]));
+    for (i=0; argv[i]; i++) {
+       char *quoted;
+
+       quoted = quote_string(argv[i]);
+       dbprintf(("'%s' ", quoted));
+       amfree(quoted);
+    }
     dbprintf(("\n"));
     dbf = dbfn();
     if (dbf) {
index 44584c90c0135ebd3245dc96ec96bb402e500b35..e5b486e4ec6050c741de358a10f8b21db453b986 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /* 
- * $Id: selfcheck.c,v 1.76 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: selfcheck.c,v 1.95 2006/08/29 11:21:00 martinea Exp $
  *
  * do self-check and send back any error messages
  */
@@ -40,6 +40,8 @@
 #include "pipespawn.h"
 #include "amfeatures.h"
 #include "client_util.h"
+#include "clientconf.h"
+#include "amandad.h"
 
 #ifdef SAMBA_CLIENT
 #include "findpass.h"
@@ -61,39 +63,46 @@ int need_compress_path=0;
 int need_calcsize=0;
 int program_is_wrapper=0;
 
+static char *amandad_auth = NULL;
 static am_feature_t *our_features = NULL;
 static char *our_feature_string = NULL;
 static g_option_t *g_options = NULL;
 
 /* local functions */
-int main P((int argc, char **argv));
-
-static void check_options P((char *program, char *calcprog, char *disk, char *amdevice, option_t *options));
-static void check_disk P((char *program, char *calcprog, char *disk, char *amdevice, int level, char *optstr));
-static void check_overall P((void));
-static void check_access P((char *filename, int mode));
-static void check_file P((char *filename, int mode));
-static void check_dir P((char *dirname, int mode));
-static void check_suid P((char *filename));
-static void check_space P((char *dir, long kbytes));
-
-int main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv);
+
+static void check_options(char *program, char *calcprog, char *disk, char *amdevice, option_t *options);
+static void check_disk(char *program, char *calcprog, char *disk, char *amdevice, int level, char *optstr);
+static void check_overall(void);
+static void check_access(char *filename, int mode);
+static void check_file(char *filename, int mode);
+static void check_dir(char *dirname, int mode);
+static void check_suid(char *filename);
+static void check_space(char *dir, off_t kbytes);
+
+int
+main(
+    int                argc,
+    char **    argv)
 {
     int level;
     char *line = NULL;
     char *program = NULL;
     char *calcprog = NULL;
     char *disk = NULL;
+    char *qdisk = NULL;
     char *amdevice = NULL;
+    char *qamdevice = NULL;
     char *optstr = NULL;
     char *err_extra = NULL;
     char *s, *fp;
+    char *conffile;
+    option_t *options;
     int ch;
+#if defined(USE_DBMALLOC)
     unsigned long malloc_hist_1, malloc_size_1;
     unsigned long malloc_hist_2, malloc_size_2;
-    option_t *options;
+#endif
 
     /* initialize */
 
@@ -105,21 +114,40 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
+#if defined(USE_DBMALLOC)
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
+#endif
 
     erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
-    dbopen();
+    dbopen(DBG_SUBDIR_CLIENT);
     startclock();
     dbprintf(("%s: version %s\n", get_pname(), version()));
 
+    if(argc > 2 && strcmp(argv[1], "amandad") == 0) {
+       amandad_auth = stralloc(argv[2]);
+    }
+
+    conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+    if (read_clientconf(conffile) > 0) {
+       printf("ERROR [reading conffile: %s]\n", conffile);
+       error("error reading conffile: %s", conffile);
+       /*NOTREACHED*/
+    }
+    amfree(conffile);
+
     our_features = am_init_feature_set();
     our_feature_string = am_feature_to_string(our_features);
 
     /* handle all service requests */
 
+    /*@ignore@*/
     for(; (line = agets(stdin)) != NULL; free(line)) {
+    /*@end@*/
+       if (line[0] == '\0')
+           continue;
+
 #define sc "OPTIONS "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
 #undef sc
            g_options = parse_g_options(line+8, 1);
            if(!g_options->hostname) {
@@ -137,6 +165,20 @@ char **argv;
            }
            printf("\n");
            fflush(stdout);
+
+           if (g_options->config) {
+               conffile = vstralloc(CONFIG_DIR, "/", g_options->config, "/",
+                                    "amanda-client.conf", NULL);
+               if (read_clientconf(conffile) > 0) {
+                   printf("ERROR [reading conffile: %s]\n", conffile);
+                   error("error reading conffile: %s", conffile);
+                   /*NOTREACHED*/
+               }
+               amfree(conffile);
+
+               dbrename(g_options->config, DBG_SUBDIR_CLIENT);
+           }
+
            continue;
        }
 
@@ -180,9 +222,10 @@ char **argv;
        if (ch == '\0') {
            goto err;                           /* no disk */
        }
-       disk = s - 1;
-       skip_non_whitespace(s, ch);
+       qdisk = s - 1;
+       skip_quoted_string(s, ch);
        s[-1] = '\0';                           /* terminate the disk name */
+       disk = unquote_string(qdisk);
 
        skip_whitespace(s, ch);                 /* find the device or level */
        if (ch == '\0') {
@@ -190,9 +233,10 @@ char **argv;
        }
        if(!isdigit((int)s[-1])) {
            fp = s - 1;
-           skip_non_whitespace(s, ch);
+           skip_quoted_string(s, ch);
             s[-1] = '\0';                      /* terminate the device */
-           amdevice = stralloc(fp);
+           qamdevice = stralloc(fp);
+           amdevice = unquote_string(qamdevice);
            skip_whitespace(s, ch);             /* find level number */
        }
        else {
@@ -207,8 +251,8 @@ char **argv;
 
        skip_whitespace(s, ch);
 #define sc "OPTIONS "
-       if (ch && strncmp (s - 1, sc, sizeof(sc)-1) == 0) {
-           s += sizeof(sc)-1;
+       if (ch && strncmp (s - 1, sc, SIZEOF(sc)-1) == 0) {
+           s += SIZEOF(sc)-1;
            ch = s[-1];
 #undef sc
            skip_whitespace(s, ch);             /* find the option string */
@@ -216,11 +260,13 @@ char **argv;
                goto err;                       /* bad options string */
            }
            optstr = s - 1;
-           skip_non_whitespace(s, ch);
+           skip_quoted_string(s, ch);
            s[-1] = '\0';                       /* terminate the options */
            options = parse_options(optstr, disk, amdevice, g_options->features, 1);
+           /*@ignore@*/
            check_options(program, calcprog, disk, amdevice, options);
            check_disk(program, calcprog, disk, amdevice, level, &optstr[2]);
+           /*@end@*/
            free_sl(options->exclude_file);
            free_sl(options->exclude_list);
            free_sl(options->include_file);
@@ -244,10 +290,13 @@ char **argv;
            need_gnutar=1;
            need_compress_path=1;
            need_calcsize=1;
+           /*@ignore@*/
            check_disk(program, calcprog, disk, amdevice, level, "");
+           /*@end@*/
        } else {
            goto err;                           /* bad syntax */
        }
+       amfree(disk);
        amfree(amdevice);
     }
 
@@ -263,15 +312,15 @@ char **argv;
     amfree(g_options->hostname);
     amfree(g_options);
 
+#if defined(USE_DBMALLOC)
     malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
     if(malloc_size_1 != malloc_size_2) {
-#if defined(USE_DBMALLOC)
        extern int dbfd;
 
        malloc_list(dbfd(), malloc_hist_1, malloc_hist_2);
-#endif
     }
+#endif
 
     dbclose();
     return 0;
@@ -288,9 +337,12 @@ char **argv;
 
 
 static void
-check_options(program, calcprog, disk, amdevice, options)
-    char *program, *calcprog, *disk, *amdevice;
-    option_t *options;
+check_options(
+    char *     program,
+    char *     calcprog,
+    char *     disk,
+    char *     amdevice,
+    option_t * options)
 {
     char *myprogram = program;
 
@@ -312,7 +364,11 @@ check_options(program, calcprog, disk, amdevice, options)
        amfree(file_include);
 
        need_calcsize=1;
-       myprogram = calcprog;
+       if (calcprog == NULL) {
+           printf("ERROR [no program name for calcsize]\n");
+       } else {
+           myprogram = calcprog;
+       }
     }
 
     if(strcmp(myprogram,"GNUTAR") == 0) {
@@ -425,27 +481,45 @@ check_options(program, calcprog, disk, amdevice, options)
            need_restore=1;
 #endif
     }
-    if(program_is_wrapper==1) {
-    }
-    if(options->compress == COMPR_BEST || options->compress == COMPR_FAST || options->compress == COMPR_CUST)
+    if ((options->compress == COMPR_BEST) || (options->compress == COMPR_FAST) 
+               || (options->compress == COMPR_CUST)) {
        need_compress_path=1;
+    }
+    if(options->auth && amandad_auth) {
+       if(strcasecmp(options->auth, amandad_auth) != 0) {
+           fprintf(stdout,"ERROR [client configured for auth=%s while server requested '%s']\n",
+                   amandad_auth, options->auth);
+       }
+    }
 }
 
-static void check_disk(program, calcprog, disk, amdevice, level, optstr)
-char *program, *calcprog, *disk, *amdevice;
-int level;
-char *optstr;
+static void
+check_disk(
+    char *     program,
+    char *     calcprog,
+    char *     disk,
+    char *     amdevice,
+    int                level,
+    char *     optstr)
 {
-    char *device = NULL;
+    char *device = stralloc("nodevice");
     char *err = NULL;
-    char *user_and_password = NULL, *domain = NULL;
+    char *user_and_password = NULL;
+    char *domain = NULL;
     char *share = NULL, *subdir = NULL;
-    int lpass = 0;
+    size_t lpass = 0;
     int amode;
     int access_result;
     char *access_type;
     char *extra_info = NULL;
     char *myprogram = program;
+    char *qdisk = quote_string(disk);
+    char *qamdevice = quote_string(amdevice);
+    char *qdevice = NULL;
+
+    (void)level;       /* Quiet unused parameter warning */
+
+    dbprintf(("%s: checking disk %s\n", debug_prefix_time(NULL), qdisk));
 
     if(strcmp(myprogram,"CALCSIZE") == 0) {
        if(amdevice[0] == '/' && amdevice[1] == '/') {
@@ -458,19 +532,17 @@ char *optstr;
        myprogram = calcprog;
     }
 
-    dbprintf(("%s: checking disk %s\n", debug_prefix_time(NULL), disk));
-
-    if (strcmp(myprogram, "GNUTAR") == 0) {
+    if (strcmp(myprogram, "GNUTAR")==0) {
         if(amdevice[0] == '/' && amdevice[1] == '/') {
 #ifdef SAMBA_CLIENT
            int nullfd, checkerr;
            int passwdfd;
            char *pwtext;
-           int pwtext_len;
-           int checkpid;
+           size_t pwtext_len;
+           pid_t checkpid;
            amwait_t retstat;
            char number[NUM_STR_SIZE];
-           int wpid;
+           pid_t wpid;
            int ret, sig, rc;
            char *line;
            char *sep;
@@ -500,7 +572,8 @@ char *optstr;
                goto common_exit;
            }
            *pwtext++ = '\0';
-           pwtext_len = strlen(pwtext);
+           pwtext_len = (size_t)strlen(pwtext);
+           amfree(device);
            if ((device = makesharename(share, 0)) == NULL) {
                err = stralloc2("cannot make share name of ", share);
                goto common_exit;
@@ -532,12 +605,11 @@ char *optstr;
 #endif
                                 "-c", "quit",
                                 NULL);
-           if (domain) {
-               memset(domain, '\0', strlen(domain));
-               amfree(domain);
-           }
+           amfree(domain);
            aclose(nullfd);
-           if (pwtext_len > 0 && fullwrite(passwdfd, pwtext, pwtext_len) < 0) {
+           /*@ignore@*/
+           if ((pwtext_len > 0)
+             && fullwrite(passwdfd, pwtext, (size_t)pwtext_len) < 0) {
                err = vstralloc("password write failed: ",
                                amdevice,
                                ": ",
@@ -546,13 +618,21 @@ char *optstr;
                aclose(passwdfd);
                goto common_exit;
            }
-           memset(user_and_password, '\0', lpass);
+           /*@end@*/
+           memset(user_and_password, '\0', (size_t)lpass);
            amfree(user_and_password);
            aclose(passwdfd);
            ferr = fdopen(checkerr, "r");
+           if (!ferr) {
+               printf("ERROR [Can't fdopen: %s]\n", strerror(errno));
+               error("Can't fdopen: %s", strerror(errno));
+               /*NOTREACHED*/
+           }
            sep = "";
            errdos = 0;
            for(sep = ""; (line = agets(ferr)) != NULL; free(line)) {
+               if (line[0] == '\0')
+                   continue;
                strappend(extra_info, sep);
                strappend(extra_info, line);
                sep = ": ";
@@ -579,7 +659,7 @@ char *optstr;
                    } else {
                        strappend(err, "returned ");
                    }
-                   snprintf(number, sizeof(number), "%d", ret);
+                   snprintf(number, (size_t)sizeof(number), "%d", ret);
                    strappend(err, number);
                }
            }
@@ -594,17 +674,18 @@ char *optstr;
                amfree(extra_info);
            }
 #else
-           err = stralloc2("This client is not configured for samba: ", disk);
+           err = stralloc2("This client is not configured for samba: ", qdisk);
 #endif
            goto common_exit;
        }
        amode = F_OK;
+       amfree(device);
        device = amname_to_dirname(amdevice);
     } else if (strcmp(program, "DUMP") == 0) {
        if(amdevice[0] == '/' && amdevice[1] == '/') {
            err = vstralloc("The DUMP program cannot handle samba shares,",
                            " use GNUTAR: ",
-                           disk,
+                           qdisk,
                            NULL);
            goto common_exit;
        }
@@ -615,11 +696,13 @@ char *optstr;
        if (1)
 #endif                                                                 /* } */
        {
+           amfree(device);
            device = amname_to_dirname(amdevice);
            amode = F_OK;
        } else
 #endif                                                                 /* } */
        {
+           amfree(device);
            device = amname_to_devname(amdevice);
 #ifdef USE_RUNDUMP
            amode = F_OK;
@@ -629,10 +712,14 @@ char *optstr;
        }
     }
     else { /* program_is_wrapper==1 */
-       int pid_wrapper;
+       pid_t pid_wrapper;
        fflush(stdout);fflush(stdin);
        switch (pid_wrapper = fork()) {
-       case -1: error("fork: %s", strerror(errno));
+       case -1:
+           printf("ERROR [fork: %s]\n", strerror(errno));
+           error("fork: %s", strerror(errno));
+           /*NOTREACHED*/
+
        case 0: /* child */
            {
                char *argvchild[6];
@@ -653,10 +740,14 @@ char *optstr;
            }
        }
        fflush(stdout);fflush(stdin);
+       amfree(device);
+       amfree(qamdevice);
+       amfree(qdisk);
        return;
     }
 
-    dbprintf(("%s: device %s\n", debug_prefix_time(NULL), device));
+    qdevice = quote_string(device);
+    dbprintf(("%s: device %s\n", debug_prefix_time(NULL), qdevice));
 
     /* skip accessability test if this is an AFS entry */
     if(strncmp(device, "afs:", 4) != 0) {
@@ -668,8 +759,8 @@ char *optstr;
        access_type = "access";
 #endif
        if(access_result == -1) {
-           err = vstralloc("could not ", access_type, " ", device,
-                       " (", disk, "): ", strerror(errno), NULL);
+           err = vstralloc("could not ", access_type, " ", qdevice,
+                       " (", qdisk, "): ", strerror(errno), NULL);
        }
 #ifdef CHECK_FOR_ACCESS_WITH_OPEN
        aclose(access_result);
@@ -681,41 +772,44 @@ common_exit:
     amfree(share);
     amfree(subdir);
     if(user_and_password) {
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
     }
-    if(domain) {
-       memset(domain, '\0', strlen(domain));
-       amfree(domain);
-    }
+    amfree(domain);
 
     if(err) {
        printf("ERROR [%s]\n", err);
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), err));
        amfree(err);
     } else {
-       printf("OK %s\n", disk);
-       dbprintf(("%s: disk \"%s\" OK\n", debug_prefix_time(NULL), disk));
-       printf("OK %s\n", amdevice);
-       dbprintf(("%s: amdevice \"%s\" OK\n",
-                 debug_prefix_time(NULL), amdevice));
-       printf("OK %s\n", device);
-       dbprintf(("%s: device \"%s\" OK\n", debug_prefix_time(NULL), device));
+       printf("OK %s\n", qdisk);
+       dbprintf(("%s: disk %s OK\n", debug_prefix_time(NULL), qdisk));
+       printf("OK %s\n", qamdevice);
+       dbprintf(("%s: amdevice %s OK\n",
+                 debug_prefix_time(NULL), qamdevice));
+       printf("OK %s\n", qdevice);
+       dbprintf(("%s: device %s OK\n", debug_prefix_time(NULL), qdevice));
     }
     if(extra_info) {
        dbprintf(("%s: extra info: %s\n", debug_prefix_time(NULL), extra_info));
        amfree(extra_info);
     }
+    amfree(qdisk);
+    amfree(qdevice);
+    amfree(qamdevice);
     amfree(device);
 
     /* XXX perhaps do something with level: read dumpdates and sanity check */
 }
 
-static void check_overall()
+static void
+check_overall(void)
 {
     char *cmd;
     struct stat buf;
     int testfd;
+    char *gnutar_list_dir;
+    int   need_amandates = 0;
 
     if( need_runtar )
     {
@@ -803,14 +897,19 @@ static void check_overall()
 #else
        printf("ERROR [GNUTAR program not available]\n");
 #endif
-#ifdef AMANDATES_FILE
-       check_file(AMANDATES_FILE, R_OK|W_OK);
-#endif
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
-       check_dir(GNUTAR_LISTED_INCREMENTAL_DIR,R_OK|W_OK);
-#endif
+       need_amandates = 1;
+       gnutar_list_dir = client_getconf_str(CLN_GNUTAR_LIST_DIR);
+       if (strlen(gnutar_list_dir) == 0)
+           gnutar_list_dir = NULL;
+       if (gnutar_list_dir) 
+           check_dir(gnutar_list_dir, R_OK|W_OK);
     }
 
+    if (need_amandates) {
+       char *amandates_file;
+       amandates_file = client_getconf_str(CLN_AMANDATES);
+       check_file(amandates_file, R_OK|W_OK);
+    }
     if( need_calcsize ) {
        char *cmd;
 
@@ -862,35 +961,44 @@ static void check_overall()
         check_file("/etc/vdumpdates", F_OK);
 
     check_access("/dev/null", R_OK|W_OK);
-    check_space(AMANDA_TMPDIR, 64);    /* for amandad i/o */
+    check_space(AMANDA_TMPDIR, (off_t)64);     /* for amandad i/o */
 
 #ifdef AMANDA_DBGDIR
-    check_space(AMANDA_DBGDIR, 64);    /* for amandad i/o */
+    check_space(AMANDA_DBGDIR, (off_t)64);     /* for amandad i/o */
 #endif
 
-    check_space("/var/lib", 64);       /* for /var/lib/dumpdates writing */
+    check_space("/var/lib", (off_t)64);        /* for /var/lib/dumpdates writing */
 }
 
-static void check_space(dir, kbytes)
-char *dir;
-long kbytes;
+static void
+check_space(
+    char *     dir,
+    off_t      kbytes)
 {
     generic_fs_stats_t statp;
-
-    if(get_fs_stats(dir, &statp) == -1)
-       printf("ERROR [cannot statfs %s: %s]\n", dir, strerror(errno));
-    else if(statp.avail < kbytes)
-       printf("ERROR [dir %s needs %ldKB, only has %ldKB available.]\n",
-              dir, kbytes, statp.avail);
-    else
-       printf("OK %s has more than %ld KB available.\n", dir, kbytes);
+    char *quoted = quote_string(dir);
+
+    if(get_fs_stats(dir, &statp) == -1) {
+       printf("ERROR [cannot statfs %s: %s]\n", quoted, strerror(errno));
+    } else if(statp.avail < kbytes) {
+       printf("ERROR [dir %s needs " OFF_T_FMT "KB, only has "
+               OFF_T_FMT "KB available.]\n", quoted,
+               (OFF_T_FMT_TYPE)kbytes,
+               (OFF_T_FMT_TYPE)statp.avail);
+    } else {
+       printf("OK %s has more than " OFF_T_FMT " KB available.\n",
+               quoted, (OFF_T_FMT_TYPE)kbytes);
+    }
+    amfree(quoted);
 }
 
-static void check_access(filename, mode)
-char *filename;
-int mode;
+static void
+check_access(
+    char *     filename,
+    int                mode)
 {
     char *noun, *adjective;
+    char *quoted = quote_string(filename);
 
     if(mode == F_OK)
         noun = "find", adjective = "exists";
@@ -902,34 +1010,44 @@ int mode;
        noun = "access", adjective = "accessible";
 
     if(access(filename, mode) == -1)
-       printf("ERROR [can not %s %s: %s]\n", noun, filename, strerror(errno));
+       printf("ERROR [can not %s %s: %s]\n", noun, quoted, strerror(errno));
     else
-       printf("OK %s %s\n", filename, adjective);
+       printf("OK %s %s\n", quoted, adjective);
+    amfree(quoted);
 }
 
-static void check_file(filename, mode)
-char *filename;
-int mode;
+static void
+check_file(
+    char *     filename,
+    int                mode)
 {
     struct stat stat_buf;
+    char *quoted;
+
     if(!stat(filename, &stat_buf)) {
        if(!S_ISREG(stat_buf.st_mode)) {
-           printf("ERROR [%s is not a file]\n", filename);
+           quoted = quote_string(filename);
+           printf("ERROR [%s is not a file]\n", quoted);
+           amfree(quoted);
        }
     }
     check_access(filename, mode);
 }
 
-static void check_dir(dirname, mode)
-char *dirname;
-int mode;
+static void
+check_dir(
+    char *     dirname,
+    int                mode)
 {
     struct stat stat_buf;
+    char *quoted;
     char *dir;
 
     if(!stat(dirname, &stat_buf)) {
        if(!S_ISDIR(stat_buf.st_mode)) {
-           printf("ERROR [%s is not a directory]\n", dirname);
+           quoted = quote_string(dirname);
+           printf("ERROR [%s is not a directory]\n", quoted);
+           amfree(quoted);
        }
     }
     dir = stralloc2(dirname, "/.");
@@ -937,22 +1055,28 @@ int mode;
     amfree(dir);
 }
 
-static void check_suid(filename)
-char *filename;
+static void
+check_suid(
+    char *     filename)
 {
 /* The following is only valid for real Unixs */
 #ifndef IGNORE_UID_CHECK
     struct stat stat_buf;
+    char *quoted = quote_string(filename);
+
     if(!stat(filename, &stat_buf)) {
        if(stat_buf.st_uid != 0 ) {
-           printf("ERROR [%s is not owned by root]\n",filename);
+           printf("ERROR [%s is not owned by root]\n", quoted);
        }
        if((stat_buf.st_mode & S_ISUID) != S_ISUID) {
-           printf("ERROR [%s is not SUID root]\n",filename);
+           printf("ERROR [%s is not SUID root]\n", quoted);
        }
     }
     else {
-       printf("ERROR [can not stat %s]\n",filename);
+       printf("ERROR [can not stat %s]\n", quoted);
     }
+    amfree(quoted);
+#else
+    (void)filename;    /* Quiet unused parameter warning */
 #endif
 }
index 9bda7ad1616989980f6fd98c859b1a2d2c64ce80..84a9d1091751bdbc02d66063666a75c5896750bf 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: sendbackup-dump.c,v 1.88 2006/03/09 20:06:11 johnfranks Exp $
+ * $Id: sendbackup-dump.c,v 1.90 2006/07/25 18:10:07 martinea Exp $
  *
  * send backup data using BSD dump
  */
 
+#include "amanda.h"
 #include "sendbackup.h"
 #include "getfsent.h"
 #include "clock.h"
@@ -36,7 +37,7 @@
 
 #define LEAF_AND_DIRS "sed -e \'\ns/^leaf[ \t]*[0-9]*[ \t]*\\.//\nt\n/^dir[ \t]/ {\ns/^dir[ \t]*[0-9]*[ \t]*\\.//\ns%$%/%\nt\n}\nd\n\'"
 
-static regex_t re_table[] = {
+static amregex_t re_table[] = {
   /* the various encodings of dump size */
   /* this should also match BSDI pre-3.0's buggy dump program, that
      produced doubled DUMP: DUMP: messages */
@@ -111,15 +112,24 @@ static regex_t re_table[] = {
   AM_STRANGE_RE(NULL)
 };
 
+static void start_backup(char *host, char *disk, char *amdevice, int level,
+               char *dumpdate, int dataf, int mesgf, int indexf);
+static void end_backup(int status);
+
 /*
  *  doing similar to $ dump | compression | encryption
  */
 
-static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, indexf)
-    char *host;
-    char *disk, *amdevice;
-    int level, dataf, mesgf, indexf;
-    char *dumpdate;
+static void
+start_backup(
+    char *     host,
+    char *     disk,
+    char *     amdevice,
+    int                level,
+    char *     dumpdate,
+    int                dataf,
+    int                mesgf,
+    int                indexf)
 {
     int dumpin, dumpout, compout;
     char *dumpkeys = NULL;
@@ -130,25 +140,33 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
     char level_str[NUM_STR_SIZE];
     char *compopt  = NULL;
     char *encryptopt = skip_argument;
+    char *qdisk;
+    char *config;
+
+    (void)dumpdate;    /* Quiet unused parameter warning */
 
+    snprintf(level_str, SIZEOF(level_str), "%d", level);
 
-    snprintf(level_str, sizeof(level_str), "%d", level);
+    qdisk = quote_string(disk);
+    dbprintf(("%s: start: %s:%s lev %d\n",
+             get_pname(), host, qdisk, level));
 
     fprintf(stderr, "%s: start [%s:%s level %d]\n",
-           get_pname(), host, disk, level);
+           get_pname(), host, qdisk, level);
+    amfree(qdisk);
 
-      /*  apply client-side encryption here */
-      if ( options->encrypt == ENCRYPT_CUST ) {
-       encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
+    /*  apply client-side encryption here */
+    if ( options->encrypt == ENCRYPT_CUST ) {
+        encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
                        &compout, &dataf, &mesgf,
                        options->clnt_encrypt, encryptopt, NULL);
-       dbprintf(("%s: pid %ld: %s\n",
+        dbprintf(("%s: pid %ld: %s\n",
                  debug_prefix_time("-gnutar"), (long)encpid, options->clnt_encrypt));
-     } else {
+    } else {
         compout = dataf;
         encpid = -1;
-     }
-      /*  now do the client-side compression */
+    }
+    /*  now do the client-side compression */
 
 
     if(options->compress == COMPR_FAST || options->compress == COMPR_BEST) {
@@ -195,8 +213,13 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
 
 #if defined(USE_RUNDUMP) || !defined(DUMP)
     cmd = vstralloc(libexecdir, "/", "rundump", versionsuffix(), NULL);
+    if (g_options->config)
+       config = g_options->config;
+    else
+       config = "NOCONFIG";
 #else
     cmd = stralloc(DUMP);
+    config = skip_argument;
 #endif
 
 #ifndef AIX_BACKUP                                     /* { */
@@ -210,6 +233,11 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
     {
         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
                                            versionsuffix(), NULL);
+       if (g_options->config)
+           config = g_options->config;
+       else
+           config = "NOCONFIG";
+
        program->backup_name  = XFSDUMP;
        program->restore_name = XFSRESTORE;
 
@@ -228,6 +256,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
        dumpkeys = stralloc(level_str);
        dumppid = pipespawn(progname, STDIN_PIPE,
                            &dumpin, &dumpout, &mesgf,
+                           config, /* JLM */
                            "xfsdump",
                            options->no_record ? "-J" : skip_argument,
                            "-F",
@@ -248,8 +277,13 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
 #ifdef USE_RUNDUMP
         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
                                            versionsuffix(), NULL);
+       if (g_options->config)
+           config = g_options->config;
+       else
+           config = "NOCONFIG";
 #else
        char *progname = cmd = newvstralloc(cmd, VXDUMP, NULL);
+       config = skip_argument;
 #endif
        program->backup_name  = VXDUMP;
        program->restore_name = VXRESTORE;
@@ -272,6 +306,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
 
        dumppid = pipespawn(progname, STDIN_PIPE,
                            &dumpin, &dumpout, &mesgf, 
+                           progname, config, /* JLM */
                            "vxdump",
                            dumpkeys,
                            "1048576",
@@ -291,6 +326,10 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
     {
         char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
                                            versionsuffix(), NULL);
+       if (g_options->config)
+           config = g_options->config;
+       else
+           config = "NOCONFIG";
        device = newstralloc(device, amname_to_dirname(amdevice));
        program->backup_name  = VDUMP;
        program->restore_name = VRESTORE;
@@ -313,6 +352,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
 
        dumppid = pipespawn(cmd, STDIN_PIPE,
                            &dumpin, &dumpout, &mesgf, 
+                           cmd, config,
                            "vdump",
                            dumpkeys,
                            "60",
@@ -350,6 +390,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
 
        dumppid = pipespawn(cmd, STDIN_PIPE,
                            &dumpin, &dumpout, &mesgf, 
+                           cmd, config,
                            "dump",
                            dumpkeys,
                            "1048576",
@@ -381,6 +422,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
 
     dumppid = pipespawn(cmd, STDIN_PIPE,
                        &dumpin, &dumpout, &mesgf, 
+                       cmd, config,
                        "backup",
                        dumpkeys,
                        "-",
@@ -405,9 +447,12 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
        aclose(indexf);
 }
 
-static void end_backup(status)
-int status;
+static void
+end_backup(
+    int                status)
 {
+    (void)status;      /* Quiet unused parameter warning */
+
     /* don't need to do anything for dump */
 }
 
index 720a31d4f3714278330313a0100024259f7cd8c4..5c7fe247ec6ef66b66fe47809688e7db1d28886c 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: sendbackup-gnutar.c,v 1.92 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: sendbackup-gnutar.c,v 1.98 2006/07/25 18:35:21 martinea Exp $
  *
  * send backup data using GNU tar
  */
 #include "util.h"
 #include "getfsent.h"                  /* for amname_to_dirname lookup */
 #include "version.h"
+#include "clientconf.h"
 
 #ifdef SAMBA_CLIENT
 #include "findpass.h"
 #endif
 
-static regex_t re_table[] = {
+static amregex_t re_table[] = {
   /* tar prints the size in bytes */
   AM_SIZE_RE("^ *Total bytes written: [0-9][0-9]*", 1),
   AM_NORMAL_RE("^Elapsed time:"),
@@ -123,17 +124,22 @@ int cur_level;
 char *cur_disk;
 time_t cur_dumptime;
 
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
+static char *gnutar_list_dir = NULL;
 static char *incrname = NULL;
-#endif
+static char *amandates_file;
 /*
  *  doing similar to $ gtar | compression | encryption 
  */
-static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, indexf)
-    char *host;
-    char *disk, *amdevice;
-    int level, dataf, mesgf, indexf;
-    char *dumpdate;
+static void
+start_backup(
+    char *     host,
+    char *     disk,
+    char *     amdevice,
+    int                level,
+    char *     dumpdate,
+    int                dataf,
+    int                mesgf,
+    int                indexf)
 {
     int dumpin, dumpout, compout;
     char *cmd = NULL;
@@ -147,21 +153,29 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
     char *error_pn = NULL;
     char *compopt  = NULL;
     char *encryptopt = skip_argument;
+    char *quoted;
+    char *qdisk;
     int infd, outfd;
     ssize_t nb;
     char buf[32768];
 
+    (void)dumpdate;    /* Quiet unused parameter warning */
+
     error_pn = stralloc2(get_pname(), "-smbclient");
 
+    qdisk = quote_string(disk);
+    dbprintf(("%s: start: %s:%s lev %d\n",
+             get_pname(), host, qdisk, level));
 
     fprintf(stderr, "%s: start [%s:%s level %d]\n",
-           get_pname(), host, disk, level);
+           get_pname(), host, qdisk, level);
+
      /*  apply client-side encryption here */
      if ( options->encrypt == ENCRYPT_CUST ) {
-      encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
+         encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
                        &compout, &dataf, &mesgf, 
                        options->clnt_encrypt, encryptopt, NULL);
-      dbprintf(("%s: pid %ld: %s\n",
+         dbprintf(("%s: pid %ld: %s\n",
                  debug_prefix_time("-gnutar"), (long)encpid, options->clnt_encrypt));
     } else {
        compout = dataf;
@@ -202,13 +216,16 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
        comppid = -1;
     }
 
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR                                   /* { */
+    gnutar_list_dir = client_getconf_str(CLN_GNUTAR_LIST_DIR);
+    if (strlen(gnutar_list_dir) == 0)
+       gnutar_list_dir = NULL;
+
 #ifdef SAMBA_CLIENT                                                    /* { */
     if (amdevice[0] == '/' && amdevice[1]=='/')
        amfree(incrname);
     else
 #endif                                                                 /* } */
-    {
+    if (gnutar_list_dir) {
        char *basename = NULL;
        char number[NUM_STR_SIZE];
        char *s;
@@ -216,7 +233,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
        char *inputname = NULL;
        int baselevel;
 
-       basename = vstralloc(GNUTAR_LISTED_INCREMENTAL_DIR,
+       basename = vstralloc(gnutar_list_dir,
                             "/",
                             host,
                             disk,
@@ -225,12 +242,13 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
         * The loop starts at the first character of the host name,
         * not the '/'.
         */
-       s = basename + sizeof(GNUTAR_LISTED_INCREMENTAL_DIR);
+       s = basename + strlen(gnutar_list_dir) + 1;
        while((ch = *s++) != '\0') {
-           if(ch == '/' || isspace(ch)) s[-1] = '_';
+           if(ch == '/')
+               s[-1] = '_';
        }
 
-       snprintf(number, sizeof(number), "%d", level);
+       snprintf(number, SIZEOF(number), "%d", level);
        incrname = vstralloc(basename, "_", number, ".new", NULL);
        unlink(incrname);
 
@@ -243,7 +261,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
        infd = -1;
        while (infd == -1) {
            if (--baselevel >= 0) {
-               snprintf(number, sizeof(number), "%d", baselevel);
+               snprintf(number, SIZEOF(number), "%d", baselevel);
                inputname = newvstralloc(inputname,
                                         basename, "_", number, NULL);
            } else {
@@ -251,14 +269,17 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
            }
            if ((infd = open(inputname, O_RDONLY)) == -1) {
                int save_errno = errno;
+               char *qname = quote_string(inputname);
 
-               dbprintf(("%s: error opening %s: %s\n",
+               dbprintf(("%s: error opening '%s': %s\n",
                          debug_prefix_time("-gnutar"),
-                         inputname,
+                         qname,
                          strerror(save_errno)));
                if (baselevel < 0) {
-                   error("error [opening %s: %s]", inputname, strerror(save_errno));
+                   error("error [opening '%s': %s]", qname, strerror(save_errno));
+                   /*NOTREACHED*/
                }
+               amfree(qname);
            }
        }
 
@@ -266,42 +287,53 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
         * Copy the previous listed incremental file to the new one.
         */
        if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) {
-           error("error [opening %s: %s]", incrname, strerror(errno));
+           error("error [opening '%s': %s]", incrname, strerror(errno));
+           /*NOTREACHED*/
        }
 
-       while ((nb = read(infd, &buf, sizeof(buf))) > 0) {
-           if (fullwrite(outfd, &buf, nb) < nb) {
+       while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) {
+           if (fullwrite(outfd, &buf, (size_t)nb) < nb) {
                error("error [writing to '%s': %s]", incrname,
                       strerror(errno));
+               /*NOTREACHED*/
            }
        }
 
        if (nb < 0) {
-           error("error [reading from %s: %s]", inputname, strerror(errno));
+           error("error [reading from '%s': %s]", inputname, strerror(errno));
+           /*NOTREACHED*/
        }
 
        if (close(infd) != 0) {
-           error("error [closing %s: %s]", inputname, strerror(errno));
+           error("error [closing '%s': %s]", inputname, strerror(errno));
+           /*NOTREACHED*/
        }
        if (close(outfd) != 0) {
-           error("error [closing %s: %s]", incrname, strerror(errno));
+           error("error [closing '%s': %s]", incrname, strerror(errno));
+           /*NOTREACHED*/
        }
 
        dbprintf(("%s: doing level %d dump as listed-incremental",
                  debug_prefix_time("-gnutar"), level));
        if(baselevel >= 0) {
-           dbprintf((" from %s", inputname));
+           quoted = quote_string(inputname);
+           dbprintf((" from '%s'", quoted));
+           amfree(quoted);
        }
-       dbprintf((" to %s\n", incrname));
+       quoted = quote_string(incrname);
+       dbprintf((" to '%s'\n", quoted));
+       amfree(quoted);
        amfree(inputname);
        amfree(basename);
     }
-#endif                                                                 /* } */
 
     /* find previous dump time */
 
-    if(!start_amandates(0))
-       error("error [opening %s: %s]", AMANDATES_FILE, strerror(errno));
+    amandates_file = client_getconf_str(CLN_AMANDATES);
+    if(!start_amandates(amandates_file, 0)) {
+       error("error [opening %s: %s]", amandates_file, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     amdates = amandates_lookup(disk);
 
@@ -315,7 +347,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
     free_amandates();
 
     gmtm = gmtime(&prev_dumptime);
-    snprintf(dumptimestr, sizeof(dumptimestr),
+    snprintf(dumptimestr, SIZEOF(dumptimestr),
                "%04d-%02d-%02d %2d:%02d:%02d GMT",
                gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
                gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);
@@ -345,11 +377,11 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
     if (amdevice[0] == '/' && amdevice[1]=='/') {
        char *sharename = NULL, *user_and_password = NULL, *domain = NULL;
        char *share = NULL, *subdir = NULL;
-       char *pwtext;
+       char *pwtext = NULL;
        char *taropt;
-       int passwdf;
-       int lpass;
-       int pwtext_len;
+       int passwdf = -1;
+       size_t lpass;
+       size_t pwtext_len;
        char *pw_fd_env;
 
        parsesharename(amdevice, &share, &subdir);
@@ -358,14 +390,16 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
            amfree(subdir);
            set_pname(error_pn);
            amfree(error_pn);
-           error("cannot parse disk entry '%s' for share/subdir", disk);
+           error("cannot parse disk entry %s for share/subdir", qdisk);
+           /*NOTREACHED*/
        }
        if ((subdir) && (SAMBA_VERSION < 2)) {
            amfree(share);
            amfree(subdir);
            set_pname(error_pn);
            amfree(error_pn);
-           error("subdirectory specified for share '%s' but samba not v2 or better", disk);
+           error("subdirectory specified for share %s but samba not v2 or better", qdisk);
+           /*NOTREACHED*/
        }
        if ((user_and_password = findpass(share, &domain)) == NULL) {
            if(domain) {
@@ -375,6 +409,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
            set_pname(error_pn);
            amfree(error_pn);
            error("error [invalid samba host or password not found?]");
+           /*NOTREACHED*/
        }
        lpass = strlen(user_and_password);
        if ((pwtext = strchr(user_and_password, '%')) == NULL) {
@@ -386,7 +421,8 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
            }
            set_pname(error_pn);
            amfree(error_pn);
-           error("password field not \'user%%pass\' for %s", disk);
+           error("password field not \'user%%pass\' for %s", qdisk);
+           /*NOTREACHED*/
        }
        *pwtext++ = '\0';
        pwtext_len = strlen(pwtext);
@@ -400,6 +436,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
            set_pname(error_pn);
            amfree(error_pn);
            error("error [can't make share name of %s]", share);
+           /*NOTREACHED*/
        }
 
        taropt = stralloc("-T");
@@ -465,6 +502,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
            set_pname(error_pn);
            amfree(error_pn);
            error("error [password write failed: %s]", strerror(save_errno));
+           /*NOTREACHED*/
        }
        memset(user_and_password, '\0', lpass);
        amfree(user_and_password);
@@ -493,13 +531,18 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
        if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 0);
        if(nb_include > 0) file_include = build_include(disk, amdevice, options, 0);
 
-       my_argv = alloc(sizeof(char *) * (17 + (nb_exclude*2)+(nb_include*2)));
+       my_argv = alloc(SIZEOF(char *) * (22 + (nb_exclude*2)+(nb_include*2)));
 
        cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
        info_tapeheader();
 
        start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
 
+        my_argv[i++] = "runtar";
+       if (g_options->config)
+           my_argv[i++] = g_options->config;
+       else
+           my_argv[i++] = "NOCONFIG";
        my_argv[i++] = "gtar";
        my_argv[i++] = "--create";
        my_argv[i++] = "--file";
@@ -507,14 +550,14 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
        my_argv[i++] = "--directory";
        my_argv[i++] = dirname;
        my_argv[i++] = "--one-file-system";
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
-       my_argv[i++] = "--listed-incremental";
-       my_argv[i++] = incrname;
-#else
-       my_argv[i++] = "--incremental";
-       my_argv[i++] = "--newer";
-       my_argv[i++] = dumptimestr;
-#endif
+       if (gnutar_list_dir && incrname) {
+           my_argv[i++] = "--listed-incremental";
+           my_argv[i++] = incrname;
+       } else {
+           my_argv[i++] = "--incremental";
+           my_argv[i++] = "--newer";
+           my_argv[i++] = dumptimestr;
+       }
 #ifdef ENABLE_GNUTAR_ATIME_PRESERVE
        /* --atime-preserve causes gnutar to call
         * utime() after reading files in order to
@@ -552,6 +595,7 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
              cmd,
              (long)dumppid));
 
+    amfree(qdisk);
     amfree(dirname);
     amfree(cmd);
     amfree(indexcmd);
@@ -568,11 +612,11 @@ static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, in
        aclose(indexf);
 }
 
-static void end_backup(goterror)
-int goterror;
+static void
+end_backup(
+    int                goterror)
 {
     if(!options->no_record && !goterror) {
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
        if (incrname != NULL && strlen(incrname) > 4) {
            char *nodotnew;
        
@@ -585,11 +629,10 @@ int goterror;
            amfree(nodotnew);
            amfree(incrname);
        }
-#endif
 
-        if(!start_amandates(1)) {
+        if(!start_amandates(amandates_file, 1)) {
            fprintf(stderr, "%s: warning [opening %s: %s]", get_pname(),
-                   AMANDATES_FILE, strerror(errno));
+                   amandates_file, strerror(errno));
        }
        else {
            amandates_updateone(cur_disk, cur_level, cur_dumptime);
index e824e1ef286555960ca682cfe184f06cb63392e9..5af8dcef5be8ceb048dc46eadbf892721c37a11d 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: sendbackup.c,v 1.77 2006/03/09 16:51:41 martinea Exp $
+ * $Id: sendbackup.c,v 1.88 2006/07/25 18:27:56 martinea Exp $
  *
  * common code for the sendbackup-* programs.
  */
 #include "arglist.h"
 #include "getfsent.h"
 #include "version.h"
+#include "clientconf.h"
 
 #define TIMEOUT 30
 
-int comppid = -1;
-int dumppid = -1;
-int tarpid = -1;
-int encpid = -1;
-int indexpid = -1;
+pid_t comppid = (pid_t)-1;
+pid_t dumppid = (pid_t)-1;
+pid_t tarpid = (pid_t)-1;
+pid_t encpid = (pid_t)-1;
+pid_t indexpid = (pid_t)-1;
 char *errorstr = NULL;
 
 int datafd;
@@ -53,6 +54,7 @@ int mesgfd;
 int indexfd;
 
 option_t *options;
+g_option_t *g_options = NULL;
 
 long dump_size = -1;
 
@@ -60,22 +62,27 @@ backup_program_t *program = NULL;
 
 static am_feature_t *our_features = NULL;
 static char *our_feature_string = NULL;
-static g_option_t *g_options = NULL;
+static char *amandad_auth = NULL;
 
 /* local functions */
-int main P((int argc, char **argv));
-char *optionstr P((option_t *options));
-char *childstr P((int pid));
-int check_status P((int pid, amwait_t w));
-
-int pipefork P((void (*func) P((void)), char *fname, int *stdinfd,
-               int stdoutfd, int stderrfd));
-void parse_backup_messages P((int mesgin));
-static void process_dumpline P((char *str));
-static void save_fd P((int *, int));
-
-char *optionstr(options)
-option_t *options;
+int main(int argc, char **argv);
+char *optionstr(option_t *options);
+char *childstr(pid_t pid);
+int check_status(pid_t pid, amwait_t w);
+
+pid_t pipefork(void (*func)(void), char *fname, int *stdinfd,
+               int stdoutfd, int stderrfd);
+void parse_backup_messages(int mesgin);
+static void process_dumpline(char *str);
+static void save_fd(int *, int);
+
+double first_num(char *str);
+
+
+
+char *
+optionstr(
+    option_t * options)
 {
     static char *optstr = NULL;
     char *compress_opt;
@@ -142,6 +149,7 @@ option_t *options;
            strappend(exclude_list_opt, exc);
        }
     }
+    amfree(exc);
     optstr = newvstralloc(optstr,
                          compress_opt,
                          encrypt_opt,
@@ -162,16 +170,23 @@ option_t *options;
 }
 
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     int interactive = 0;
-    int level, mesgpipe[2];
-    char *prog, *disk, *amdevice, *dumpdate, *stroptions;
+    int level = 0;
+    int mesgpipe[2];
+    char *prog, *dumpdate, *stroptions;
+    char *disk = NULL;
+    char *qdisk = NULL;
+    char *amdevice = NULL;
+    char *qamdevice = NULL;
     char *line = NULL;
     char *err_extra = NULL;
     char *s;
+    char *conffile;
     int i;
     int ch;
     unsigned long malloc_hist_1, malloc_size_1;
@@ -179,7 +194,8 @@ char **argv;
 
     /* initialize */
 
-    safe_fd(DATA_FD_OFFSET, DATA_FD_COUNT);
+    safe_fd(DATA_FD_OFFSET, DATA_FD_COUNT*2);
+
     safe_cd();
 
     set_pname("sendbackup");
@@ -187,17 +203,38 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
+    /* Don't die when interrupt received */
+    signal(SIGINT, SIG_IGN);
+
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
-    interactive = (argc > 1 && strcmp(argv[1],"-t") == 0);
+    if(argc > 1 && strcmp(argv[1],"-t") == 0) {
+       interactive = 1;
+       argc--;
+       argv++;
+    } else {
+       interactive = 0;
+    }
+
     erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
-    dbopen();
+    dbopen(DBG_SUBDIR_CLIENT);
     startclock();
     dbprintf(("%s: version %s\n", get_pname(), version()));
 
+    if(argc > 2 && strcmp(argv[1], "amandad") == 0) {
+       amandad_auth = stralloc(argv[2]);
+    }
+
     our_features = am_init_feature_set();
     our_feature_string = am_feature_to_string(our_features);
 
+    conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+    if (read_clientconf(conffile) > 0) {
+       error("error reading conffile: %s", conffile);
+       /*NOTREACHED*/
+    }
+    amfree(conffile);
+
     if(interactive) {
        /*
         * In interactive (debug) mode, the backup data is sent to
@@ -211,17 +248,20 @@ char **argv;
 
     prog = NULL;
     disk = NULL;
+    qdisk = NULL;
     amdevice = NULL;
     dumpdate = NULL;
     stroptions = NULL;
 
     for(; (line = agets(stdin)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        if(interactive) {
            fprintf(stderr, "%s> ", get_pname());
            fflush(stderr);
        }
 #define sc "OPTIONS "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
 #undef sc
            g_options = parse_g_options(line+8, 1);
            if(!g_options->hostname) {
@@ -229,6 +269,18 @@ char **argv;
                gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH);
                g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0';
            }
+
+           if (g_options->config) {
+               conffile = vstralloc(CONFIG_DIR, "/", g_options->config, "/",
+                                    "amanda-client.conf", NULL);
+               if (read_clientconf(conffile) > 0) {
+                   error("error reading conffile: %s", conffile);
+                   /*NOTREACHED*/
+               }
+               amfree(conffile);
+
+               dbrename(g_options->config, DBG_SUBDIR_CLIENT);
+           }
            continue;
        }
 
@@ -237,6 +289,7 @@ char **argv;
            goto err;
        }
 
+       dbprintf(("  sendbackup req: <%s>\n", line));
        s = line;
        ch = *s++;
 
@@ -255,11 +308,15 @@ char **argv;
            err_extra = "no disk name";
            goto err;                           /* no disk name */
        }
+
        amfree(disk);
-       disk = s - 1;
-       skip_non_whitespace(s, ch);
+       amfree(qdisk);
+       qdisk = s - 1;
+       ch = *qdisk;
+       skip_quoted_string(s, ch);
        s[-1] = '\0';
-       disk = stralloc(disk);
+       qdisk = stralloc(qdisk);
+       disk = unquote_string(qdisk);
 
        skip_whitespace(s, ch);                 /* find the device or level */
        if (ch == '\0') {
@@ -269,6 +326,7 @@ char **argv;
 
        if(!isdigit((int)s[-1])) {
            amfree(amdevice);
+           amfree(qamdevice);
            amdevice = s - 1;
            skip_non_whitespace(s, ch);
            s[-1] = '\0';
@@ -278,7 +336,7 @@ char **argv;
        else {
            amdevice = stralloc(disk);
        }
-
+       qamdevice = quote_string(amdevice);
                                                /* find the level number */
        if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
            err_extra = "bad level";
@@ -303,11 +361,11 @@ char **argv;
            goto err;                           /* no options */
        }
 #define sc "OPTIONS "
-       if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
            err_extra = "no OPTIONS keyword";
            goto err;                           /* no options */
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
        skip_whitespace(s, ch);                 /* find the options string */
@@ -320,9 +378,18 @@ char **argv;
     }
     amfree(line);
 
+    if (prog       == NULL ||
+       disk       == NULL ||
+       amdevice   == NULL ||
+       dumpdate   == NULL ||
+       stroptions == NULL) {
+       err_extra = "no valid sendbackup request";
+       goto err;
+    }
+       
     dbprintf(("  parsed request as: program `%s'\n", prog));
-    dbprintf(("                     disk `%s'\n", disk));
-    dbprintf(("                     device `%s'\n", amdevice));
+    dbprintf(("                     disk `%s'\n", qdisk));
+    dbprintf(("                     device `%s'\n", qamdevice));
     dbprintf(("                     level %d\n", level));
     dbprintf(("                     since %s\n", dumpdate));
     dbprintf(("                     options `%s'\n", stroptions));
@@ -334,6 +401,7 @@ char **argv;
     }
     if (programs[i] == NULL) {
        error("ERROR [%s: unknown program %s]", get_pname(), prog);
+       /*NOTREACHED*/
     }
     program = programs[i];
 
@@ -341,14 +409,23 @@ char **argv;
 
     if(!interactive) {
        datafd = DATA_FD_OFFSET + 0;
-       mesgfd = DATA_FD_OFFSET + 1;
-       indexfd = DATA_FD_OFFSET + 2;
+       mesgfd = DATA_FD_OFFSET + 2;
+       indexfd = DATA_FD_OFFSET + 4;
     }
     if (!options->createindex)
        indexfd = -1;
 
+    if(options->auth && amandad_auth) {
+       if(strcasecmp(options->auth, amandad_auth) != 0) {
+           printf("ERROR [client configured for auth=%s while server requested '%s']\n",
+                  amandad_auth, options->auth);
+           exit(-1);
+       }
+    }
+
     printf("CONNECT DATA %d MESG %d INDEX %d\n",
-          datafd, mesgfd, indexfd);
+          DATA_FD_OFFSET, DATA_FD_OFFSET+1,
+          indexfd == -1 ? -1 : DATA_FD_OFFSET+2);
     printf("OPTIONS ");
     if(am_has_feature(g_options->features, fe_rep_options_features)) {
        printf("features=%s;", our_feature_string);
@@ -372,6 +449,7 @@ char **argv;
        s = strerror(errno);
        error("ERROR [%s: open of /dev/null for debug data stream: %s]\n",
                  get_pname(), s);
+       /*NOTREACHED*/
       }
       mesgfd = 2;
       indexfd = 1;
@@ -396,6 +474,7 @@ char **argv;
 
     if(pipe(mesgpipe) == -1) {
       error("error [opening mesg pipe: %s]", strerror(errno));
+      /*NOTREACHED*/
     }
 
     program->start_backup(g_options->hostname, disk, amdevice, level, dumpdate, datafd, mesgpipe[1],
@@ -406,7 +485,9 @@ char **argv;
 
     amfree(prog);
     amfree(disk);
+    amfree(qdisk);
     amfree(amdevice);
+    amfree(qamdevice);
     amfree(dumpdate);
     amfree(stroptions);
     amfree(our_feature_string);
@@ -438,12 +519,15 @@ char **argv;
     return 1;
 }
 
-char *childstr(pid)
-int pid;
+
 /*
  * Returns a string for a child process.  Checks the saved dump and
  * compress pids to see which it is.
  */
+
+char *
+childstr(
+    pid_t pid)
 {
     if(pid == dumppid) return program->backup_name;
     if(pid == comppid) return "compress";
@@ -453,14 +537,16 @@ int pid;
 }
 
 
-int check_status(pid, w)
-int pid;
-amwait_t w;
 /*
  * Determine if the child return status really indicates an error.
  * If so, add the error message to the error string; more than one
  * child can have an error.
  */
+
+int
+check_status(
+    pid_t      pid,
+    amwait_t   w)
 {
     char *thiserr = NULL;
     char *str;
@@ -527,10 +613,10 @@ amwait_t w;
     }
 
     if(ret == 0) {
-       snprintf(number, sizeof(number), "%d", sig);
+       snprintf(number, SIZEOF(number), "%d", sig);
        thiserr = vstralloc(str, " got signal ", number, NULL);
     } else {
-       snprintf(number, sizeof(number), "%d", ret);
+       snprintf(number, SIZEOF(number), "%d", ret);
        thiserr = vstralloc(str, " returned ", number, NULL);
     }
 
@@ -546,9 +632,11 @@ amwait_t w;
 }
 
 
-/* Send header info to the message file.
-*/
-void info_tapeheader()
+/*
+ *Send header info to the message file.
+ */
+void
+info_tapeheader(void)
 {
     fprintf(stderr, "%s: info BACKUP=%s\n", get_pname(), program->backup_name);
 
@@ -562,7 +650,7 @@ void info_tapeheader()
 #endif
                );
 
-    fprintf(stderr, "%s -f... -\n", program->restore_name);
+    fprintf(stderr, "%s -f - ...\n", program->restore_name);
 
     if (options->compress == COMPR_FAST || options->compress == COMPR_BEST)
        fprintf(stderr, "%s: info COMPRESS_SUFFIX=%s\n",
@@ -571,24 +659,29 @@ void info_tapeheader()
     fprintf(stderr, "%s: info end\n", get_pname());
 }
 
-int pipefork(func, fname, stdinfd, stdoutfd, stderrfd)
-void (*func) P((void));
-char *fname;
-int *stdinfd;
-int stdoutfd, stderrfd;
+pid_t
+pipefork(
+    void       (*func)(void),
+    char *     fname,
+    int *      stdinfd,
+    int                stdoutfd,
+    int                stderrfd)
 {
-    int pid, inpipe[2];
+    int inpipe[2];
+    pid_t pid;
 
     dbprintf(("%s: forking function %s in pipeline\n",
        debug_prefix_time(NULL), fname));
 
     if(pipe(inpipe) == -1) {
        error("error [open pipe to %s: %s]", fname, strerror(errno));
+       /*NOTREACHED*/
     }
 
     switch(pid = fork()) {
     case -1:
        error("error [fork %s: %s]", fname, strerror(errno));
+       /*NOTREACHED*/
     default:   /* parent process */
        aclose(inpipe[0]);      /* close input side of pipe */
        *stdinfd = inpipe[1];
@@ -599,27 +692,32 @@ int stdoutfd, stderrfd;
        if(dup2(inpipe[0], 0) == -1) {
            error("error [fork %s: dup2(%d, in): %s]",
                  fname, inpipe[0], strerror(errno));
+           /*NOTRACHED*/
        }
        if(dup2(stdoutfd, 1) == -1) {
            error("error [fork %s: dup2(%d, out): %s]",
                  fname, stdoutfd, strerror(errno));
+           /*NOTRACHED*/
        }
        if(dup2(stderrfd, 2) == -1) {
            error("error [fork %s: dup2(%d, err): %s]",
                  fname, stderrfd, strerror(errno));
+           /*NOTRACHED*/
        }
 
        func();
        exit(0);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
     return pid;
 }
 
-void parse_backup_messages(mesgin)
-int mesgin;
+void
+parse_backup_messages(
+    int                mesgin)
 {
-    int goterror, wpid;
+    int goterror;
+    pid_t wpid;
     amwait_t retstat;
     char *line;
 
@@ -632,6 +730,7 @@ int mesgin;
 
     if(errno) {
        error("error [read mesg pipe: %s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     while((wpid = wait(&retstat)) != -1) {
@@ -640,8 +739,10 @@ int mesgin;
 
     if(errorstr) {
        error("error [%s]", errorstr);
+       /*NOTREACHED*/
     } else if(dump_size == -1) {
        error("error [no backup size line]");
+       /*NOTREACHED*/
     }
 
     program->end_backup(goterror);
@@ -651,13 +752,13 @@ int mesgin;
 }
 
 
-double first_num P((char *str));
-
-double first_num(str)
-char *str;
 /*
  * Returns the value of the first integer in a string.
  */
+
+double
+first_num(
+    char *     str)
 {
     char *num;
     int ch;
@@ -669,15 +770,16 @@ char *str;
     while(isdigit(ch) || ch == '.') ch = *str++;
     str[-1] = '\0';
     d = atof(num);
-    str[-1] = ch;
+    str[-1] = (char)ch;
     return d;
 }
 
 
-static void process_dumpline(str)
-char *str;
+static void
+process_dumpline(
+    char *     str)
 {
-    regex_t *rp;
+    amregex_t *rp;
     char *type;
     char startchr;
 
@@ -724,30 +826,30 @@ char *str;
 }
 
 
-/* start_index.  Creates an index file from the output of dump/tar.
-   It arranges that input is the fd to be written by the dump process.
-   If createindex is not enabled, it does nothing.  If it is not, a
-   new process will be created that tees input both to a pipe whose
-   read fd is dup2'ed input and to a program that outputs an index
-   file to `index'.
-
-   make sure that the chat from restore doesn't go to stderr cause
-   this goes back to amanda which doesn't expect to see it
-   (2>/dev/null should do it)
-
-   Originally by Alan M. McIvor, 13 April 1996
-
-   Adapted by Alexandre Oliva, 1 May 1997
-
-   This program owes a lot to tee.c from GNU sh-utils and dumptee.c
-   from the DeeJay backup package.
-
-*/
-
-static volatile int index_finished = 0;
+/*
+ * start_index.  Creates an index file from the output of dump/tar.
+ * It arranges that input is the fd to be written by the dump process.
+ * If createindex is not enabled, it does nothing.  If it is not, a
+ * new process will be created that tees input both to a pipe whose
+ * read fd is dup2'ed input and to a program that outputs an index
+ * file to `index'.
+ *
+ * make sure that the chat from restore doesn't go to stderr cause
+ * this goes back to amanda which doesn't expect to see it
+ * (2>/dev/null should do it)
+ *
+ * Originally by Alan M. McIvor, 13 April 1996
+ *
+ * Adapted by Alexandre Oliva, 1 May 1997
+ *
+ * This program owes a lot to tee.c from GNU sh-utils and dumptee.c
+ * from the DeeJay backup package.
+ */
 
-static void save_fd(fd, min)
-int *fd, min;
+static void
+save_fd(
+    int *      fd,
+    int                min)
 {
   int origfd = *fd;
 
@@ -763,9 +865,13 @@ int *fd, min;
       debug_prefix_time(NULL), origfd, *fd));
 }
 
-void start_index(createindex, input, mesg, index, cmd)
-int createindex, input, mesg, index;
-char *cmd;
+void
+start_index(
+    int                createindex,
+    int                input,
+    int                mesg,
+    int                index,
+    char *     cmd)
 {
   int pipefd[2];
   FILE *pipe_fp;
@@ -776,16 +882,19 @@ char *cmd;
 
   if (pipe(pipefd) != 0) {
     error("creating index pipe: %s", strerror(errno));
+    /*NOTREACHED*/
   }
 
   switch(indexpid = fork()) {
   case -1:
     error("forking index tee process: %s", strerror(errno));
+    /*NOTREACHED*/
 
   default:
     aclose(pipefd[0]);
     if (dup2(pipefd[1], input) == -1) {
       error("dup'ping index tee output: %s", strerror(errno));
+      /*NOTREACHED*/
     }
     aclose(pipefd[1]);
     return;
@@ -811,22 +920,24 @@ char *cmd;
 
   if ((pipe_fp = popen(cmd, "w")) == NULL) {
     error("couldn't start index creator [%s]", strerror(errno));
+    /*NOTREACHED*/
   }
 
   dbprintf(("%s: started index creator: \"%s\"\n",
     debug_prefix_time(NULL), cmd));
   while(1) {
     char buffer[BUFSIZ], *ptr;
-    int bytes_read;
-    int bytes_written;
-    int just_written;
+    ssize_t bytes_read;
+    size_t bytes_written;
+    ssize_t just_written;
 
     do {
-       bytes_read = read(0, buffer, sizeof(buffer));
+       bytes_read = read(0, buffer, SIZEOF(buffer));
     } while ((bytes_read < 0) && ((errno == EINTR) || (errno == EAGAIN)));
 
     if (bytes_read < 0) {
       error("index tee cannot read [%s]", strerror(errno));
+      /*NOTREACHED*/
     }
 
     if (bytes_read == 0)
@@ -835,9 +946,9 @@ char *cmd;
     /* write the stuff to the subprocess */
     ptr = buffer;
     bytes_written = 0;
-    just_written = fullwrite(fileno(pipe_fp), ptr, bytes_read);
+    just_written = fullwrite(fileno(pipe_fp), ptr, (size_t)bytes_read);
     if (just_written < 0) {
-       /* the signal handler may have assigned to index_finished
+       /* 
         * just as we waited for write() to complete.
         */
        if (errno != EPIPE) {
@@ -853,10 +964,10 @@ char *cmd;
        occurs */
     ptr = buffer;
     bytes_written = 0;
-    just_written = fullwrite(3, ptr, bytes_read);
+    just_written = fullwrite(3, ptr, (size_t)bytes_read);
     if (just_written < 0) {
        error("index tee cannot write [%s]", strerror(errno));
-       /* NOTREACHED */
+       /*NOTREACHED*/
     } else {
        bytes_written += just_written;
        ptr += just_written;
index ee2a836a0af3b97008ed93a3c00e6179ddf800f5..2a4cdb8d8b20af68c6408e70fde9f4d9b5fb1cfc 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: sendbackup.h,v 1.18 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: sendbackup.h,v 1.20 2006/07/25 18:10:07 martinea Exp $
  *
  * a few common decls for the sendbackup-* sources
  */
+#ifndef SENDBACKUP_H
+#define SENDBACKUP_H
+
 #include "amanda.h"
 #include "pipespawn.h"
 #include "client_util.h"
+#include "amandad.h"
 
-void info_tapeheader P((void));
-void start_index P((int createindex, int input, int mesg, 
-                   int index, char *cmd));
+void info_tapeheader(void);
+void start_index(int createindex, int input, int mesg, 
+                   int index, char *cmd);
 
 /*
  * Dump output lines are scanned for two types of regex matches.
@@ -61,24 +65,25 @@ typedef struct regex_s {
     int srcline;
     int scale;                  /* only used for size lines */
     dmpline_t typ;
-} regex_t;
+} amregex_t;
 
 #define AM_NORMAL_RE(re)       {(re), __LINE__, 0, DMP_NORMAL}
 #define AM_STRANGE_RE(re)      {(re), __LINE__, 0, DMP_STRANGE}
 #define AM_SIZE_RE(re,s)       {(re), __LINE__, (s), DMP_SIZE}
 #define AM_ERROR_RE(re)                {(re), __LINE__, 0, DMP_ERROR}
 
-extern int  comppid, dumppid, encpid, tarpid;
-extern int indexpid;
+extern pid_t  comppid, dumppid, encpid, tarpid;
+extern pid_t indexpid;
 extern option_t *options;
+extern g_option_t *g_options;
 
 typedef struct backup_program_s {
     char *name, *backup_name, *restore_name;
-    regex_t *re_table;
-    void (*start_backup) P((char *host, char *disk, char *amdevice, int level, char *dumpdate, 
-                           int dataf, int mesgf, int indexf));
-    void (*end_backup) P((int goterror));
+    amregex_t *re_table;
+    void (*start_backup)(char *host, char *disk, char *amdevice, int level, char *dumpdate, int dataf, int mesgf, int indexf);
+    void (*end_backup)(int goterror);
 } backup_program_t;
 
 extern backup_program_t *programs[], *program;
 
+#endif /* !SENDBACKUP_H */
index ecbe2b2ef7a510e48df4637e29ccd612a6132216..bf3595ab223aa29ae8571519a813f2679969f2a3 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: sendsize.c,v 1.152 2006/03/09 16:51:41 martinea Exp $
+ * $Id: sendsize.c,v 1.171 2006/08/24 01:57:15 paddy_s Exp $
  *
  * send estimated backup sizes using dump
  */
@@ -38,6 +38,8 @@
 #include "getfsent.h"
 #include "version.h"
 #include "client_util.h"
+#include "clientconf.h"
+#include "amandad.h"
 
 #ifdef SAMBA_CLIENT
 #include "findpass.h"
@@ -76,8 +78,11 @@ typedef struct level_estimates_s {
 typedef struct disk_estimates_s {
     struct disk_estimates_s *next;
     char *amname;
+    char *qamname;
     char *amdevice;
+    char *qamdevice;
     char *dirname;
+    char *qdirname;
     char *program;
     char *calcprog;
     int program_is_wrapper;
@@ -95,25 +100,27 @@ static char *our_feature_string = NULL;
 static g_option_t *g_options = NULL;
 
 /* local functions */
-int main P((int argc, char **argv));
-void add_diskest P((char *disk, char *amdevice, int level, int spindle, 
+int main(int argc, char **argv);
+void add_diskest(char *disk, char *amdevice, int level, int spindle, 
                    int program_is_wrapper, char *prog, char *calcprog,
-                   option_t *options));
-void calc_estimates P((disk_estimates_t *est));
-void free_estimates P((disk_estimates_t *est));
-void dump_calc_estimates P((disk_estimates_t *));
-void smbtar_calc_estimates P((disk_estimates_t *));
-void gnutar_calc_estimates P((disk_estimates_t *));
-void wrapper_calc_estimates P((disk_estimates_t *));
-void generic_calc_estimates P((disk_estimates_t *));
-
-
-int main(argc, argv)
-int argc;
-char **argv;
+                   option_t *options);
+void calc_estimates(disk_estimates_t *est);
+void free_estimates(disk_estimates_t *est);
+void dump_calc_estimates(disk_estimates_t *);
+void star_calc_estimates(disk_estimates_t *);
+void smbtar_calc_estimates(disk_estimates_t *);
+void gnutar_calc_estimates(disk_estimates_t *);
+void wrapper_calc_estimates(disk_estimates_t *);
+void generic_calc_estimates(disk_estimates_t *);
+
+
+int
+main(
+    int                argc,
+    char **    argv)
 {
     int level, spindle;
-    char *prog, *calcprog, *disk, *amdevice, *dumpdate;
+    char *prog, *calcprog, *dumpdate;
     option_t *options = NULL;
     int program_is_wrapper;
     disk_estimates_t *est;
@@ -123,12 +130,23 @@ char **argv;
     char *s, *fp;
     int ch;
     char *err_extra = NULL;
-    unsigned long malloc_hist_1, malloc_size_1;
-    unsigned long malloc_hist_2, malloc_size_2;
     int done;
     int need_wait;
     int dumpsrunning;
+    char *disk = NULL;
+    char *qdisk = NULL;
+    char *qlist = NULL;
+    char *amdevice = NULL;
+    char *qamdevice = NULL;
+    char *conffile;
+    char *amandates_file;
+#if defined(USE_DBMALLOC)
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+#endif
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
 
     /* initialize */
 
@@ -140,10 +158,12 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
+#if defined(USE_DBMALLOC)
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
+#endif
 
     erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
-    dbopen();
+    dbopen(DBG_SUBDIR_CLIENT);
     startclock();
     dbprintf(("%s: version %s\n", get_pname(), version()));
 
@@ -152,13 +172,24 @@ char **argv;
 
     set_debug_prefix_pid(getpid());
 
+    conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+    if (read_clientconf(conffile) > 0) {
+       error("error reading conffile: %s", conffile);
+       /*NOTREACHED*/
+    }
+    amfree(conffile);
+
     /* handle all service requests */
 
-    start_amandates(0);
+    amandates_file = client_getconf_str(CLN_AMANDATES);
+    if(!start_amandates(amandates_file, 0))
+        error("error [opening %s: %s]", amandates_file, strerror(errno));
 
     for(; (line = agets(stdin)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
 #define sc "OPTIONS "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
 #undef sc
            g_options = parse_g_options(line+8, 1);
            if(!g_options->hostname) {
@@ -179,6 +210,19 @@ char **argv;
            }
            printf("\n");
            fflush(stdout);
+
+           if (g_options->config) {
+               conffile = vstralloc(CONFIG_DIR, "/", g_options->config, "/",
+                                    "amanda-client.conf", NULL);
+               if (read_clientconf(conffile) > 0) {
+                   error("error reading conffile: %s", conffile);
+                   /*NOTREACHED*/
+               }
+               amfree(conffile);
+
+               dbrename(g_options->config, DBG_SUBDIR_CLIENT);
+           }
+
            continue;
        }
 
@@ -187,7 +231,7 @@ char **argv;
 
        skip_whitespace(s, ch);                 /* find the program name */
        if(ch == '\0') {
-           err_extra = "no program name";
+           err_extra = stralloc("no program name");
            goto err;                           /* no program name */
        }
        prog = s - 1;
@@ -209,7 +253,7 @@ char **argv;
        if(strncmp(prog, "CALCSIZE", 8) == 0) {
            skip_whitespace(s, ch);             /* find the program name */
            if(ch == '\0') {
-               err_extra = "no program name";
+               err_extra = stralloc("no program name");
                goto err;
            }
            calcprog = s - 1;
@@ -222,56 +266,71 @@ char **argv;
 
        skip_whitespace(s, ch);                 /* find the disk name */
        if(ch == '\0') {
-           err_extra = "no disk name";
+           err_extra = stralloc("no disk name");
            goto err;                           /* no disk name */
        }
-       disk = s - 1;
-       skip_non_whitespace(s, ch);
-       s[-1] = '\0';
+
+       if (qdisk != NULL)
+           amfree(qdisk);
+       if (disk != NULL)
+           amfree(disk);
+
+       fp = s - 1;
+       skip_quoted_string(s, ch);
+       s[-1] = '\0';                           /* terminate the disk name */
+       qdisk = stralloc(fp);
+       disk = unquote_string(qdisk);
 
        skip_whitespace(s, ch);                 /* find the device or level */
        if (ch == '\0') {
-           err_extra = "bad level";
+           err_extra = stralloc("bad level");
            goto err;
        }
        if(!isdigit((int)s[-1])) {
            fp = s - 1;
-           skip_non_whitespace(s, ch);
+           skip_quoted_string(s, ch);
            s[-1] = '\0';
-           amdevice = stralloc(fp);
+           qamdevice = stralloc(fp);
+           amdevice = unquote_string(qamdevice);
            skip_whitespace(s, ch);             /* find level number */
        }
        else {
            amdevice = stralloc(disk);
+           qamdevice = stralloc(qdisk);
        }
 
                                                /* find the level number */
        if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
-           err_extra = "bad level";
+           err_extra = stralloc("bad level");
            goto err;                           /* bad level */
        }
+       if (level < 0 || level >= DUMP_LEVELS) {
+           err_extra = stralloc("bad level");
+           goto err;
+       }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);                 /* find the dump date */
        if(ch == '\0') {
-           err_extra = "no dumpdate";
+           err_extra = stralloc("no dumpdate");
            goto err;                           /* no dumpdate */
        }
        dumpdate = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
+       (void)dumpdate;                         /* XXX: Set but not used */
 
        spindle = 0;                            /* default spindle */
 
        skip_whitespace(s, ch);                 /* find the spindle */
        if(ch != '\0') {
            if(sscanf(s - 1, "%d", &spindle) != 1) {
-               err_extra = "bad spindle";
+               err_extra = stralloc("bad spindle");
                goto err;                       /* bad spindle */
            }
            skip_integer(s, ch);
 
-           skip_whitespace(s, ch);             /* find the exclusion list */
+           skip_whitespace(s, ch);             /* find the parameters */
            if(ch != '\0') {
                if(strncmp(s-1, "OPTIONS |;",10) == 0) {
                    options = parse_options(s + 8,
@@ -281,32 +340,61 @@ char **argv;
                                            0);
                }
                else {
-                   options = alloc(sizeof(option_t));
+                   options = alloc(SIZEOF(option_t));
                    init_options(options);
-                   if(strncmp(s-1, "exclude-file=", 13) == 0) {
-                       options->exclude_file =
-                               append_sl(options->exclude_file, s+12);
-                   }
-                   if(strncmp(s-1, "exclude-list=", 13) == 0) {
-                       options->exclude_list =
-                               append_sl(options->exclude_list, s+12);
-                   }
-
-                   skip_non_whitespace(s, ch);
-                   if(ch) {
-                       err_extra = "extra text at end";
-                       goto err;               /* should have gotten to end */
+                   while (ch != '\0') {
+                       if(strncmp(s-1, "exclude-file=", 13) == 0) {
+                           qlist = unquote_string(s+12);
+                           options->exclude_file =
+                               append_sl(options->exclude_file, qlist);
+                           amfree(qlist);
+                       } else if(strncmp(s-1, "exclude-list=", 13) == 0) {
+                           options->exclude_list =
+                               append_sl(options->exclude_list, qlist);
+                           qlist = unquote_string(s+12);
+                           amfree(qlist);
+                       } else if(strncmp(s-1, "include-file=", 13) == 0) {
+                           options->include_file =
+                               append_sl(options->include_file, qlist);
+                           qlist = unquote_string(s+12);
+                           amfree(qlist);
+                       } else if(strncmp(s-1, "include-list=", 13) == 0) {
+                           options->include_list =
+                               append_sl(options->include_list, qlist);
+                           qlist = unquote_string(s+12);
+                           amfree(qlist);
+                       } else {
+                           err_extra = vstralloc("Invalid parameter (",
+                               s-1, ")", NULL);
+                           goto err;           /* should have gotten to end */
+                       }
+                       skip_quoted_string(s, ch);
+                       skip_whitespace(s, ch); /* find the inclusion list */
+                       amfree(qlist);
                    }
                }
            }
            else {
-               options = alloc(sizeof(option_t));
+               options = alloc(SIZEOF(option_t));
                init_options(options);
            }
        }
+       else {
+           options = alloc(SIZEOF(option_t));
+           init_options(options);
+       }
 
+       /*@ignore@*/
        add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options);
+       /*@end@*/
+       amfree(disk);
+       amfree(qdisk);
        amfree(amdevice);
+       amfree(qamdevice);
+    }
+    if (g_options == NULL) {
+       error("Missing OPTIONS line in sendsize input\n");
+       /*NOTREACHED*/
     }
     amfree(line);
 
@@ -333,6 +421,7 @@ char **argv;
            child_pid = wait(&child_status);
            if(child_pid == -1) {
                error("wait failed: %s", strerror(errno));
+               /*NOTREACHED*/
            }
            if(WIFSIGNALED(child_status)) {
                dbprintf(("%s: child %ld terminated with signal %d\n",
@@ -419,6 +508,7 @@ char **argv;
                exit(0);
            } else if(est->child == -1) {
                error("calc_estimates fork failed: %s", strerror(errno));
+               /*NOTREACHED*/
            }
            dumpsrunning++;                     /* parent */
        }
@@ -440,13 +530,13 @@ char **argv;
     amfree(g_options->str);
     amfree(g_options);
 
+#if defined(USE_DBMALLOC)
     malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
     if(malloc_size_1 != malloc_size_2) {
-#if defined(USE_DBMALLOC)
        malloc_list(dbfd(), malloc_hist_1, malloc_hist_2);
-#endif
     }
+#endif
 
     dbclose();
     return 0;
@@ -456,21 +546,33 @@ char **argv;
              debug_prefix_time(NULL),
              err_extra ? ": " : "",
              err_extra ? err_extra : ""));
+    amfree(err_extra);
     dbclose();
     return 1;
 }
 
 
-void add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options)
-char *disk, *amdevice, *prog, *calcprog;
-int level, spindle, program_is_wrapper;
-option_t *options;
+void
+add_diskest(
+    char *     disk,
+    char *     amdevice,
+    int                level,
+    int                spindle,
+    int                program_is_wrapper,
+    char *     prog,
+    char *     calcprog,
+    option_t * options)
 {
     disk_estimates_t *newp, *curp;
     amandates_t *amdp;
     int dumplev, estlev;
     time_t dumpdate;
 
+    if (level < 0)
+       level = 0;
+    if (level >= DUMP_LEVELS)
+       level = DUMP_LEVELS - 1;
+
     for(curp = est_list; curp != NULL; curp = curp->next) {
        if(strcmp(curp->amname, disk) == 0) {
            /* already have disk info, just note the level request */
@@ -488,13 +590,16 @@ option_t *options;
        }
     }
 
-    newp = (disk_estimates_t *) alloc(sizeof(disk_estimates_t));
-    memset(newp, 0, sizeof(*newp));
+    newp = (disk_estimates_t *) alloc(SIZEOF(disk_estimates_t));
+    memset(newp, 0, SIZEOF(*newp));
     newp->next = est_list;
     est_list = newp;
     newp->amname = stralloc(disk);
+    newp->qamname = quote_string(disk);
     newp->amdevice = stralloc(amdevice);
+    newp->qamdevice = quote_string(amdevice);
     newp->dirname = amname_to_dirname(newp->amdevice);
+    newp->qdirname = quote_string(newp->dirname);
     newp->program = stralloc(prog);
     if(calcprog != NULL)
        newp->calcprog = stralloc(calcprog);
@@ -520,12 +625,16 @@ option_t *options;
 }
 
 
-void free_estimates(est)
-disk_estimates_t *est;
+void
+free_estimates(
+    disk_estimates_t * est)
 {
     amfree(est->amname);
+    amfree(est->qamname);
     amfree(est->amdevice);
+    amfree(est->qamdevice);
     amfree(est->dirname);
+    amfree(est->qdirname);
     amfree(est->program);
     if(est->options) {
        free_sl(est->options->exclude_file);
@@ -543,13 +652,14 @@ disk_estimates_t *est;
  *
  */
 
-void calc_estimates(est)
-disk_estimates_t *est;
+void
+calc_estimates(
+    disk_estimates_t * est)
 {
-    dbprintf(("%s: calculating for amname '%s', dirname '%s', spindle %d\n",
+    dbprintf(("%s: calculating for amname %s, dirname %s, spindle %d\n",
              debug_prefix_time(NULL),
-             est->amname, est->dirname, est->spindle));
-
+             est->qamname, est->qdirname, est->spindle));
+       
     if(est->program_is_wrapper ==  1)
        wrapper_calc_estimates(est);
     else
@@ -573,14 +683,14 @@ disk_estimates_t *est;
          if (est->amdevice[0] == '/' && est->amdevice[1] == '/')
            dbprintf(("%s: Can't use CALCSIZE for samba estimate: %s %s\n",
                      debug_prefix_time(NULL),
-                     est->amname, est->dirname));
+                     est->qamname, est->qdirname));
          else
 #endif
            generic_calc_estimates(est);
 
-    dbprintf(("%s: done with amname '%s', dirname '%s', spindle %d\n",
+    dbprintf(("%s: done with amname %s dirname %s spindle %d\n",
              debug_prefix_time(NULL),
-             est->amname, est->dirname, est->spindle));
+             est->qamname, est->qdirname, est->spindle));
 }
 
 /*
@@ -589,33 +699,40 @@ disk_estimates_t *est;
  */
 
 /* local functions */
-long getsize_dump P((char *disk, char *amdevice, int level, option_t *options));
-long getsize_smbtar P((char *disk, char *amdevice, int level, option_t *options));
-long getsize_gnutar P((char *disk, char *amdevice, int level,
-                      option_t *options, time_t dumpsince));
-long getsize_wrapper P((char *program, char *disk, char *amdevice, int level,
-                       option_t *options, time_t dumpsince));
-long handle_dumpline P((char *str));
-double first_num P((char *str));
-
-void wrapper_calc_estimates(est)
-disk_estimates_t *est;
+off_t getsize_dump(char *disk, char *amdevice, int level, option_t *options);
+off_t getsize_star(char *disk, char *amdevice, int level,
+                      option_t *options, time_t dumpsince);
+off_t getsize_smbtar(char *disk, char *amdevice, int level, option_t *options);
+off_t getsize_gnutar(char *disk, char *amdevice, int level,
+                      option_t *options, time_t dumpsince);
+off_t getsize_wrapper(char *program, char *disk, char *amdevice, int level,
+                       option_t *options, time_t dumpsince);
+off_t handle_dumpline(char *str);
+double first_num(char *str);
+
+void
+wrapper_calc_estimates(
+    disk_estimates_t * est)
 {
   int level;
-  long size;
+  off_t size;
 
   for(level = 0; level < DUMP_LEVELS; level++) {
       if (est->est[level].needestimate) {
          dbprintf(("%s: getting size via wrapper for %s level %d\n",
-                   debug_prefix_time(NULL), est->amname, level));
-         size = getsize_wrapper(est->program, est->amname, est->amdevice, level, est->options,
-                                est->est[level].dumpsince);
+                   debug_prefix_time(NULL), est->qamname, level));
+         size = getsize_wrapper(est->program, est->amname, est->amdevice,
+                       level, est->options, est->est[level].dumpsince);
 
          amflock(1, "size");
 
-         fseek(stdout, (off_t)0, SEEK_SET);
+         if (fseek(stdout, 0L, SEEK_END) < 0) {
+             dbprintf(("wrapper_calc_estimates: warning - seek failed: %s\n",
+                       strerror(errno)));
+         }
 
-         printf("%s %d SIZE %ld\n", est->amname, level, size);
+         printf("%s %d SIZE " OFF_T_FMT "\n", est->qamname, level,
+                (OFF_T_FMT_TYPE)size);
          fflush(stdout);
 
          amfunlock(1, "size");
@@ -624,28 +741,36 @@ disk_estimates_t *est;
 }
 
 
-void generic_calc_estimates(est)
-disk_estimates_t *est;
+void
+generic_calc_estimates(
+    disk_estimates_t * est)
 {
     int pipefd = -1, nullfd = -1;
     char *cmd;
-    char *my_argv[DUMP_LEVELS*2+20];
+    char *my_argv[DUMP_LEVELS*2+22];
     char number[NUM_STR_SIZE];
-    int i, level, my_argc, calcpid;
+    int i, level, my_argc, status;
+    pid_t calcpid;
     int nb_exclude = 0;
     int nb_include = 0;
     char *file_exclude = NULL;
     char *file_include = NULL;
     times_t start_time;
     FILE *dumpout = NULL;
-    long size = 1;
+    off_t size = (off_t)1;
     char *line = NULL;
     char *match_expr;
 
     cmd = vstralloc(libexecdir, "/", "calcsize", versionsuffix(), NULL);
 
     my_argc = 0;
+
     my_argv[my_argc++] = stralloc("calcsize");
+    if (g_options->config)
+       my_argv[my_argc++] = stralloc(g_options->config);
+    else
+       my_argv[my_argc++] = stralloc("NOCONFIG");
+
     my_argv[my_argc++] = stralloc(est->calcprog);
 
     my_argv[my_argc++] = stralloc(est->amname);
@@ -662,9 +787,11 @@ disk_estimates_t *est;
        nb_include += est->options->include_list->nb_element;
 
     if(nb_exclude > 0)
-       file_exclude = build_exclude(est->amname, est->amdevice,est->options,0);
+       file_exclude = build_exclude(est->amname,
+               est->amdevice, est->options, 0);
     if(nb_include > 0)
-       file_include = build_include(est->amname, est->amdevice,est->options,0);
+       file_include = build_include(est->amname,
+               est->amdevice, est->options, 0);
 
     if(file_exclude) {
        my_argv[my_argc++] = stralloc("-X");
@@ -683,10 +810,10 @@ disk_estimates_t *est;
 
     for(level = 0; level < DUMP_LEVELS; level++) {
        if(est->est[level].needestimate) {
-           snprintf(number, sizeof(number), "%d", level);
+           snprintf(number, SIZEOF(number), "%d", level);
            my_argv[my_argc++] = stralloc(number); 
            dbprintf((" %s", number));
-           snprintf(number, sizeof(number),
+           snprintf(number, SIZEOF(number),
                        "%ld", (long)est->est[level].dumpsince);
            my_argv[my_argc++] = stralloc(number); 
            dbprintf((" %s", number));
@@ -706,29 +833,36 @@ disk_estimates_t *est;
     amfree(cmd);
 
     dumpout = fdopen(pipefd,"r");
-    match_expr = vstralloc(est->amname," %d SIZE %ld", NULL);
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+    match_expr = vstralloc(est->qamname," %d SIZE " OFF_T_FMT, NULL);
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        if(sscanf(line, match_expr, &level, &size) == 2) {
            printf("%s\n", line); /* write to amandad */
-           dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
+           dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
                      debug_prefix(NULL),
-                     est->amname,
+                     est->qamname,
                      level,
                      size));
        }
     }
     amfree(match_expr);
 
-    dbprintf(("%s: waiting for %s \"%s\" child\n",
-             debug_prefix_time(NULL), my_argv[0], est->amdevice));
-    wait(NULL);
-    dbprintf(("%s: after %s \"%s\" wait\n",
-             debug_prefix_time(NULL), my_argv[0], est->amdevice));
+    dbprintf(("%s: waiting for %s %s child (pid=%d)\n",
+             debug_prefix_time(NULL), my_argv[0], est->qamdevice, calcpid));
+    wait(&status);
+    dbprintf(("%s: after %s %s wait: child pid=%d status=%d\n",
+             debug_prefix_time(NULL), my_argv[0], est->qamdevice,
+             calcpid, WEXITSTATUS(status)));
 
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s: %s\n",
              debug_prefix(NULL),
-             est->amname,
+             est->qamname,
              walltime_str(timessub(curclock(), start_time))));
 
 common_exit:
@@ -739,23 +873,29 @@ common_exit:
 }
 
 
-void dump_calc_estimates(est)
-disk_estimates_t *est;
+void
+dump_calc_estimates(
+    disk_estimates_t * est)
 {
     int level;
-    long size;
+    off_t size;
 
     for(level = 0; level < DUMP_LEVELS; level++) {
        if(est->est[level].needestimate) {
            dbprintf(("%s: getting size via dump for %s level %d\n",
-                     debug_prefix_time(NULL), est->amname, level));
-           size = getsize_dump(est->amname, est->amdevice,level, est->options);
+                     debug_prefix_time(NULL), est->qamname, level));
+           size = getsize_dump(est->amname, est->amdevice,
+                       level, est->options);
 
            amflock(1, "size");
 
-           fseek(stdout, (off_t)0, SEEK_SET);
+           if (fseek(stdout, 0L, SEEK_END) < 0) {
+               dbprintf(("dump_calc_estimates: warning - seek failed: %s\n",
+                               strerror(errno)));
+           }
 
-           printf("%s %d SIZE %ld\n", est->amname, level, size);
+           printf("%s %d SIZE " OFF_T_FMT "\n",
+                  est->qamname, level, (OFF_T_FMT_TYPE)size);
            fflush(stdout);
 
            amfunlock(1, "size");
@@ -764,23 +904,28 @@ disk_estimates_t *est;
 }
 
 #ifdef SAMBA_CLIENT
-void smbtar_calc_estimates(est)
-disk_estimates_t *est;
+void
+smbtar_calc_estimates(
+    disk_estimates_t * est)
 {
     int level;
-    long size;
+    off_t size;
 
     for(level = 0; level < DUMP_LEVELS; level++) {
        if(est->est[level].needestimate) {
            dbprintf(("%s: getting size via smbclient for %s level %d\n",
-                     debug_prefix_time(NULL), est->amname, level));
+                     debug_prefix_time(NULL), est->qamname, level));
            size = getsize_smbtar(est->amname, est->amdevice, level, est->options);
 
            amflock(1, "size");
 
-           fseek(stdout, (off_t)0, SEEK_SET);
+           if (fseek(stdout, 0L, SEEK_END) < 0) {
+               dbprintf(("smbtar_calc_estimates: warning - seek failed: %s\n",
+                               strerror(errno)));
+           }
 
-           printf("%s %d SIZE %ld\n", est->amname, level, size);
+           printf("%s %d SIZE " OFF_T_FMT "\n",
+                  est->qamname, level, (OFF_T_FMT_TYPE)size);
            fflush(stdout);
 
            amfunlock(1, "size");
@@ -790,24 +935,29 @@ disk_estimates_t *est;
 #endif
 
 #ifdef GNUTAR
-void gnutar_calc_estimates(est)
-disk_estimates_t *est;
+void
+gnutar_calc_estimates(
+    disk_estimates_t * est)
 {
   int level;
-  long size;
+  off_t size;
 
   for(level = 0; level < DUMP_LEVELS; level++) {
       if (est->est[level].needestimate) {
          dbprintf(("%s: getting size via gnutar for %s level %d\n",
-                   debug_prefix_time(NULL), est->amname, level));
+                   debug_prefix_time(NULL), est->qamname, level));
          size = getsize_gnutar(est->amname, est->amdevice, level,
                                est->options, est->est[level].dumpsince);
 
          amflock(1, "size");
 
-         fseek(stdout, (off_t)0, SEEK_SET);
+         if (fseek(stdout, 0L, SEEK_END) < 0) {
+             dbprintf(("gnutar_calc_estimates: warning - seek failed: %s\n",
+                               strerror(errno)));
+         }
 
-         printf("%s %d SIZE %ld\n", est->amname, level, size);
+         printf("%s %d SIZE " OFF_T_FMT "\n",
+                est->qamname, level, (OFF_T_FMT_TYPE)size);
          fflush(stdout);
 
          amfunlock(1, "size");
@@ -821,12 +971,13 @@ typedef struct regex_s {
     int scale;
 } regex_t;
 
+/*@ignore@*/
 regex_t re_size[] = {
 #ifdef DUMP
     {"  DUMP: estimated -*[0-9][0-9]* tape blocks", 1024},
     {"  DUMP: [Ee]stimated [0-9][0-9]* blocks", 512},
-    {"  DUMP: [Ee]stimated [0-9][0-9]* bytes", 1},            /* Ultrix 4.4 */
-    {" UFSDUMP: estimated [0-9][0-9]* blocks", 512},           /* NEC EWS-UX */
+    {"  DUMP: [Ee]stimated [0-9][0-9]* bytes", 1},             /* Ultrix 4.4 */
+    {" UFSDUMP: estimated [0-9][0-9]* blocks", 512},           /* NEC EWS-UX */
     {"dump: Estimate: [0-9][0-9]* tape blocks", 1024},             /* OSF/1 */
     {"backup: There are an estimated [0-9][0-9]* tape blocks.",1024}, /* AIX */
     {"backup: estimated [0-9][0-9]* 1k blocks", 1024},               /* AIX */
@@ -834,27 +985,27 @@ regex_t re_size[] = {
     {"backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape(s)",1024},  /* AIX */
     {"backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume(s)",1024},  /* AIX */
     {"dump: Estimate: [0-9][0-9]* blocks being output to pipe",1024},
-                                                              /* DU 4.0 dump */
-    {"dump: Dumping [0-9][0-9]* bytes, ", 1},                /* DU 4.0 vdump */
-    {"DUMP: estimated [0-9][0-9]* KB output", 1024},                 /* HPUX */
-    {"DUMP: estimated [0-9][0-9]* KB\\.", 1024},                 /* NetApp */
-    {"  UFSDUMP: estimated [0-9][0-9]* blocks", 512},               /* Sinix */
+                                                             /* DU 4.0 dump  */
+    {"dump: Dumping [0-9][0-9]* bytes, ", 1},                /* DU 4.0 vdump */
+    {"DUMP: estimated [0-9][0-9]* KB output", 1024},                 /* HPUX */
+    {"DUMP: estimated [0-9][0-9]* KB\\.", 1024},                   /* NetApp */
+    {"  UFSDUMP: estimated [0-9][0-9]* blocks", 512},               /* Sinix */
 
 #ifdef HAVE_DUMP_ESTIMATE
     {"[0-9][0-9]* blocks, [0-9][0-9]*.[0-9][0-9]* volumes", 1024},
-                                                          /* DU 3.2g dump -E */
-    {"^[0-9][0-9]* blocks$", 1024},                      /* DU 4.0 dump  -E */
-    {"^[0-9][0-9]*$", 1},                             /* Solaris ufsdump -S */
+                                                          /* DU 3.2g dump -E */
+    {"^[0-9][0-9]* blocks$", 1024},                       /* DU 4.0 dump  -E */
+    {"^[0-9][0-9]*$", 1},                              /* Solaris ufsdump -S */
 #endif
 #endif
 
 #ifdef VDUMP
-    {"vdump: Dumping [0-9][0-9]* bytes, ", 1},               /* OSF/1 vdump */
+    {"vdump: Dumping [0-9][0-9]* bytes, ", 1},                /* OSF/1 vdump */
 #endif
     
 #ifdef VXDUMP
-    {"vxdump: estimated [0-9][0-9]* blocks", 512},          /* HPUX's vxdump */
-    {"  VXDUMP: estimated [0-9][0-9]* blocks", 512},                /* Sinix */
+    {"vxdump: estimated [0-9][0-9]* blocks", 512},          /* HPUX's vxdump */
+    {"  VXDUMP: estimated [0-9][0-9]* blocks", 512},                /* Sinix */
 #endif
 
 #ifdef XFSDUMP
@@ -877,16 +1028,18 @@ regex_t re_size[] = {
 
     { NULL, 0 }
 };
-
-
-long getsize_dump(disk, amdevice, level, options)
-    char *disk, *amdevice;
-    int level;
-    option_t *options;
+/*@end@*/
+
+off_t
+getsize_dump(
+    char       *disk,
+    char       *amdevice,
+    int                level,
+    option_t * options)
 {
     int pipefd[2], nullfd, stdoutfd, killctl[2];
     pid_t dumppid;
-    long size;
+    off_t size;
     FILE *dumpout;
     char *dumpkeys = NULL;
     char *device = NULL;
@@ -898,29 +1051,55 @@ long getsize_dump(disk, amdevice, level, options)
     char level_str[NUM_STR_SIZE];
     int s;
     times_t start_time;
+    char *qdisk = quote_string(disk);
+    char *qdevice;
+    char *config;
+#ifdef DUMP
+    int is_rundump = 1;
+#endif
+
+    (void)options;     /* Quiet unused parameter warning */
 
-    snprintf(level_str, sizeof(level_str), "%d", level);
+    (void)getsize_smbtar;      /* Quiet unused parameter warning */
+
+    snprintf(level_str, SIZEOF(level_str), "%d", level);
 
     device = amname_to_devname(amdevice);
+    qdevice = quote_string(device);
     fstype = amname_to_fstype(amdevice);
 
-    dbprintf(("%s: calculating for device '%s' with '%s'\n",
-             debug_prefix_time(NULL), device, fstype));
+    dbprintf(("%s: calculating for device %s with %s\n",
+             debug_prefix_time(NULL), qdevice, fstype));
 
     cmd = vstralloc(libexecdir, "/rundump", versionsuffix(), NULL);
     rundump_cmd = stralloc(cmd);
-
+    if (g_options->config)
+        config = g_options->config;
+    else
+        config = "NOCONFIG";
     if ((stdoutfd = nullfd = open("/dev/null", O_RDWR)) == -1) {
        dbprintf(("getsize_dump could not open /dev/null: %s\n",
-                 strerror(errno)));
+                 strerror(errno)));
        amfree(cmd);
        amfree(rundump_cmd);
        amfree(fstype);
        amfree(device);
+       amfree(qdevice);
+       amfree(qdisk);
        return(-1);
     }
     pipefd[0] = pipefd[1] = killctl[0] = killctl[1] = -1;
-    pipe(pipefd);
+    if (pipe(pipefd) < 0) {
+       dbprintf(("getsize_dump could create data pipes: %s\n",
+                 strerror(errno)));
+       amfree(cmd);
+       amfree(rundump_cmd);
+       amfree(fstype);
+       amfree(device);
+       amfree(qdevice);
+       amfree(qdisk);
+       return(-1);
+    }
 
 #ifdef XFSDUMP                                         /* { */
 #ifdef DUMP                                            /* { */
@@ -929,9 +1108,9 @@ long getsize_dump(disk, amdevice, level, options)
     if (1)
 #endif                                                 /* } */
     {
-        name = stralloc(" (xfsdump)");
+       name = stralloc(" (xfsdump)");
        dbprintf(("%s: running \"%s%s -F -J -l %s - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, level_str, device));
+                 debug_prefix_time(NULL), cmd, name, level_str, qdevice));
     }
     else
 #endif                                                 /* } */
@@ -943,14 +1122,16 @@ long getsize_dump(disk, amdevice, level, options)
 #endif                                                 /* } */
     {
 #ifdef USE_RUNDUMP
-        name = stralloc(" (vxdump)");
+       name = stralloc(" (vxdump)");
 #else
        name = stralloc("");
        cmd = newstralloc(cmd, VXDUMP);
+       config = skip_argument;
+       is_rundump = 0;
 #endif
        dumpkeys = vstralloc(level_str, "s", "f", NULL);
-        dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+       dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
     }
     else
 #endif                                                 /* } */
@@ -963,10 +1144,12 @@ long getsize_dump(disk, amdevice, level, options)
     {
        name = stralloc(" (vdump)");
        amfree(device);
+       amfree(qdevice);
        device = amname_to_dirname(amdevice);
+       qdevice = quote_string(device);
        dumpkeys = vstralloc(level_str, "b", "f", NULL);
        dbprintf(("%s: running \"%s%s %s 60 - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
     }
     else
 #endif                                                 /* } */
@@ -981,12 +1164,14 @@ long getsize_dump(disk, amdevice, level, options)
 # else                                                 /* } { */
        name = stralloc("");
        cmd = newstralloc(cmd, DUMP);
+        config = skip_argument;
+       is_rundump = 0;
 # endif                                                        /* } */
 
 # ifdef AIX_BACKUP                                     /* { */
        dumpkeys = vstralloc("-", level_str, "f", NULL);
        dbprintf(("%s: running \"%s%s %s - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
 # else                                                 /* } { */
        dumpkeys = vstralloc(level_str,
 #  ifdef HAVE_DUMP_ESTIMATE                            /* { */
@@ -1003,10 +1188,10 @@ long getsize_dump(disk, amdevice, level, options)
 
 #  ifdef HAVE_HONOR_NODUMP                             /* { */
        dbprintf(("%s: running \"%s%s %s 0 1048576 - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
 #  else                                                        /* } { */
        dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
 #  endif                                               /* } */
 # endif                                                        /* } */
     }
@@ -1014,9 +1199,15 @@ long getsize_dump(disk, amdevice, level, options)
 #endif                                                 /* } */
     {
        error("no dump program available");
+       /*NOTREACHED*/
     }
 
-    pipe(killctl);
+    if (pipe(killctl) < 0) {
+       dbprintf(("%s: Could not create pipe: %s\n",
+               debug_prefix(NULL), strerror(errno)));
+       /* Message will be printed later... */
+       killctl[0] = killctl[1] = -1;
+    }
 
     start_time = curclock();
     switch(dumppid = fork()) {
@@ -1027,6 +1218,8 @@ long getsize_dump(disk, amdevice, level, options)
        amfree(cmd);
        amfree(rundump_cmd);
        amfree(device);
+       amfree(qdevice);
+       amfree(qdisk);
        amfree(name);
        amfree(fstype);
        return -1;
@@ -1036,8 +1229,7 @@ long getsize_dump(disk, amdevice, level, options)
        if(SETPGRP == -1)
            SETPGRP_FAILED();
        else if (killctl[0] == -1 || killctl[1] == -1)
-           dbprintf(("%s: pipe for killpgrp failed, trying without killpgrp\n",
-                     debug_prefix(NULL)));
+           dbprintf(("%s: Trying without killpgrp\n", debug_prefix(NULL)));
        else {
            switch(fork()) {
            case -1:
@@ -1047,6 +1239,7 @@ long getsize_dump(disk, amdevice, level, options)
 
            default:
            {
+               char *config;
                char *killpgrp_cmd = vstralloc(libexecdir, "/killpgrp",
                                               versionsuffix(), NULL);
                dbprintf(("%s: running %s\n",
@@ -1058,7 +1251,12 @@ long getsize_dump(disk, amdevice, level, options)
                close(pipefd[1]);
                close(killctl[1]);
                close(nullfd);
-               execle(killpgrp_cmd, killpgrp_cmd, (char *)0, safe_env());
+               if (g_options->config)
+                   config = g_options->config;
+               else
+                   config = "NOCONFIG";
+               execle(killpgrp_cmd, killpgrp_cmd, config, (char *)0,
+                      safe_env());
                dbprintf(("%s: cannot execute %s: %s\n",
                          debug_prefix(NULL), killpgrp_cmd, strerror(errno)));
                exit(-1);
@@ -1084,8 +1282,12 @@ long getsize_dump(disk, amdevice, level, options)
 #else
        if (1)
 #endif
-           execle(cmd, "xfsdump", "-F", "-J", "-l", level_str, "-", device,
-                  (char *)0, safe_env());
+           if (is_rundump)
+               execle(cmd, "rundump", config, "xfsdump", "-F", "-J", "-l",
+                      level_str, "-", device, (char *)0, safe_env());
+           else
+               execle(cmd, "xfsdump", "-F", "-J", "-l",
+                      level_str, "-", device, (char *)0, safe_env());
        else
 #endif
 #ifdef VXDUMP
@@ -1094,8 +1296,12 @@ long getsize_dump(disk, amdevice, level, options)
 #else
        if (1)
 #endif
-           execle(cmd, "vxdump", dumpkeys, "1048576", "-", device, (char *)0,
-                  safe_env());
+           if (is_rundump)
+               execle(cmd, "rundump", config, "vxdump", dumpkeys, "1048576",
+                      "-", device, (char *)0, safe_env());
+           else
+               execle(cmd, "vxdump", dumpkeys, "1048576", "-",
+                      device, (char *)0, safe_env());
        else
 #endif
 #ifdef VDUMP
@@ -1104,24 +1310,42 @@ long getsize_dump(disk, amdevice, level, options)
 #else
        if (1)
 #endif
-           execle(cmd, "vdump", dumpkeys, "60", "-", device, (char *)0,
-                  safe_env());
+           if (is_rundump)
+               execle(cmd, "rundump", config, "vdump", dumpkeys, "60", "-",
+                      device, (char *)0, safe_env());
+           else
+               execle(cmd, "vdump", dumpkeys, "60", "-",
+                      device, (char *)0, safe_env());
        else
 #endif
 #ifdef DUMP
 # ifdef AIX_BACKUP
-           execle(cmd, "backup", dumpkeys, "-", device, (char *)0, safe_env());
+           if (is_rundump)
+               execle(cmd, "rundump", config, "backup", dumpkeys, "-",
+                      device, (char *)0, safe_env());
+           else
+               execle(cmd, "backup", dumpkeys, "-",
+                      device, (char *)0, safe_env());
 # else
-           execle(cmd, "dump", dumpkeys, 
+           if (is_rundump) {
+               execle(cmd, "rundump", config, "dump", dumpkeys, 
 #ifdef HAVE_HONOR_NODUMP
-                  "0",
+                      "0",
 #endif
-                  "1048576", "-", device, (char *)0, safe_env());
+                      "1048576", "-", device, (char *)0, safe_env());
+           } else {
+               execle(cmd, "dump", dumpkeys, 
+#ifdef HAVE_HONOR_NODUMP
+                      "0",
+#endif
+                      "1048576", "-", device, (char *)0, safe_env());
 # endif
+           }
 #endif
        {
            error("exec %s failed or no dump program available: %s",
                  cmd, strerror(errno));
+           /*NOTREACHED*/
        }
     }
 
@@ -1132,13 +1356,24 @@ long getsize_dump(disk, amdevice, level, options)
     if (killctl[0] != -1)
        aclose(killctl[0]);
     dumpout = fdopen(pipefd[0],"r");
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
        size = handle_dumpline(line);
-       if(size > -1) {
+       if(size > (off_t)-1) {
            amfree(line);
-           if((line = agets(dumpout)) != NULL) {
+           while ((line = agets(dumpout)) != NULL) {
+               if (line[0] != '\0')
+                   break;
+               amfree(line);
+           }
+           if (line != NULL) {
                dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
            }
            break;
@@ -1149,23 +1384,23 @@ long getsize_dump(disk, amdevice, level, options)
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s level %d: %s\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              walltime_str(timessub(curclock(), start_time))));
-    if(size == -1) {
+    if(size == (off_t)-1) {
        dbprintf(("%s: no size line match in %s%s output for \"%s\"\n",
                  debug_prefix(NULL), cmd, name, disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
        dbprintf(("%s: Run %s%s manually to check for errors\n",
                    debug_prefix(NULL), cmd, name));
-    } else if(size == 0 && level == 0) {
+    } else if(size == (off_t)0 && level == 0) {
        dbprintf(("%s: possible %s%s problem -- is \"%s\" really empty?\n",
                  debug_prefix(NULL), cmd, name, disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
     } else {
            dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              size));
     }
@@ -1211,10 +1446,10 @@ long getsize_dump(disk, amdevice, level, options)
     }
 
     dbprintf(("%s: waiting for %s%s \"%s\" child\n",
-             debug_prefix_time(NULL), cmd, name, disk));
+             debug_prefix_time(NULL), cmd, name, qdisk));
     wait(NULL);
-    dbprintf(("%s: after %s%s \"%s\" wait\n",
-             debug_prefix_time(NULL), cmd, name, disk));
+    dbprintf(("%s: after %s%s %s wait\n",
+             debug_prefix_time(NULL), cmd, name, qdisk));
 
  terminated:
 
@@ -1222,6 +1457,8 @@ long getsize_dump(disk, amdevice, level, options)
     afclose(dumpout);
 
     amfree(device);
+    amfree(qdevice);
+    amfree(qdisk);
     amfree(fstype);
 
     amfree(cmd);
@@ -1231,24 +1468,29 @@ long getsize_dump(disk, amdevice, level, options)
 }
 
 #ifdef SAMBA_CLIENT
-long getsize_smbtar(disk, amdevice, level, optionns)
-    char *disk, *amdevice;
-    int level;
-    option_t *optionns;
+off_t
+getsize_smbtar(
+    char       *disk,
+    char       *amdevice,
+    int                level,
+    option_t * options)
 {
     int pipefd = -1, nullfd = -1, passwdfd = -1;
-    int dumppid;
-    long size;
+    pid_t dumppid;
+    off_t size;
     FILE *dumpout;
     char *tarkeys, *sharename, *user_and_password = NULL, *domain = NULL;
     char *share = NULL, *subdir = NULL;
-    int lpass;
+    size_t lpass;
     char *pwtext;
-    int pwtext_len;
+    size_t pwtext_len;
     char *line;
     char *pw_fd_env;
     times_t start_time;
     char *error_pn = NULL;
+    char *qdisk = quote_string(disk);
+
+    (void)options;     /* Quiet unused parameter warning */
 
     error_pn = stralloc2(get_pname(), "-smbclient");
 
@@ -1258,14 +1500,16 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        amfree(subdir);
        set_pname(error_pn);
        amfree(error_pn);
-       error("cannot parse disk entry '%s' for share/subdir", disk);
+       error("cannot parse disk entry %s for share/subdir", qdisk);
+       /*NOTREACHED*/
     }
     if ((subdir) && (SAMBA_VERSION < 2)) {
        amfree(share);
        amfree(subdir);
        set_pname(error_pn);
        amfree(error_pn);
-       error("subdirectory specified for share '%s' but samba not v2 or better", disk);
+       error("subdirectory specified for share %s but samba not v2 or better", qdisk);
+       /*NOTREACHED*/
     }
     if ((user_and_password = findpass(share, &domain)) == NULL) {
 
@@ -1276,10 +1520,11 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        set_pname(error_pn);
        amfree(error_pn);
        error("cannot find password for %s", disk);
+       /*NOTREACHED*/
     }
     lpass = strlen(user_and_password);
     if ((pwtext = strchr(user_and_password, '%')) == NULL) {
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
        if(domain) {
            memset(domain, '\0', strlen(domain));
@@ -1288,11 +1533,12 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        set_pname(error_pn);
        amfree(error_pn);
        error("password field not \'user%%pass\' for %s", disk);
+       /*NOTREACHED*/
     }
     *pwtext++ = '\0';
     pwtext_len = strlen(pwtext);
     if ((sharename = makesharename(share, 0)) == NULL) {
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
        if(domain) {
            memset(domain, '\0', strlen(domain));
@@ -1301,9 +1547,10 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        set_pname(error_pn);
        amfree(error_pn);
        error("cannot make share name of %s", share);
+       /*NOTREACHED*/
     }
     if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
        if(domain) {
            memset(domain, '\0', strlen(domain));
@@ -1314,6 +1561,7 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        amfree(sharename);
        error("could not open /dev/null: %s\n",
              strerror(errno));
+       /*NOTREACHED*/
     }
 
 #if SAMBA_VERSION >= 2
@@ -1357,17 +1605,18 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        amfree(domain);
     }
     aclose(nullfd);
-    if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, pwtext_len) < 0) {
+    if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, (size_t)pwtext_len) < 0) {
        int save_errno = errno;
 
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
        aclose(passwdfd);
        set_pname(error_pn);
        amfree(error_pn);
        error("password write failed: %s", strerror(save_errno));
+       /*NOTREACHED*/
     }
-    memset(user_and_password, '\0', lpass);
+    memset(user_and_password, '\0', (size_t)lpass);
     amfree(user_and_password);
     aclose(passwdfd);
     amfree(sharename);
@@ -1375,13 +1624,24 @@ long getsize_smbtar(disk, amdevice, level, optionns)
     amfree(subdir);
     amfree(error_pn);
     dumpout = fdopen(pipefd,"r");
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
        size = handle_dumpline(line);
        if(size > -1) {
            amfree(line);
-           if((line = agets(dumpout)) != NULL) {
+           while ((line = agets(dumpout)) != NULL) {
+               if (line[0] != '\0')
+                   break;
+               amfree(line);
+           }
+           if(line != NULL) {
                dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
            }
            break;
@@ -1392,50 +1652,54 @@ long getsize_smbtar(disk, amdevice, level, optionns)
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s level %d: %s\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              walltime_str(timessub(curclock(), start_time))));
-    if(size == -1) {
+    if(size == (off_t)-1) {
        dbprintf(("%s: no size line match in %s output for \"%s\"\n",
                  debug_prefix(NULL), SAMBA_CLIENT, disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
-    } else if(size == 0 && level == 0) {
+    } else if(size == (off_t)0 && level == 0) {
        dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
                  debug_prefix(NULL), SAMBA_CLIENT, disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
     }
     dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              size));
 
     kill(-dumppid, SIGTERM);
 
     dbprintf(("%s: waiting for %s \"%s\" child\n",
-             debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+             debug_prefix_time(NULL), SAMBA_CLIENT, qdisk));
     wait(NULL);
-    dbprintf(("%s: after %s \"%s\" wait\n",
-             debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+    dbprintf(("%s: after %s %s wait\n",
+             debug_prefix_time(NULL), SAMBA_CLIENT, qdisk));
 
     afclose(dumpout);
     pipefd = -1;
 
     amfree(error_pn);
+    amfree(qdisk);
 
     return size;
 }
 #endif
 
 #ifdef GNUTAR
-long getsize_gnutar(disk, amdevice, level, options, dumpsince)
-char *disk, *amdevice;
-int level;
-option_t *options;
-time_t dumpsince;
+off_t
+getsize_gnutar(
+    char       *disk,
+    char       *amdevice,
+    int                level,
+    option_t * options,
+    time_t     dumpsince)
 {
-    int pipefd = -1, nullfd = -1, dumppid;
-    long size = -1;
+    int pipefd = -1, nullfd = -1;
+    pid_t dumppid;
+    off_t size = (off_t)-1;
     FILE *dumpout = NULL;
     char *incrname = NULL;
     char *basename = NULL;
@@ -1457,6 +1721,8 @@ time_t dumpsince;
     int infd, outfd;
     ssize_t nb;
     char buf[32768];
+    char *qdisk = quote_string(disk);
+    char *gnutar_list_dir;
 
     if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
     if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
@@ -1466,17 +1732,19 @@ time_t dumpsince;
     if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 0);
     if(nb_include > 0) file_include = build_include(disk, amdevice, options, 0);
 
-    my_argv = alloc(sizeof(char *) * 21);
+    my_argv = alloc(SIZEOF(char *) * 22);
     i = 0;
 
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
-    {
+    gnutar_list_dir = client_getconf_str(CLN_GNUTAR_LIST_DIR);
+    if (strlen(gnutar_list_dir) == 0)
+       gnutar_list_dir = NULL;
+    if (gnutar_list_dir) {
        char number[NUM_STR_SIZE];
        char *s;
        int ch;
        int baselevel;
 
-       basename = vstralloc(GNUTAR_LISTED_INCREMENTAL_DIR,
+       basename = vstralloc(gnutar_list_dir,
                             "/",
                             g_options->hostname,
                             disk,
@@ -1485,12 +1753,12 @@ time_t dumpsince;
         * The loop starts at the first character of the host name,
         * not the '/'.
         */
-       s = basename + sizeof(GNUTAR_LISTED_INCREMENTAL_DIR);
+       s = basename + strlen(gnutar_list_dir) + 1;
        while((ch = *s++) != '\0') {
            if(ch == '/' || isspace(ch)) s[-1] = '_';
        }
 
-       snprintf(number, sizeof(number), "%d", level);
+       snprintf(number, SIZEOF(number), "%d", level);
        incrname = vstralloc(basename, "_", number, ".new", NULL);
        unlink(incrname);
 
@@ -1503,7 +1771,7 @@ time_t dumpsince;
        infd = -1;
        while (infd == -1) {
            if (--baselevel >= 0) {
-               snprintf(number, sizeof(number), "%d", baselevel);
+               snprintf(number, SIZEOF(number), "%d", baselevel);
                inputname = newvstralloc(inputname,
                                         basename, "_", number, NULL);
            } else {
@@ -1529,8 +1797,8 @@ time_t dumpsince;
            goto common_exit;
        }
 
-       while ((nb = read(infd, &buf, sizeof(buf))) > 0) {
-           if (fullwrite(outfd, &buf, nb) < nb) {
+       while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) {
+           if (fullwrite(outfd, &buf, (size_t)nb) < nb) {
                dbprintf(("%s: writing to %s: %s\n",
                           debug_prefix(NULL), incrname, strerror(errno)));
                goto common_exit;
@@ -1557,21 +1825,23 @@ time_t dumpsince;
        amfree(inputname);
        amfree(basename);
     }
-#endif
 
     gmtm = gmtime(&dumpsince);
-    snprintf(dumptimestr, sizeof(dumptimestr),
+    snprintf(dumptimestr, SIZEOF(dumptimestr),
                "%04d-%02d-%02d %2d:%02d:%02d GMT",
                gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
                gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);
 
     dirname = amname_to_dirname(amdevice);
 
-
-
-#ifdef GNUTAR
     cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
+    my_argv[i++] = "runtar";
+    if (g_options->config)
+       my_argv[i++] = g_options->config;
+    else
+       my_argv[i++] = "NOCONFIG";
 
+#ifdef GNUTAR
     my_argv[i++] = GNUTAR;
 #else
     my_argv[i++] = "tar";
@@ -1582,15 +1852,14 @@ time_t dumpsince;
     my_argv[i++] = "--directory";
     my_argv[i++] = dirname;
     my_argv[i++] = "--one-file-system";
-    my_argv[i++] = "--numeric-owner";
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
-    my_argv[i++] = "--listed-incremental";
-    my_argv[i++] = incrname;
-#else
-    my_argv[i++] = "--incremental";
-    my_argv[i++] = "--newer";
-    my_argv[i++] = dumptimestr;
-#endif
+    if (gnutar_list_dir) {
+           my_argv[i++] = "--listed-incremental";
+           my_argv[i++] = incrname;
+    } else {
+       my_argv[i++] = "--incremental";
+       my_argv[i++] = "--newer";
+       my_argv[i++] = dumptimestr;
+    }
 #ifdef ENABLE_GNUTAR_ATIME_PRESERVE
     /* --atime-preserve causes gnutar to call
      * utime() after reading files in order to
@@ -1619,21 +1888,35 @@ time_t dumpsince;
 
     start_time = curclock();
 
-    nullfd = open("/dev/null", O_RDWR);
+    if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
+       dbprintf(("Cannot access /dev/null : %s\n", strerror(errno)));
+       goto common_exit;
+    }
+
     dumppid = pipespawnv(cmd, STDERR_PIPE, &nullfd, &nullfd, &pipefd, my_argv);
-    amfree(cmd);
-    amfree(file_exclude);
-    amfree(file_include);
 
     dumpout = fdopen(pipefd,"r");
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
        size = handle_dumpline(line);
-       if(size > -1) {
+       if(size > (off_t)-1) {
            amfree(line);
-           if((line = agets(dumpout)) != NULL) {
+           while ((line = agets(dumpout)) != NULL) {
+               if (line[0] != '\0') {
+                   break;
+               }
+               amfree(line);
+           }
+           if (line != NULL) {
                dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+               break;
            }
            break;
        }
@@ -1643,31 +1926,31 @@ time_t dumpsince;
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s level %d: %s\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              walltime_str(timessub(curclock(), start_time))));
-    if(size == -1) {
+    if(size == (off_t)-1) {
        dbprintf(("%s: no size line match in %s output for \"%s\"\n",
                  debug_prefix(NULL), my_argv[0], disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
-    } else if(size == 0 && level == 0) {
+    } else if(size == (off_t)0 && level == 0) {
        dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
                  debug_prefix(NULL), my_argv[0], disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
     }
     dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              size));
 
     kill(-dumppid, SIGTERM);
 
     dbprintf(("%s: waiting for %s \"%s\" child\n",
-             debug_prefix_time(NULL), my_argv[0], disk));
+             debug_prefix_time(NULL), my_argv[0], qdisk));
     wait(NULL);
-    dbprintf(("%s: after %s \"%s\" wait\n",
-             debug_prefix_time(NULL), my_argv[0], disk));
+    dbprintf(("%s: after %s %s wait\n",
+             debug_prefix_time(NULL), my_argv[0], qdisk));
 
 common_exit:
 
@@ -1679,6 +1962,10 @@ common_exit:
     amfree(dirname);
     amfree(inputname);
     amfree(my_argv);
+    amfree(qdisk);
+    amfree(cmd);
+    amfree(file_exclude);
+    amfree(file_include);
 
     aclose(nullfd);
     afclose(dumpout);
@@ -1689,14 +1976,18 @@ common_exit:
 }
 #endif
 
-long getsize_wrapper(program, disk, amdevice, level, options, dumpsince)
-char *program, *disk, *amdevice;
-int level;
-option_t *options;
-time_t dumpsince;
+off_t
+getsize_wrapper(
+    char       *program,
+    char       *disk,
+    char       *amdevice,
+    int                level,
+    option_t * options,
+    time_t     dumpsince)
 {
-    int pipefd[2], nullfd, dumppid;
-    long size;
+    int pipefd[2], nullfd;
+    pid_t dumppid;
+    off_t size = (off_t)-1;
     FILE *dumpout;
     char *line = NULL;
     char *cmd = NULL;
@@ -1705,11 +1996,13 @@ time_t dumpsince;
     int  i, j;
     char *argvchild[10];
     char *newoptstr = NULL;
-    long size1, size2;
+    off_t size1, size2;
     times_t start_time;
+    char *qdisk = quote_string(disk);
+    char *qamdevice = quote_string(amdevice);
 
     gmtm = gmtime(&dumpsince);
-    snprintf(dumptimestr, sizeof(dumptimestr),
+    snprintf(dumptimestr, SIZEOF(dumptimestr),
                "%04d-%02d-%02d %2d:%02d:%02d GMT",
                gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
                gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);
@@ -1723,7 +2016,7 @@ time_t dumpsince;
        argvchild[i++] = "full";
     else {
        char levelstr[NUM_STR_SIZE];
-       snprintf(levelstr,sizeof(levelstr),"%d",level);
+       snprintf(levelstr,SIZEOF(levelstr),"%d",level);
        argvchild[i++] = "level";
        argvchild[i++] = levelstr;
     }
@@ -1737,14 +2030,23 @@ time_t dumpsince;
        dbprintf((" %s", argvchild[j]));
     }
     dbprintf(("\n"));
-    nullfd = open("/dev/null", O_RDWR);
-    pipe(pipefd);
+
+    if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
+       dbprintf(("Cannot access /dev/null : %s\n", strerror(errno)));
+       goto common_exit;
+    }
+
+    if (pipe(pipefd) < 0) {
+       dbprintf(("getsize_wrapper could create data pipes: %s\n",
+                 strerror(errno)));
+       goto common_exit;
+    }
 
     start_time = curclock();
 
     switch(dumppid = fork()) {
     case -1:
-      size = -1;
+      size = (off_t)-1;
       goto common_exit;
     default:
       break; /* parent */
@@ -1756,21 +2058,35 @@ time_t dumpsince;
 
       execve(cmd, argvchild, safe_env());
       error("exec %s failed: %s", cmd, strerror(errno));
+      /*NOTREACHED*/
     }
     amfree(newoptstr);
 
     aclose(pipefd[1]);
     dumpout = fdopen(pipefd[0],"r");
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
-       i = sscanf(line,"%ld %ld",&size1, &size2);
+       i = sscanf(line, OFF_T_FMT " " OFF_T_FMT,
+               (OFF_T_FMT_TYPE *)&size1, 
+               (OFF_T_FMT_TYPE *)&size2);
        if(i == 2) {
            size = size1 * size2;
        }
        if(size > -1) {
            amfree(line);
-           if((line = agets(dumpout)) != NULL) {
+           while ((line = agets(dumpout)) != NULL) {
+               if (line[0] != '\0')
+                   break;
+               amfree(line);
+           }
+           if(line != NULL) {
                dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
            }
            break;
@@ -1781,31 +2097,31 @@ time_t dumpsince;
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s level %d: %s\n",
              debug_prefix(NULL),
-             amdevice,
+             qamdevice,
              level,
              walltime_str(timessub(curclock(), start_time))));
-    if(size == -1) {
+    if(size == (off_t)-1) {
        dbprintf(("%s: no size line match in %s output for \"%s\"\n",
-                 debug_prefix(NULL), cmd, disk));
+                 debug_prefix(NULL), cmd, qdisk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
-    } else if(size == 0 && level == 0) {
+    } else if(size == (off_t)0 && level == 0) {
        dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
-                 debug_prefix(NULL), cmd, disk));
+                 debug_prefix(NULL), cmd, qdisk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
     }
-    dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
+    dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
              debug_prefix(NULL),
-             amdevice,
+             qamdevice,
              level,
              size));
 
     kill(-dumppid, SIGTERM);
 
     dbprintf(("%s: waiting for %s \"%s\" child\n",
-             debug_prefix_time(NULL), cmd, disk));
+             debug_prefix_time(NULL), cmd, qdisk));
     wait(NULL);
-    dbprintf(("%s: after %s \"%s\" wait\n",
-             debug_prefix_time(NULL), cmd, disk));
+    dbprintf(("%s: after %s %s wait\n",
+             debug_prefix_time(NULL), cmd, qdisk));
 
     aclose(nullfd);
     afclose(dumpout);
@@ -1814,15 +2130,19 @@ common_exit:
 
     amfree(cmd);
     amfree(newoptstr);
+    amfree(qdisk);
+    amfree(qamdevice);
     return size;
 }
 
 
-double first_num(str)
-char *str;
 /*
  * Returns the value of the first integer in a string.
  */
+
+double
+first_num(
+    char *     str)
 {
     char *start;
     int ch;
@@ -1834,27 +2154,32 @@ char *str;
     while(isdigit(ch) || (ch == '.')) ch = *str++;
     str[-1] = '\0';
     d = atof(start);
-    str[-1] = ch;
+    str[-1] = (char)ch;
     return d;
 }
 
 
-long handle_dumpline(str)
-char *str;
 /*
  * Checks the dump output line against the error and size regex tables.
  */
+
+off_t
+handle_dumpline(
+    char *     str)
 {
     regex_t *rp;
     double size;
 
     /* check for size match */
+    /*@ignore@*/
     for(rp = re_size; rp->regex != NULL; rp++) {
        if(match(rp->regex, str)) {
            size = ((first_num(str)*rp->scale+1023.0)/1024.0);
-           if(size < 0) size = 1;              /* found on NeXT -- sigh */
-           return (long) size;
+           if(size < 0.0)
+               size = 1.0;             /* found on NeXT -- sigh */
+           return (off_t)size;
        }
     }
-    return -1;
+    /*@end@*/
+    return (off_t)-1;
 }
index d2ee5ea56d737adce0eaefcf1dca78fb7ea22a54..3e99a981b43b669705bf88fb99fc62beb416d0e0 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: unctime.c,v 1.2 1997/08/27 08:11:44 amcore Exp $ */
+/* $Id: unctime.c,v 1.3 2006/05/25 01:47:11 johnfranks Exp $ */
 
 #include "amanda.h"
 
 #define        E_SECOND        17
 #define        E_YEAR          20
 
-static int lookup P((char *));
+static int lookup(char *);
 
 
 time_t
-unctime(str)
-       char *str;
+unctime(
+    char *str)
 {
        struct tm then;
        char dbuf[26];
 
-       (void) strncpy(dbuf, str, sizeof(dbuf) - 1);
-       dbuf[sizeof(dbuf) - 1] = '\0';
+       (void) strncpy(dbuf, str, SIZEOF(dbuf) - 1);
+       dbuf[SIZEOF(dbuf) - 1] = '\0';
        dbuf[E_MONTH+3] = '\0';
        if ((then.tm_mon = lookup(&dbuf[E_MONTH])) < 0)
                return -1;
@@ -81,13 +81,13 @@ static char months[] =
        "JanFebMarAprMayJunJulAugSepOctNovDec";
 
 static int
-lookup(str)
-       char *str;
+lookup(
+    char *     str)
 {
        register char *cp, *cp2;
 
        for (cp = months, cp2 = str; *cp != '\0'; cp += 3)
                if (strncmp(cp, cp2, 3) == 0)
-                       return ((cp-months) / 3);
+                       return ((int)(cp-months) / 3);
        return -1;
 }
index d0ed70f744b5d93eff0b0645c9770cf4c46d20b4..91d070000c3d443e56157c87137d0b0355267dd9 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: versionsuffix.c,v 1.8 2005/09/20 21:32:25 jrjackson Exp $
+ * $Id: versionsuffix.c,v 1.9 2006/05/25 01:47:11 johnfranks Exp $
  *
  * prints the (possibly empty) suffix appended to amanda program names
  */
 #include "amanda.h"
 #include "version.h"
 
-int main P((void));
+int main(int argc, char **argv);
 
-int main()
+int main(int argc, char **argv)
 {
        safe_fd(-1, 0);
 
+       (void)argc;     /* Quiet unused parameter warning */
+       (void)argv;     /* Quiet unused parameter warning */
+
        set_pname("versionsuffix");
 
        printf("%s\n", versionsuffix());
index 1d237ead48c7a89a7e5873650aada6b3155972ba..7f25d62e856a929272840b8c3588bfe64949c96b 100644 (file)
@@ -7,42 +7,71 @@ REGsrcdir = $(srcdir)/$(REGDIR)
 
 INCLUDES = -I$(REGsrcdir)
 
-libamanda_la_SOURCES = \
-       alloc.c         amflock.c       \
-       bsd-security.c  \
-       clock.c         \
-       debug.c         dgram.c         \
-       event.c         error.c         \
-       amfeatures.c    \
-       file.c          fileheader.c    \
-       krb4-security.c krb5-security.c \
-       match.c         \
-       packet.c        pipespawn.c     protocol.c      \
-       regcomp.c       regerror.c      regexec.c       regfree.c       \
-       rsh-security.c  \
-       security.c      sl.c            ssh-security.c  statfs.c        \
-       stream.c        tapelist.c      \
-       token.c         \
-       util.c          \
-       versuff.c       version.c
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
+libamanda_la_SOURCES =         \
+       alloc.c                 \
+       amfeatures.c            \
+       amflock.c               \
+       bsd-security.c          \
+       bsdtcp-security.c       \
+       bsdudp-security.c       \
+       clock.c                 \
+       debug.c                 \
+       dgram.c                 \
+       error.c                 \
+       event.c                 \
+       file.c                  \
+       fileheader.c            \
+       krb4-security.c         \
+       krb5-security.c         \
+       match.c                 \
+       packet.c                \
+       pipespawn.c             \
+       protocol.c              \
+       regcomp.c               \
+       regerror.c              \
+       regexec.c               \
+       regfree.c               \
+       rsh-security.c          \
+       security.c              \
+       security-util.c         \
+       sl.c                    \
+       ssh-security.c          \
+       statfs.c                \
+       stream.c                \
+       tapelist.c              \
+       token.c                 \
+       util.c                  \
+       version.c               \
+       versuff.c
 
 libamanda_la_LIBADD =  @LTLIBOBJS@ @LTALLOCA@
 libamanda_la_LDFLAGS =  -release $(VERSION)
 
-noinst_HEADERS =       amanda.h        amregex.h       arglist.h       \
-                       clock.h         \
-                       dgram.h         \
-                       event.h         \
-                       amfeatures.h    \
-                       packet.h        pipespawn.h     protocol.h      \
-                       queue.h         \
-                       sl.h            security.h      statfs.h        \
-                       stream.h        \
-                       tapelist.h      \
-                       token.h         \
-                       util.h          \
-                       version.h       \
-                       fileheader.h
+noinst_HEADERS =               \
+       amanda.h                \
+       amfeatures.h            \
+       amregex.h               \
+       arglist.h               \
+       clock.h                 \
+       dgram.h                 \
+       event.h                 \
+       fileheader.h            \
+       packet.h                \
+       pipespawn.h             \
+       protocol.h              \
+       queue.h                 \
+       security.h              \
+       security-util.h         \
+       sl.h                    \
+       statfs.h                \
+       stream.h                \
+       tapelist.h              \
+       token.h                 \
+       util.h                  \
+       version.h
 
 .sh:
        cat $< > $@
@@ -51,7 +80,7 @@ noinst_HEADERS =      amanda.h        amregex.h       arglist.h       \
 EXTRA_PROGRAMS = genversion $(TEST_PROGS)
 
 genversion_SOURCES = genversion.c
-genversion_LDADD = $(libamanda_la_LIBADD) versuff.o
+genversion_LDADD = $(libamanda_la_LIBADD) versuff.lo
 
 genversion.@OBJEXT@: genversion.h
 genversion.h: $(top_builddir)/config.status
@@ -71,12 +100,14 @@ regexec.@OBJEXT@ regexec.lo: regex.h engine.ih
 regerror.@OBJEXT@ regerror.lo: regex.h regerror.ih
 regfree.@OBJEXT@ regfree.lo: regex.h
 
-REGEXHSRC =    $(REGsrcdir)/regex2.h \
-               $(REGsrcdir)/regcomp.c \
-               $(REGsrcdir)/regexec.c \
-               $(REGsrcdir)/regerror.c \
+REGEXCSRC =    $(REGsrcdir)/regcomp.c  \
+               $(REGsrcdir)/regexec.c  \
+               $(REGsrcdir)/regerror.c \
                $(REGsrcdir)/regfree.c
 
+REGEXHSRC =    $(REGsrcdir)/regex2.h   \
+               $(REGEXCSRC)
+
 # these are used for testing only:
 TEST_PROGS = statfs token file bsdsecurity amfeatures
 
@@ -85,16 +116,16 @@ CLEANFILES = regex.h regcomp.ih engine.ih regerror.ih *.test.c
 DISTCLEANFILES = version.c genversion.h genversion amanda-int.h
 
 regex.h: $(REGEXHSRC) $(REGsrcdir)/mkh
-       sh $(REGsrcdir)/mkh -o -i _REGEX_H_ $(REGEXHSRC) >$@
+       sh $(REGsrcdir)/mkh -i _REGEX_H_ $(REGEXHSRC) >$@
 
 regcomp.ih: $(REGsrcdir)/regcomp.c $(REGsrcdir)/mkh
-       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regcomp.c >$@
+       sh $(REGsrcdir)/mkh -p $(REGsrcdir)/regcomp.c >$@
 
 engine.ih: $(REGsrcdir)/engine.c $(REGsrcdir)/mkh
-       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/engine.c >$@
+       sh $(REGsrcdir)/mkh -p $(REGsrcdir)/engine.c >$@
 
 regerror.ih: $(REGsrcdir)/regerror.c $(REGsrcdir)/mkh
-       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regerror.c >$@
+       sh $(REGsrcdir)/mkh -p $(REGsrcdir)/regerror.c >$@
 
 # used for testing only
 
@@ -103,7 +134,8 @@ STANDARD_COMMON_STUFF_NOT_FILE = \
        clock.$(OBJEXT) \
        debug.$(OBJEXT) \
        error.$(OBJEXT) \
-       util.$(OBJEXT)
+       util.$(OBJEXT) \
+       match.$(OBJEXT)
 
 STANDARD_COMMON_STUFF = \
        $(STANDARD_COMMON_STUFF_NOT_FILE) \
@@ -135,6 +167,18 @@ bsdsecurity_LDADD = $(libamanda_a_LIBADD) \
 amfeatures_SOURCES = amfeatures.test.c
 amfeatures_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
 
+lint:
+       @echo $(LINT) $(libamanda_la_SOURCES)
+       @$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $(libamanda_la_SOURCES)
+       @echo $(LINT) $(genversion_SOURCES)
+       @$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $(genversion_SOURCES)
+
+listlibsrc:
+       @ for p in $(libamanda_la_SOURCES) $(REGEXCSRC); do     \
+               listlibsrcs="$$listlibsrcs `pwd`/$$p";          \
+       done;                                                   \
+       echo $$listlibsrcs >listlibsrc.output
+
 %.test.c: $(srcdir)/%.c
        echo '#define TEST' >$@
        echo '#include "$<"' >>$@
index 18a44314d312390a0c77559cf894a62b34d0515b..4672c53f92ee1cb293e6de682862b68e3183cb52 100644 (file)
@@ -64,13 +64,14 @@ am__installdirs = "$(DESTDIR)$(libdir)"
 libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
 libamanda_la_DEPENDENCIES = @LTLIBOBJS@ @LTALLOCA@
-am_libamanda_la_OBJECTS = alloc.lo amflock.lo bsd-security.lo clock.lo \
-       debug.lo dgram.lo event.lo error.lo amfeatures.lo file.lo \
-       fileheader.lo krb4-security.lo krb5-security.lo match.lo \
-       packet.lo pipespawn.lo protocol.lo regcomp.lo regerror.lo \
-       regexec.lo regfree.lo rsh-security.lo security.lo sl.lo \
+am_libamanda_la_OBJECTS = alloc.lo amfeatures.lo amflock.lo \
+       bsd-security.lo bsdtcp-security.lo bsdudp-security.lo clock.lo \
+       debug.lo dgram.lo error.lo event.lo file.lo fileheader.lo \
+       krb4-security.lo krb5-security.lo match.lo packet.lo \
+       pipespawn.lo protocol.lo regcomp.lo regerror.lo regexec.lo \
+       regfree.lo rsh-security.lo security.lo security-util.lo sl.lo \
        ssh-security.lo statfs.lo stream.lo tapelist.lo token.lo \
-       util.lo versuff.lo version.lo
+       util.lo version.lo versuff.lo
 libamanda_la_OBJECTS = $(am_libamanda_la_OBJECTS)
 am__EXEEXT_1 = statfs$(EXEEXT) token$(EXEEXT) file$(EXEEXT) \
        bsdsecurity$(EXEEXT) amfeatures$(EXEEXT)
@@ -78,7 +79,7 @@ am_amfeatures_OBJECTS = amfeatures.test.$(OBJEXT)
 amfeatures_OBJECTS = $(am_amfeatures_OBJECTS)
 am__DEPENDENCIES_1 = @LTLIBOBJS@ @LTALLOCA@
 am__DEPENDENCIES_2 = alloc.$(OBJEXT) clock.$(OBJEXT) debug.$(OBJEXT) \
-       error.$(OBJEXT) util.$(OBJEXT)
+       error.$(OBJEXT) util.$(OBJEXT) match.$(OBJEXT)
 am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) file.$(OBJEXT)
 amfeatures_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
 am_bsdsecurity_OBJECTS = bsd-security.test.$(OBJEXT)
@@ -92,7 +93,7 @@ file_OBJECTS = $(am_file_OBJECTS)
 file_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
 am_genversion_OBJECTS = genversion.$(OBJEXT)
 genversion_OBJECTS = $(am_genversion_OBJECTS)
-genversion_DEPENDENCIES = $(am__DEPENDENCIES_1) versuff.o
+genversion_DEPENDENCIES = $(am__DEPENDENCIES_1) versuff.lo
 am_statfs_OBJECTS = statfs.test.$(OBJEXT)
 statfs_OBJECTS = $(am_statfs_OBJECTS)
 statfs_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
@@ -127,11 +128,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -139,6 +143,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -323,50 +329,80 @@ lib_LTLIBRARIES = libamanda.la
 REGDIR = ../regex-src
 REGsrcdir = $(srcdir)/$(REGDIR)
 INCLUDES = -I$(REGsrcdir)
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
 libamanda_la_SOURCES = \
-       alloc.c         amflock.c       \
-       bsd-security.c  \
-       clock.c         \
-       debug.c         dgram.c         \
-       event.c         error.c         \
-       amfeatures.c    \
-       file.c          fileheader.c    \
-       krb4-security.c krb5-security.c \
-       match.c         \
-       packet.c        pipespawn.c     protocol.c      \
-       regcomp.c       regerror.c      regexec.c       regfree.c       \
-       rsh-security.c  \
-       security.c      sl.c            ssh-security.c  statfs.c        \
-       stream.c        tapelist.c      \
-       token.c         \
-       util.c          \
-       versuff.c       version.c
+       alloc.c                 \
+       amfeatures.c            \
+       amflock.c               \
+       bsd-security.c          \
+       bsdtcp-security.c       \
+       bsdudp-security.c       \
+       clock.c                 \
+       debug.c                 \
+       dgram.c                 \
+       error.c                 \
+       event.c                 \
+       file.c                  \
+       fileheader.c            \
+       krb4-security.c         \
+       krb5-security.c         \
+       match.c                 \
+       packet.c                \
+       pipespawn.c             \
+       protocol.c              \
+       regcomp.c               \
+       regerror.c              \
+       regexec.c               \
+       regfree.c               \
+       rsh-security.c          \
+       security.c              \
+       security-util.c         \
+       sl.c                    \
+       ssh-security.c          \
+       statfs.c                \
+       stream.c                \
+       tapelist.c              \
+       token.c                 \
+       util.c                  \
+       version.c               \
+       versuff.c
 
 libamanda_la_LIBADD = @LTLIBOBJS@ @LTALLOCA@
 libamanda_la_LDFLAGS = -release $(VERSION)
-noinst_HEADERS = amanda.h      amregex.h       arglist.h       \
-                       clock.h         \
-                       dgram.h         \
-                       event.h         \
-                       amfeatures.h    \
-                       packet.h        pipespawn.h     protocol.h      \
-                       queue.h         \
-                       sl.h            security.h      statfs.h        \
-                       stream.h        \
-                       tapelist.h      \
-                       token.h         \
-                       util.h          \
-                       version.h       \
-                       fileheader.h
+noinst_HEADERS = \
+       amanda.h                \
+       amfeatures.h            \
+       amregex.h               \
+       arglist.h               \
+       clock.h                 \
+       dgram.h                 \
+       event.h                 \
+       fileheader.h            \
+       packet.h                \
+       pipespawn.h             \
+       protocol.h              \
+       queue.h                 \
+       security.h              \
+       security-util.h         \
+       sl.h                    \
+       statfs.h                \
+       stream.h                \
+       tapelist.h              \
+       token.h                 \
+       util.h                  \
+       version.h
 
 genversion_SOURCES = genversion.c
-genversion_LDADD = $(libamanda_la_LIBADD) versuff.o
-REGEXHSRC = $(REGsrcdir)/regex2.h \
-               $(REGsrcdir)/regcomp.c \
-               $(REGsrcdir)/regexec.c \
-               $(REGsrcdir)/regerror.c \
+genversion_LDADD = $(libamanda_la_LIBADD) versuff.lo
+REGEXCSRC = $(REGsrcdir)/regcomp.c     \
+               $(REGsrcdir)/regexec.c  \
+               $(REGsrcdir)/regerror.c \
                $(REGsrcdir)/regfree.c
 
+REGEXHSRC = $(REGsrcdir)/regex2.h      \
+               $(REGEXCSRC)
+
 
 # these are used for testing only:
 TEST_PROGS = statfs token file bsdsecurity amfeatures
@@ -379,7 +415,8 @@ STANDARD_COMMON_STUFF_NOT_FILE = \
        clock.$(OBJEXT) \
        debug.$(OBJEXT) \
        error.$(OBJEXT) \
-       util.$(OBJEXT)
+       util.$(OBJEXT) \
+       match.$(OBJEXT)
 
 STANDARD_COMMON_STUFF = \
        $(STANDARD_COMMON_STUFF_NOT_FILE) \
@@ -514,6 +551,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amflock.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd-security.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd-security.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsdtcp-security.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsdudp-security.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clock.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dgram.Plo@am__quote@
@@ -534,6 +573,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regexec.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regfree.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsh-security.Plo@am__quote@
+@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)/sl.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh-security.Plo@am__quote@
@@ -774,16 +814,28 @@ regerror.@OBJEXT@ regerror.lo: regex.h regerror.ih
 regfree.@OBJEXT@ regfree.lo: regex.h
 
 regex.h: $(REGEXHSRC) $(REGsrcdir)/mkh
-       sh $(REGsrcdir)/mkh -o -i _REGEX_H_ $(REGEXHSRC) >$@
+       sh $(REGsrcdir)/mkh -i _REGEX_H_ $(REGEXHSRC) >$@
 
 regcomp.ih: $(REGsrcdir)/regcomp.c $(REGsrcdir)/mkh
-       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regcomp.c >$@
+       sh $(REGsrcdir)/mkh -p $(REGsrcdir)/regcomp.c >$@
 
 engine.ih: $(REGsrcdir)/engine.c $(REGsrcdir)/mkh
-       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/engine.c >$@
+       sh $(REGsrcdir)/mkh -p $(REGsrcdir)/engine.c >$@
 
 regerror.ih: $(REGsrcdir)/regerror.c $(REGsrcdir)/mkh
-       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regerror.c >$@
+       sh $(REGsrcdir)/mkh -p $(REGsrcdir)/regerror.c >$@
+
+lint:
+       @echo $(LINT) $(libamanda_la_SOURCES)
+       @$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $(libamanda_la_SOURCES)
+       @echo $(LINT) $(genversion_SOURCES)
+       @$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $(genversion_SOURCES)
+
+listlibsrc:
+       @ for p in $(libamanda_la_SOURCES) $(REGEXCSRC); do     \
+               listlibsrcs="$$listlibsrcs `pwd`/$$p";          \
+       done;                                                   \
+       echo $$listlibsrcs >listlibsrc.output
 
 %.test.c: $(srcdir)/%.c
        echo '#define TEST' >$@
index 0a0cdef3555f72a6b29d115910fdcd533b0bee06..81670ea80bcbab0a131adccc0635db99553c6e71 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: alloc.c,v 1.35 2005/12/21 19:07:49 paddy_s Exp $
+ * $Id: alloc.c,v 1.37 2006/07/05 10:41:32 martinea Exp $
  *
  * Memory allocators with error handling.  If the allocation fails,
  * errordump() is called, relieving the caller from checking the return
@@ -34,7 +34,7 @@
 #include "arglist.h"
 #include "queue.h"
 
-static char *internal_vstralloc P((const char *, va_list));
+static char *internal_vstralloc(const char *, va_list);
 
 /*
  *=====================================================================
@@ -63,10 +63,11 @@ static char *internal_vstralloc P((const char *, va_list));
  */
 
 const char *
-debug_caller_loc(file, line)
-    const char *file;
-    int line;
+debug_caller_loc(
+    const char *file,
+    int line)
 {
+    /*@keep@*/
     struct loc_str {
        char *str;
        LIST_ENTRY(loc_str) le;
@@ -78,7 +79,7 @@ debug_caller_loc(file, line)
     if ((p = strrchr(file, '/')) != NULL)
        file = p + 1;                           /* just the last path element */
 
-    snprintf(loc, sizeof(loc), "%s@%d", file, line);
+    snprintf(loc, SIZEOF(loc), "%s@%d", file, line);
 
     for (ls = LIST_FIRST(&root); ls != NULL; ls = LIST_NEXT(ls, le)) {
        if (strcmp(loc, ls->str) == 0) {
@@ -97,7 +98,7 @@ debug_caller_loc(file, line)
     /*
      * This is a new entry.  Put it at the head of the list.
      */
-    ls = malloc(sizeof(*ls));
+    ls = malloc(SIZEOF(*ls));
     if (ls == NULL)
        return ("??");                  /* not much better than abort */
     ls->str = malloc(strlen(loc) + 1);
@@ -138,9 +139,9 @@ static char         *saved_file;
 static int             saved_line;
 
 int
-debug_alloc_push (s, l)
-    char *s;
-    int l;
+debug_alloc_push(
+    char *s,
+    int l)
 {
     debug_alloc_loc_info[debug_alloc_ptr].file = s;
     debug_alloc_loc_info[debug_alloc_ptr].line = l;
@@ -162,7 +163,7 @@ debug_alloc_push (s, l)
  */
 
 void
-debug_alloc_pop ()
+debug_alloc_pop(void)
 {
     debug_alloc_ptr =
       (debug_alloc_ptr + DEBUG_ALLOC_SAVE_MAX - 1) % DEBUG_ALLOC_SAVE_MAX;
@@ -174,20 +175,21 @@ debug_alloc_pop ()
  * alloc - a wrapper for malloc.
  */
 void *
-debug_alloc(s, l, size)
-    const char *s;
-    int l;
-    size_t size;
+debug_alloc(
+    const char *s,
+    int l,
+    size_t size)
 {
     void *addr;
 
     malloc_enter(debug_caller_loc(s, l));
     addr = (void *)malloc(max(size, 1));
     if (addr == NULL) {
-       errordump("%s@%d: memory allocation failed (%u bytes requested)",
+       errordump("%s@%d: memory allocation failed (" SIZE_T_FMT " bytes requested)",
                  s ? s : "(unknown)",
                  s ? l : -1,
-                 size);
+                 (SIZE_T_FMT_TYPE)size);
+       /*NOTREACHED*/
     }
     malloc_leave(debug_caller_loc(s, l));
     return addr;
@@ -198,11 +200,11 @@ debug_alloc(s, l, size)
  * newalloc - free existing buffer and then alloc a new one.
  */
 void *
-debug_newalloc(s, l, old, size)
-    const char *s;
-    int l;
-    void *old;
-    size_t size;
+debug_newalloc(
+    const char *s,
+    int l,
+    void *old,
+    size_t size)
 {
     char *addr;
 
@@ -219,10 +221,10 @@ debug_newalloc(s, l, old, size)
  *            Just like strdup()!
  */
 char *
-debug_stralloc(s, l, str)
-    const char *s;
-    int l;
-    const char *str;
+debug_stralloc(
+    const char *s,
+    int l,
+    const char *str)
 {
     char *addr;
 
@@ -235,9 +237,10 @@ debug_stralloc(s, l, str)
 
 /* vstrextend -- Extends the existing string by appending the other 
  * arguments. */
-arglist_function(char *vstrextend,
-                 char **,
-                 oldstr)
+/*@ignore@*/
+arglist_function(
+    char *vstrextend,
+    char **, oldstr)
 {
        char *keep = *oldstr;
        va_list ap;
@@ -252,6 +255,7 @@ arglist_function(char *vstrextend,
        arglist_end(ap);
         return *oldstr;
 }
+/*@end@*/
 
 /*
  * internal_vstralloc - copies up to MAX_STR_ARGS strings into newly
@@ -264,21 +268,21 @@ arglist_function(char *vstrextend,
 #define        MAX_VSTRALLOC_ARGS      32
 
 static char *
-internal_vstralloc(str, argp)
-    const char *str;
-    va_list argp;
+internal_vstralloc(
+    const char *str,
+    va_list argp)
 {
     char *next;
     char *result;
-    int a;
+    int a, b;
     size_t total_len;
     const char *arg[MAX_VSTRALLOC_ARGS+1];
     size_t len[MAX_VSTRALLOC_ARGS+1];
     size_t l;
-    const char *s;
 
     if (str == NULL) {
-       return NULL;                            /* probably will not happen */
+       errordump("internal_vstralloc: str is NULL");
+       /*NOTREACHED*/
     }
 
     a = 0;
@@ -292,24 +296,24 @@ internal_vstralloc(str, argp)
            continue;                           /* minor optimisation */
        }
        if (a >= MAX_VSTRALLOC_ARGS) {
-           errordump("%s@%d: more than %d arg%s to vstralloc",
+           errordump("%s@%d: more than %d args to vstralloc",
                      saved_file ? saved_file : "(unknown)",
                      saved_file ? saved_line : -1,
-                     MAX_VSTRALLOC_ARGS,
-                     (MAX_VSTRALLOC_ARGS == 1) ? "" : "s");
+                     MAX_VSTRALLOC_ARGS);
+           /*NOTREACHED*/
        }
        arg[a] = next;
        len[a] = l;
        total_len += l;
        a++;
     }
-    arg[a] = NULL;
-    len[a] = 0;
 
-    next = result = debug_alloc(saved_file, saved_line, total_len+1);
-    for (a = 0; (s = arg[a]) != NULL; a++) {
-       memcpy(next, s, len[a]);
-       next += len[a];
+    result = debug_alloc(saved_file, saved_line, total_len+1);
+
+    next = result;
+    for (b = 0; b < a; b++) {
+       memcpy(next, arg[b], len[b]);
+       next += len[b];
     }
     *next = '\0';
 
@@ -320,7 +324,9 @@ internal_vstralloc(str, argp)
 /*
  * vstralloc - copies multiple strings into newly allocated memory.
  */
-arglist_function(char *debug_vstralloc, const char *, str)
+arglist_function(
+    char *debug_vstralloc,
+    const char *, str)
 {
     va_list argp;
     char *result;
@@ -339,11 +345,11 @@ arglist_function(char *debug_vstralloc, const char *, str)
  * newstralloc - free existing string and then stralloc a new one.
  */
 char *
-debug_newstralloc(s, l, oldstr, newstr)
-    const char *s;
-    int l;
-    char *oldstr;
-    const char *newstr;
+debug_newstralloc(
+    const char *s,
+    int l,
+    char *oldstr,
+    const char *newstr)
 {
     char *addr;
 
@@ -358,11 +364,10 @@ debug_newstralloc(s, l, oldstr, newstr)
 /*
  * newvstralloc - free existing string and then vstralloc a new one.
  */
-arglist_function1(char *debug_newvstralloc,
-                 char *,
-                 oldstr,
-                 const char *,
-                 newstr)
+arglist_function1(
+    char *debug_newvstralloc,
+    char *, oldstr,
+    const char *, newstr)
 {
     va_list argp;
     char *result;
@@ -382,7 +387,7 @@ arglist_function1(char *debug_newvstralloc,
  * safe_env - build a "safe" environment list.
  */
 char **
-safe_env()
+safe_env(void)
 {
     static char *safe_env_list[] = {
        "TZ",
@@ -402,7 +407,7 @@ safe_env()
      * safe_env_list so our result is always a valid, although possibly
      * empty, environment list.
      */
-#define SAFE_ENV_CNT   (sizeof(safe_env_list) / sizeof(*safe_env_list))
+#define SAFE_ENV_CNT   (size_t)(sizeof(safe_env_list) / sizeof(*safe_env_list))
     char **envp = safe_env_list + SAFE_ENV_CNT - 1;
 
     char **p;
@@ -411,7 +416,7 @@ safe_env()
     char *v;
     size_t l1, l2;
 
-    if ((q = (char **)malloc(sizeof(safe_env_list))) != NULL) {
+    if ((q = (char **)malloc(SIZEOF(safe_env_list))) != NULL) {
        envp = q;
        for (p = safe_env_list; *p != NULL; p++) {
            if ((v = getenv(*p)) == NULL) {
@@ -447,19 +452,19 @@ safe_env()
  */
 
 int
-debug_amtable_alloc(s, l, table, current, elsize, count, bump, init_func)
-    const char *s;
-    int l;
-    void **table;
-    int *current;
-    size_t elsize;
-    int count;
-    int bump;
-    void (*init_func)(void *);
+debug_amtable_alloc(
+    const char *s,
+    int l,
+    void **table,
+    size_t *current,
+    size_t elsize,
+    size_t count,
+    int bump,
+    void (*init_func)(void *))
 {
     void *table_new;
-    int table_count_new;
-    int i;
+    size_t table_count_new;
+    size_t i;
 
     if (count >= *current) {
        table_count_new = ((count + bump) / bump) * bump;
@@ -492,9 +497,9 @@ debug_amtable_alloc(s, l, table, current, elsize, count, bump, init_func)
  */
 
 void
-amtable_free(table, current)
-    void **table;
-    int *current;
+amtable_free(
+    void **table,
+    size_t *current)
 {
     amfree(*table);
     *current = 0;
index ad100874ccd49984b9257ed78eade8bc2a2553e9..c6664b707ae21c228420028a272142be85b61039 100644 (file)
@@ -21,9 +21,7 @@
    allocating any.  It is a good idea to use alloca(0) in
    your main control loop, etc. to force garbage collection.  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "amanda.h"
 
 #ifndef HAVE_ALLOCA
 
@@ -131,7 +129,7 @@ find_stack_direction ()
    alignment chunk size.  The following default should work okay.  */
 
 #ifndef        ALIGN_SIZE
-#define        ALIGN_SIZE      sizeof(double)
+#define        ALIGN_SIZE      SIZEOF(double)
 #endif
 
 typedef union hdr
@@ -193,7 +191,7 @@ alloca (size)
   /* Allocate combined header + user data storage.  */
 
   {
-    register pointer new = malloc (sizeof (header) + size);
+    register pointer new = malloc (SIZEOF (header) + size);
     /* Address of header.  */
 
     ((header *) new)->h.next = last_alloca_header;
@@ -203,7 +201,7 @@ alloca (size)
 
     /* User storage begins just after header.  */
 
-    return (pointer) ((char *) new + sizeof (header));
+    return (pointer) ((char *) new + SIZEOF (header));
   }
 }
 
index 66cff1d624c1f288cc9cfdb805ab280376f2d9b7..ccea1758adfdc7577902b03dc76e730112c0a5a3 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amanda.h,v 1.123 2006/03/03 15:05:15 vectro Exp $
+ * $Id: amanda.h,v 1.131 2006/07/25 18:27:56 martinea Exp $
  *
  * the central header file included by all amanda sources
  */
 #include "config.h"
 #endif
 
+/*
+ * Force large file source even if configure guesses wrong.
+ */
+#ifndef _LARGE_FILE_SOURCE
+#define _LARGE_FILES 1
+#endif
+
+#ifndef _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE 1
+#endif
+
+#ifndef  _FILE_OFFSET_BITS
+#define        _FILE_OFFSET_BITS 64
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
 /*
  * I would prefer that each Amanda module include only those system headers
  * that are locally needed, but on most Unixes the system header files are not
 #  include <alloca.h>
 #endif
 
-#if 0
-/* an explanation for this is available in the CHANGES file for
-   amanda-2.4.0b5 */
-#ifdef HAVE_ASM_BYTEORDER_H
-#  include <asm/byteorder.h>
-#endif
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-
 /* from the autoconf documentation */
 #ifdef HAVE_DIRENT_H
 #  include <dirent.h>
 #  include <stdlib.h>
 #endif
 
+#ifdef HAVE_LIBGEN_H
+#  include <libgen.h>
+#endif
+
 #ifdef HAVE_STRING_H
 #  include <string.h>
 #endif
 #  include <syslog.h>
 #endif
 
+#ifdef HAVE_MATH_H
+#  include <math.h>
+#endif
+
 #ifdef HAVE_SYS_FILE_H
 #  include <sys/file.h>
 #endif
@@ -186,6 +201,10 @@ struct iovec {
 #  include <sys/wait.h>
 #endif
 
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
 #ifdef WAIT_USES_INT
   typedef int amwait_t;
 # ifndef WEXITSTATUS
@@ -275,12 +294,12 @@ struct iovec {
 #ifdef USE_DBMALLOC
 #include "dbmalloc.h"
 #else
-#define        malloc_enter(func)
-#define        malloc_leave(func)
-#define        malloc_mark(ptr)
-#define        malloc_chain_check()
-#define        malloc_dump(fd)
-#define        malloc_list(a,b,c)
+#define        malloc_enter(func)              ((void)0)
+#define        malloc_leave(func)              ((void)0)
+#define        malloc_mark(ptr)                ((void)0)
+#define        malloc_chain_check()            ((void)0)
+#define        malloc_dump(fd)                 ((void)0)
+#define        malloc_list(a,b,c)              ((void)0)
 #define        malloc_inuse(hist)              (*(hist) = 0, 0)
 #define        dbmalloc_caller_loc(x,y)        (x)
 #endif
@@ -302,20 +321,35 @@ struct iovec {
 extern int errno;
 #endif
 
+/*
+ * Some compilers have int for type of sizeof() some use size_t.
+ * size_t is the one we want...
+ */
+#define        SIZEOF(x)       (size_t)sizeof(x)
+
 
 /*
  * Some older BSD systems don't have these FD_ macros, so if not, provide them.
  */
-#ifndef FD_SET
-#  define FD_SETSIZE      (sizeof(fd_set) * 8)
-#  define FD_SET(n, p)    (((fd_set *) (p))->fds_bits[0] |= (1 << ((n) % 32)))
-#  define FD_CLR(n, p)    (((fd_set *) (p))->fds_bits[0] &= ~(1 << ((n) % 32)))
-#  define FD_ISSET(n, p)  (((fd_set *) (p))->fds_bits[0] & (1 << ((n) % 32)))
-#  define FD_ZERO(p)      memset((p), 0, sizeof(*(p)))
+#if !defined(FD_SET) || defined(LINT) || defined(__lint)
+#  undef FD_SETSIZE
+#  define FD_SETSIZE      (int)(SIZEOF(fd_set) * CHAR_BIT)
+
+#  undef FD_SET
+#  define FD_SET(n, p)    (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] |= (int)((1 << ((n) % WORD_BIT))))
+
+#  undef FD_CLR
+#  define FD_CLR(n, p)    (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] &= (int)(~(1 << ((n) % WORD_BIT))))
+
+#  undef FD_ISSET
+#  define FD_ISSET(n, p)  (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] & (1 << ((n) % WORD_BIT)))
+
+#  undef FD_ZERO
+#  define FD_ZERO(p)      memset((p), 0, SIZEOF(*(p)))
 #endif
 
 #ifndef FD_COPY
-#  define FD_COPY(p, q)   memcpy((q), (p), sizeof(fd_set))
+#  define FD_COPY(p, q)   memcpy((q), (p), SIZEOF(*(p)))
 #endif
 
 
@@ -332,30 +366,16 @@ extern int errno;
 #  define void char
 #endif
 
-/*
- * Macros to allow code to adapt to both ANSI and class C environments.
- *
- * P(): prototype argument macro - removes arguments from prototypes in
- *      class C environments
- * stringize(): turn a bare word or words into a quoted string
- * stringconcat(): turn two quoted strings into one
- */
-#if STDC_HEADERS
-#  define P(parms)     parms
-#  define stringize(x) #x
-#  define stringconcat(x, y) x ## y
-#else
-#  define P(parms)     ()
-#  define stringize(x) "x"
-#  define stringconcat(x, y) x/**/y
-#endif
+#define stringize(x) #x
+#define stringconcat(x, y) x ## y
 
 /*
  * So that we can use GNUC attributes (such as to get -Wall warnings
  * for printf-like functions).  Only do this in gcc 2.7 or later ...
  * it may work on earlier stuff, but why chance it.
  */
-#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7
+#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7 || defined(S_SPLINT_S) || defined(LINT) || defined(__lint)
+#undef __attribute__
 #define __attribute__(__x)
 #endif
 
@@ -373,6 +393,7 @@ extern int errno;
        onerror(abort);                                                 \
        error("assert: %s false, file %s, line %d",                     \
           stringize(exp), __FILE__, __LINE__);                         \
+        /*NOTREACHED*/                                                 \
     }                                                                  \
 } while (0)
 
@@ -383,27 +404,29 @@ extern int errno;
  */
 
 #ifdef DEBUG_CODE                                                      /* { */
-#   define dbopen()    debug_open()
+#   define dbopen(a)   debug_open(a)
 #   define dbreopen(a,b) debug_reopen(a,b)
+#   define dbrename(a,b) debug_rename(a,b)
 #   define dbclose()   debug_close()
-#   define dbprintf(p) (debug? (debug_printf p, 0) : 0)
+#   define dbprintf(p) (debug_printf p)
 #   define dbfd()      debug_fd()
 #   define dbfp()      debug_fp()
 #   define dbfn()      debug_fn()
 
-extern void debug_open P((void));
-extern void debug_reopen P((char *file, char *notation));
-extern void debug_close P((void));
-extern void debug_printf P((const char *format, ...))
+extern void debug_open(char *subdir);
+extern void debug_reopen(char *file, char *notation);
+extern void debug_rename(char *config, char *subdir);
+extern void debug_close(void);
+extern void debug_printf(const char *format, ...)
     __attribute__ ((format (printf, 1, 2)));
-extern int  debug_fd P((void));
-extern FILE *  debug_fp P((void));
-extern char *  debug_fn P((void));
-extern void set_debug_prefix_pid P((pid_t));
-extern char *debug_prefix P((char *));
-extern char *debug_prefix_time P((char *));
+extern int  debug_fd(void);
+extern FILE *  debug_fp(void);
+extern char *  debug_fn(void);
+extern void set_debug_prefix_pid(pid_t);
+extern char *debug_prefix(char *);
+extern char *debug_prefix_time(char *);
 #else                                                                  /* }{ */
-#   define dbopen()
+#   define dbopen(a)
 #   define dbreopen(a,b)
 #   define dbclose()
 #   define dbprintf(p)
@@ -418,7 +441,7 @@ extern char *debug_prefix_time P((char *));
 /* amanda #days calculation, with roundoff */
 
 #define SECS_PER_DAY   (24*60*60)
-#define days_diff(a, b)        (((b) - (a) + SECS_PER_DAY/2) / SECS_PER_DAY)
+#define days_diff(a, b)        (int)(((b) - (a) + SECS_PER_DAY/2) / SECS_PER_DAY)
 
 /* Global constants.  */
 #ifndef AMANDA_SERVICE_NAME
@@ -431,10 +454,10 @@ extern char *debug_prefix_time P((char *));
 #define SERVICE_SUFFIX ""
 #endif
 #ifndef AMANDA_SERVICE_DEFAULT
-#define AMANDA_SERVICE_DEFAULT 10080
+#define AMANDA_SERVICE_DEFAULT ((in_port_t)10080)
 #endif
 #ifndef KAMANDA_SERVICE_DEFAULT
-#define KAMANDA_SERVICE_DEFAULT        10081
+#define KAMANDA_SERVICE_DEFAULT        ((in_port_t)10081)
 #endif
 
 #define am_round(v,u)  ((((v) + (u) - 1) / (u)) * (u))
@@ -452,30 +475,31 @@ extern char *debug_prefix_time P((char *));
 /* Maximum length of tape label, plus one for null-terminator. */
 #define MAX_TAPE_LABEL_LEN (10240)
 #define MAX_TAPE_LABEL_BUF (MAX_TAPE_LABEL_LEN+1)
+#define MAX_TAPE_LABEL_FMT "%10240s"
 
 /* Define miscellaneous amanda functions.  */
 #define ERR_INTERACTIVE        1
 #define ERR_SYSLOG     2
 #define ERR_AMANDALOG  4
 
-extern void   set_logerror P((void (*f)(char *)));
-extern void   set_pname P((char *pname));
-extern char  *get_pname P((void));
+extern void   set_logerror(void (*f)(char *));
+extern void   set_pname(char *pname);
+extern char  *get_pname(void);
 extern int    erroutput_type;
-extern void   error     P((const char *format, ...))
+extern void   error(const char *format, ...)
     __attribute__ ((format (printf, 1, 2), noreturn));
-extern void   errordump P((const char *format, ...))
+extern void   errordump(const char *format, ...)
     __attribute__ ((format (printf, 1, 2), noreturn));
-extern int    onerror         P((void (*errf)(void)));
+extern int    onerror(void (*errf)(void));
 
-extern void *debug_alloc P((const char *c, int l, size_t size));
-extern void *debug_newalloc P((const char *c, int l, void *old, size_t size));
-extern char *debug_stralloc P((const char *c, int l, const char *str));
-extern char *debug_newstralloc P((const char *c, int l, char *oldstr,
-    const char *newstr));
-extern const char *debug_caller_loc P((const char *file, int line));
-extern int debug_alloc_push P((char *file, int line));
-extern void debug_alloc_pop P((void));
+extern void *debug_alloc      (const char *c, int l, size_t size);
+extern void *debug_newalloc   (const char *c, int l, void *old, size_t size);
+extern char *debug_stralloc   (const char *c, int l, const char *str);
+extern char *debug_newstralloc(const char *c, int l, char *oldstr,
+                              const char *newstr);
+extern const char *debug_caller_loc (const char *file, int line);
+extern int debug_alloc_push (char *file, int line);
+extern void debug_alloc_pop (void);
 
 #define        alloc(s)                debug_alloc(__FILE__, __LINE__, (s))
 #define        newalloc(p,s)           debug_newalloc(__FILE__, __LINE__, (p), (s))
@@ -515,29 +539,30 @@ extern void debug_alloc_pop P((void));
 #define vstralloc debug_alloc_push(__FILE__,__LINE__)?0:debug_vstralloc
 #define newvstralloc debug_alloc_push(__FILE__,__LINE__)?0:debug_newvstralloc
 
-extern char  *debug_vstralloc       P((const char *str, ...));
-extern char  *debug_newvstralloc    P((char *oldstr, const char *newstr, ...));
+extern char  *debug_vstralloc(const char *str, ...);
+extern char  *debug_newvstralloc(char *oldstr, const char *newstr, ...);
 
 #define        stralloc2(s1,s2)      vstralloc((s1),(s2),NULL)
 #define        newstralloc2(p,s1,s2) newvstralloc((p),(s1),(s2),NULL)
 
 /* Usage: vstrextend(foo, "bar, "baz", NULL). Extends the existing 
  * string, or allocates a brand new one. */
-extern char *vstrextend P((char **oldstr, ...));
+extern char *vstrextend(char **oldstr, ...);
 
-extern char  *debug_agets   P((const char *c, int l, FILE *file));
-extern char  *debug_areads  P((const char *c, int l, int fd));
+extern /*@only@*/ /*@null@*/ char *debug_agets(const char *c, int l, FILE *file);
+extern /*@only@*/ /*@null@*/ char *debug_areads(const char *c, int l, int fd);
 #define agets(f)             debug_agets(__FILE__,__LINE__,(f))
 #define areads(f)            debug_areads(__FILE__,__LINE__,(f))
 
-extern int debug_amtable_alloc P((const char *file,
+extern int debug_amtable_alloc(const char *file,
                                  int line,
                                  void **table,
-                                 int *current,
+                                 size_t *current,
                                  size_t elsize,
-                                 int count,
+                                 size_t count,
                                  int bump,
-                                 void (*init_func)(void *)));
+                                 void (*init_func)(void *));
+
 #define amtable_alloc(t,c,s,n,b,f) debug_amtable_alloc(__FILE__,      \
                                                     __LINE__,        \
                                                     (t),             \
@@ -547,29 +572,30 @@ extern int debug_amtable_alloc P((const char *file,
                                                     (b),             \
                                                     (f))
 
-extern void amtable_free      P((void **table, int *current));
+extern void amtable_free(void **table, size_t *current);
 
 extern uid_t  client_uid;
 extern gid_t  client_gid;
-extern void   safe_fd         P((int fd_start, int fd_count));
-extern void   safe_cd         P((void));
-extern void   save_core       P((void));
-extern char **safe_env        P((void));
-extern char  *validate_regexp P((char *regex));
-extern char  *validate_glob   P((char *glob));
-extern char  *clean_regex     P((char *regex));
-extern int    match           P((char *regex, char *str));
-extern int    match_glob      P((char *glob, char *str));
-extern char  *glob_to_regex   P((char *glob));
-extern int    match_tar       P((char *glob, char *str));
-extern char  *tar_to_regex    P((char *glob));
-extern int    match_host      P((char *glob, char *host));
-extern int    match_disk      P((char *glob, char *disk));
-extern int    match_datestamp P((char *dateexp, char *datestamp));
-extern int    match_level     P((char *levelexp, char *level));
-extern time_t unctime         P((char *timestr));
-extern ssize_t  areads_dataready  P((int fd));
-extern void     areads_relbuf     P((int fd));
+
+void   safe_fd(int fd_start, int fd_count);
+void   safe_cd(void);
+void   save_core(void);
+char **        safe_env(void);
+char * validate_regexp(const char *regex);
+char * validate_glob(const char *glob);
+char * clean_regex(const char *regex);
+int    match(const char *regex, const char *str);
+int    match_glob(const char *glob, const char *str);
+char * glob_to_regex(const char *glob);
+int    match_tar(const char *glob, const char *str);
+char * tar_to_regex(const char *glob);
+int    match_host(const char *glob, const char *host);
+int    match_disk(const char *glob, const char *disk);
+int    match_datestamp(const char *dateexp, const char *datestamp);
+int    match_level(const char *levelexp, const char *level);
+time_t unctime(char *timestr);
+ssize_t        areads_dataready(int fd);
+void   areads_relbuf(int fd);
 
 /*
  * amfree(ptr) -- if allocated, release space and set ptr to NULL.
@@ -579,13 +605,14 @@ extern void     areads_relbuf     P((int fd));
  */
 
 #define        amfree(ptr) do {                                                \
-    if(ptr) {                                                          \
+    if((ptr) != NULL) {                                                        \
        int e__errno = errno;                                           \
        free(ptr);                                                      \
        (ptr) = NULL;                                                   \
        errno = e__errno;                                               \
+       (void)(ptr);  /* Fix value never used warning at end of routines */ \
     }                                                                  \
-} while(0)
+} while (0)
 
 #define strappend(s1,s2) do {                                          \
     char *t_t_t = (s1) ? stralloc2((s1),(s2)) : stralloc((s2));                \
@@ -620,26 +647,29 @@ extern void     areads_relbuf     P((int fd));
        areads_relbuf(fd);                                              \
     }                                                                  \
     (fd) = -1;                                                         \
+    (void)(fd);  /* Fix value never used warning at end of routines */ \
 } while(0)
 
 #define afclose(f) do {                                                        \
     if((f) != NULL) {                                                  \
        fclose(f);                                                      \
+       (f) = NULL;                                                     \
+       (void)(f);  /* Fix value never used warning at end of routines */ \
     }                                                                  \
-    (f) = NULL;                                                                \
 } while(0)
 
 #define apclose(p) do {                                                        \
     if((p) != NULL) {                                                  \
        pclose(p);                                                      \
+       (p) = NULL;                                                     \
+       (void)(p);  /* Fix value never used warning at end of routines */ \
     }                                                                  \
-    (p) = NULL;                                                                \
 } while(0)
 
 /*
  * Return the number of elements in an array.
  */
-#define am_countof(a)  (sizeof(a) / sizeof((a)[0]))
+#define am_countof(a)  (int)(SIZEOF(a) / SIZEOF((a)[0]))
 
 /*
  * min/max.  Don't do something like
@@ -725,7 +755,7 @@ extern void     areads_relbuf     P((int fd));
  */
 
 #define        STR_SIZE        4096            /* a generic string buffer size */
-#define        NUM_STR_SIZE    32              /* a generic number buffer size */
+#define        NUM_STR_SIZE    128             /* a generic number buffer size */
 
 #define        skip_whitespace(ptr,c) do {                                     \
     while((c) != '\n' && isspace(c)) (c) = *(ptr)++;                   \
@@ -748,9 +778,34 @@ extern void     areads_relbuf     P((int fd));
     while(isdigit(c)) (c) = *(ptr)++;                                  \
 } while(0)
 
+#define skip_quoted_string(ptr, c) do {                                        \
+    int        iq = 0;                                                         \
+    while (((c) != '\0') && !((iq == 0) && isspace(c))) {              \
+       if ((c) == '"') {                                               \
+           iq = !iq;                                                   \
+       } else if (((c) == '\\') && (*(ptr) == '"')) {                  \
+           (ptr)++;                                                    \
+       }                                                               \
+       (c) = *(ptr)++;                                                 \
+    }                                                                  \
+} while (0)
+
+#define        skip_quoted_line(ptr, c) do {                                   \
+    int        iq = 0;                                                         \
+    while((c) && !((iq == 0) && ((c) == '\n'))) {                      \
+       if ((c) == '"')                                                 \
+           iq = !iq;                                                   \
+       (c) = *(ptr)++;                                                 \
+    }                                                                  \
+    if(c)                                                              \
+       (c) = *(ptr)++;                                                 \
+} while(0)
+
 #define        skip_line(ptr,c) do {                                           \
-    while((c) && (c) != '\n') (c) = *(ptr)++;                          \
-    if(c) (c) = *(ptr)++;                                              \
+    while((c) && (c) != '\n')                                          \
+       (c) = *(ptr)++;                                                 \
+    if(c)                                                              \
+       (c) = *(ptr)++;                                                 \
 } while(0)
 
 #define        copy_string(ptr,c,f,l,fp) do {                                  \
@@ -759,12 +814,14 @@ extern void     areads_relbuf     P((int fd));
        if((fp) >= (f) + (l) - 1) {                                     \
            *(fp) = '\0';                                               \
            (fp) = NULL;                                                \
+           (void)(fp);  /* Fix value never used warning at end of routines */ \
            break;                                                      \
        }                                                               \
        *(fp)++ = (c);                                                  \
        (c) = *(ptr)++;                                                 \
     }                                                                  \
-    if(fp) *fp = '\0';                                                 \
+    if(fp)                                                             \
+       *fp = '\0';                                                     \
 } while(0)
 
 #define        copy_string_cs(ptr,c,f,l,fp) do {                               \
@@ -787,27 +844,18 @@ extern void     areads_relbuf     P((int fd));
         || ((s)[1] == '.' && (s)[2] == '\0')))
 
 /* from amflock.c */
-extern int    amflock   P((int fd, char *resource));
-extern int    amroflock P((int fd, char *resource));
-extern int    amfunlock P((int fd, char *resource));
+extern int    amflock(int fd, char *resource);
+extern int    amroflock(int fd, char *resource);
+extern int    amfunlock(int fd, char *resource);
 
 /* from file.c */
-extern int    mkpdir    P((char *file, int mode, uid_t uid, gid_t gid));
-extern int    rmpdir    P((char *file, char *topdir));
-extern char  *sanitise_filename P((char *inp));
-
-/* from bsd-security.c */
-extern char  *check_user_ruserok     P((const char *host,
-                                       struct passwd *pwd,
-                                       const char *user));
-extern char  *check_user_amandahosts P((const char *host,
-                                       struct passwd *pwd,
-                                       const char *user));
+extern int    mkpdir(char *file, mode_t mode, uid_t uid, gid_t gid);
+extern int    rmpdir(char *file, char *topdir);
+extern char  *sanitise_filename(char *inp);
 
+/* from old bsd-security.c */
 extern int debug;
-extern int check_security P((struct sockaddr_in *, char *, unsigned long,
-                             char **));
-
+extern int check_security(struct sockaddr_in *, char *, unsigned long, char **);
 
 /*
  * Handle functions which are not always declared on all systems.  This
@@ -816,39 +864,39 @@ extern int check_security P((struct sockaddr_in *, char *, unsigned long,
 
 /* AIX #defines accept, and provides a prototype for the alternate name */
 #if !defined(HAVE_ACCEPT_DECL) && !defined(accept)
-extern int accept P((int s, struct sockaddr *addr, int *addrlen));
+extern int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
 #endif
 
 #ifndef HAVE_ATOF_DECL
-extern double atof P((const char *ptr));
+extern double atof(const char *ptr);
 #endif
 
 #ifndef HAVE_BCOPY
 # define bcopy(from,to,n) ((void)memmove((to), (from), (n)))
 #else
 # ifndef HAVE_BCOPY_DECL
-extern void bcopy P((const void *s1, void *s2, size_t n));
+extern void bcopy(const void *s1, void *s2, size_t n);
 # endif
 #endif
 
 #ifndef HAVE_BIND_DECL
-extern int bind P((int s, const struct sockaddr *name, int namelen));
+extern int bind(int s, const struct sockaddr *name, socklen_t namelen);
 #endif
 
 #ifndef HAVE_BZERO
 #define bzero(s,n) ((void)memset((s),0,(n)))
 #else
 # ifndef HAVE_BZERO_DECL
-extern void bzero P((void *s, size_t n));
+extern void bzero(void *s, size_t n);
 # endif
 #endif
 
 #ifndef HAVE_CLOSELOG_DECL
-extern void closelog P((void));
+extern void closelog(void);
 #endif
 
 #ifndef HAVE_CONNECT_DECL
-extern int connect P((int s, struct sockaddr *name, int namelen));
+extern int connect(int s, struct sockaddr *name, socklen_t namelen);
 #endif
 
 #if !defined(TEXTDB) && !defined(HAVE_DBM_OPEN_DECL)
@@ -869,77 +917,77 @@ extern int connect P((int s, struct sockaddr *name, int namelen));
     } datum;
 #endif
 
-    extern DBM   *dbm_open     P((char *file, int flags, int mode));
-    extern void   dbm_close    P((DBM *db));
-    extern datum  dbm_fetch    P((DBM *db, datum key));
-    extern datum  dbm_firstkey P((DBM *db));
-    extern datum  dbm_nextkey  P((DBM *db));
-    extern int    dbm_delete   P((DBM *db, datum key));
-    extern int    dbm_store    P((DBM *db, datum key, datum content, int flg));
+    extern DBM   *dbm_open(char *file, int flags, int mode);
+    extern void   dbm_close(DBM *db);
+    extern datum  dbm_fetch(DBM *db, datum key);
+    extern datum  dbm_firstkey(DBM *db);
+    extern datum  dbm_nextkey(DBM *db);
+    extern int    dbm_delete(DBM *db, datum key);
+    extern int    dbm_store(DBM *db, datum key, datum content, int flg);
 #endif
 
 #ifndef HAVE_FCLOSE_DECL
-extern int fclose P((FILE *stream));
+extern int fclose(FILE *stream);
 #endif
 
 #ifndef HAVE_FFLUSH_DECL
-extern int fflush P((FILE *stream));
+extern int fflush(FILE *stream);
 #endif
 
 #ifndef HAVE_FPRINTF_DECL
-extern int fprintf P((FILE *stream, const char *format, ...));
+extern int fprintf(FILE *stream, const char *format, ...);
 #endif
 
 #ifndef HAVE_FPUTC_DECL
-extern int fputc P((int c, FILE *stream));
+extern int fputc(int c, FILE *stream);
 #endif
 
 #ifndef HAVE_FPUTS_DECL
-extern int fputs P((const char *s, FILE *stream));
+extern int fputs(const char *s, FILE *stream);
 #endif
 
 #ifndef HAVE_FREAD_DECL
-extern size_t fread P((void *ptr, size_t size, size_t nitems, FILE *stream));
+extern size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
 #endif
 
 #ifndef HAVE_FSEEK_DECL
-extern int fseek P((FILE *stream, long offset, int ptrname));
+extern int fseek(FILE *stream, long offset, int ptrname);
 #endif
 
 #ifndef HAVE_FWRITE_DECL
-extern size_t fwrite P((const void *ptr, size_t size, size_t nitems,
-                       FILE *stream));
+extern size_t fwrite(const void *ptr, size_t size, size_t nitems,
+                       FILE *stream);
 #endif
 
 #ifndef HAVE_GETHOSTNAME_DECL
-extern int gethostname P((char *name, int namelen));
+extern int gethostname(char *name, int namelen);
 #endif
 
 #ifndef HAVE_GETOPT_DECL
 extern char *optarg;
-extern int getopt P((int argc, char * const *argv, const char *optstring));
+extern int getopt(int argc, char * const *argv, const char *optstring);
 #endif
 
 /* AIX #defines getpeername, and provides a prototype for the alternate name */
 #if !defined(HAVE_GETPEERNAME_DECL) && !defined(getpeername)
-extern int getpeername P((int s, struct sockaddr *name, int *namelen));
+extern int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
 #endif
 
 /* AIX #defines getsockname, and provides a prototype for the alternate name */
 #if !defined(HAVE_GETSOCKNAME_DECL) && !defined(getsockname)
-extern int getsockname P((int s, struct sockaddr *name, int *namelen));
+extern int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
 #endif
 
 #ifndef HAVE_GETSOCKOPT_DECL
-extern int getsockopt P((int s, int level, int optname, char *optval,
-                        int *optlen));
+extern int getsockopt(int s, int level, int optname, char *optval,
+                        socklen_t *optlen);
 #endif
 
 #ifndef HAVE_GETTIMEOFDAY_DECL
 # ifdef HAVE_TWO_ARG_GETTIMEOFDAY
-extern int gettimeofday P((struct timeval *tp, struct timezone *tzp));
+extern int gettimeofday(struct timeval *tp, struct timezone *tzp);
 # else
-extern int gettimeofday P((struct timeval *tp));
+extern int gettimeofday(struct timeval *tp);
 # endif
 #endif
 
@@ -947,245 +995,251 @@ extern int gettimeofday P((struct timeval *tp));
 # define initgroups(name,basegid) 0
 #else
 # ifndef HAVE_INITGROUPS_DECL
-extern int initgroups P((const char *name, gid_t basegid));
+extern int initgroups(const char *name, gid_t basegid);
 # endif
 #endif
 
 #ifndef HAVE_IOCTL_DECL
-extern int ioctl P((int fildes, int request, ...));
+extern int ioctl(int fildes, int request, ...);
+#endif
+
+#ifndef isnormal
+#ifndef HAVE_ISNORMAL
+#define        isnormal(f) (((f) < 0.0) || ((f) > 0.0))
+#endif
 #endif
 
 #ifndef HAVE_LISTEN_DECL
-extern int listen P((int s, int backlog));
+extern int listen(int s, int backlog);
 #endif
 
 #ifndef HAVE_LSTAT_DECL
-extern int lstat P((const char *path, struct stat *buf));
+extern int lstat(const char *path, struct stat *buf);
 #endif
 
 #ifndef HAVE_MALLOC_DECL
-extern void *malloc P((size_t size));
+extern void *malloc (size_t size);
 #endif
 
 #ifndef HAVE_MEMMOVE_DECL
 #ifdef HAVE_MEMMOVE
-extern void *memmove P((void *to, const void *from, size_t n));
+extern void *memmove(void *to, const void *from, size_t n);
 #else
-extern char *memmove P((char *to, /*const*/ char *from, size_t n));
+extern char *memmove(char *to, /*const*/ char *from, size_t n);
 #endif
 #endif
 
 #ifndef HAVE_MEMSET_DECL
-extern void *memset P((void *s, int c, size_t n));
+extern void *memset(void *s, int c, size_t n);
 #endif
 
 #ifndef HAVE_MKTEMP_DECL
-extern char *mktemp P((char *template));
+extern char *mktemp(char *template);
 #endif
 
 #ifndef HAVE_MKSTEMP_DECL
-extern int mkstemp P((char *template));
+extern int mkstemp(char *template);
 #endif
 
 #ifndef HAVE_MKTIME_DECL
-extern time_t mktime P((struct tm *timeptr));
+extern time_t mktime(struct tm *timeptr);
 #endif
 
 #ifndef HAVE_OPENLOG_DECL
 #ifdef LOG_AUTH
-extern void openlog P((const char *ident, int logopt, int facility));
+extern void openlog(const char *ident, int logopt, int facility);
 #else
-extern void openlog P((const char *ident, int logopt));
+extern void openlog(const char *ident, int logopt);
 #endif
 #endif
 
 #ifndef HAVE_PCLOSE_DECL
-extern int pclose P((FILE *stream));
+extern int pclose(FILE *stream);
 #endif
 
 #ifndef HAVE_PERROR_DECL
-extern void perror P((const char *s));
+extern void perror(const char *s);
 #endif
 
 #ifndef HAVE_PRINTF_DECL
-extern int printf P((const char *format, ...));
+extern int printf(const char *format, ...);
 #endif
 
 #ifndef HAVE_PUTS_DECL
-extern int puts P((const char *s));
+extern int puts(const char *s);
 #endif
 
 #ifndef HAVE_REALLOC_DECL
-extern void *realloc P((void *ptr, size_t size));
+extern void *realloc(void *ptr, size_t size);
 #endif
 
 /* AIX #defines recvfrom, and provides a prototype for the alternate name */
 #if !defined(HAVE_RECVFROM_DECL) && !defined(recvfrom)
-extern int recvfrom P((int s, char *buf, int len, int flags,
-                      struct sockaddr *from, int *fromlen));
+extern int recvfrom(int s, char *buf, int len, int flags,
+                      struct sockaddr *from, socklen_t *fromlen);
 #endif
 
 #ifndef HAVE_REMOVE_DECL
-extern int remove P((const char *path));
+extern int remove(const char *path);
 #endif
 
 #ifndef HAVE_RENAME_DECL
-extern int rename P((const char *old, const char *new));
+extern int rename(const char *old, const char *new);
 #endif
 
 #ifndef HAVE_REWIND_DECL
-extern void rewind P((FILE *stream));
+extern void rewind(FILE *stream);
 #endif
 
 #ifndef HAVE_RUSEROK_DECL
-extern int ruserok P((const char *rhost, int suser,
-                     const char *ruser, const char *luser));
+extern int ruserok(const char *rhost, int suser,
+                     const char *ruser, const char *luser);
 #endif
 
 #ifndef HAVE_SELECT_DECL
-extern int select P((int nfds,
+extern int select(int nfds,
                     SELECT_ARG_TYPE *readfds,
                     SELECT_ARG_TYPE *writefds,
                     SELECT_ARG_TYPE *exceptfds,
-                    struct timeval *timeout));
+                    struct timeval *timeout);
 #endif
 
 #ifndef HAVE_SENDTO_DECL
-extern int sendto P((int s, const char *msg, int len, int flags,
-                    const struct sockaddr *to, int tolen));
+extern int sendto(int s, const char *msg, int len, int flags,
+                    const struct sockaddr *to, int tolen);
 #endif
 
 #ifdef HAVE_SETRESGID
-#define        setegid(x)      setresgid(-1,(x),-1)
+#define        setegid(x)      setresgid((gid_t)-1,(x),(gid_t)-1)
 #ifndef HAVE_SETRESGID_DECL
-extern int setresgid P((gid_t rgid, gid_t egid, gid_t sgid));
+extern int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
 #endif
 #else
 #ifndef HAVE_SETEGID_DECL
-extern int setegid P((gid_t egid));
+extern int setegid(gid_t egid);
 #endif
 #endif
 
 #ifdef HAVE_SETRESUID
-#define        seteuid(x)      setresuid(-1,(x),-1)
+#define        seteuid(x)      setresuid((uid_t)-1,(x),(uid_t)-1)
 #ifndef HAVE_SETRESUID_DECL
-extern int setresuid P((uid_t ruid, uid_t euid, uid_t suid));
+extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);
 #endif
 #else
 #ifndef HAVE_SETEUID_DECL
-extern int seteuid P((uid_t euid));
+extern int seteuid(uid_t euid);
 #endif
 #endif
 
 #ifndef HAVE_SETPGID_DECL
 #ifdef HAVE_SETPGID
-extern int setpgid P((int pid, int pgid));
+extern int setpgid(pid_t pid, pid_t pgid);
 #endif
 #endif
 
 #ifndef HAVE_SETPGRP_DECL
 #ifdef SETPGRP_VOID
-extern pid_t setpgrp P((void));
+extern pid_t setpgrp(void);
 #else
-extern pid_t setpgrp P((int pgrp, int pid));
+extern pid_t setpgrp(pid_t pgrp, pid_t pid);
 #endif
 #endif
 
 #ifndef HAVE_SETSOCKOPT_DECL
-extern int setsockopt P((int s, int level, int optname,
-                        const char *optval, int optlen));
+extern int setsockopt(int s, int level, int optname,
+                        const char *optval, int optlen);
 #endif
 
 #ifdef HAVE_SHMGET
 #ifndef HAVE_SHMAT_DECL
-extern void *shmat P((int shmid, const SHM_ARG_TYPE *shmaddr, int shmflg));
+extern void *shmat(int shmid, const SHM_ARG_TYPE *shmaddr, int shmflg);
 #endif
 
 #ifndef HAVE_SHMCTL_DECL
-extern int shmctl P((int shmid, int cmd, struct shmid_ds *buf));
+extern int shmctl(int shmid, int cmd, struct shmid_ds *buf);
 #endif
 
 #ifndef HAVE_SHMDT_DECL
-extern int shmdt P((SHM_ARG_TYPE *shaddr));
+extern int shmdt(SHM_ARG_TYPE *shaddr);
 #endif
 
 #ifndef HAVE_SHMGET_DECL
-extern int shmget P((key_t key, size_t size, int shmflg));
+extern int shmget(key_t key, size_t size, int shmflg);
 #endif
 #endif
 
 #ifndef HAVE_SNPRINTF_DECL
 #include "arglist.h"
-int snprintf  P((char *buf, size_t len, const char *format,...))
+int snprintf(char *buf, size_t len, const char *format,...)
                    __attribute__((format(printf,3,4)));
 #endif
 #ifndef HAVE_VSNPRINTF_DECL
 #include "arglist.h"
-int vsnprintf P((char *buf, size_t len, const char *format, va_list ap));
+int vsnprintf(char *buf, size_t len, const char *format, va_list ap);
 #endif
 
 #ifndef HAVE_SOCKET_DECL
-extern int socket P((int domain, int type, int protocol));
+extern int socket(int domain, int type, int protocol);
 #endif
 
 #ifndef HAVE_SOCKETPAIR_DECL
-extern int socketpair P((int domain, int type, int protocol, int sv[2]));
+extern int socketpair(int domain, int type, int protocol, int sv[2]);
 #endif
 
 #ifndef HAVE_SSCANF_DECL
-extern int sscanf P((const char *s, const char *format, ...));
+extern int sscanf(const char *s, const char *format, ...);
 #endif
 
 #ifndef HAVE_STRCASECMP_DECL
-extern int strcasecmp P((const char *s1, const char *s2));
+extern int strcasecmp(const char *s1, const char *s2);
 #endif
 
 #ifndef HAVE_STRERROR_DECL
-extern char *strerror P((int errnum));
+extern char *strerror(int errnum);
 #endif
 
 #ifndef HAVE_STRFTIME_DECL
-extern size_t strftime P((char *s, size_t maxsize, const char *format,
-                         const struct tm *timeptr));
+extern size_t strftime(char *s, size_t maxsize, const char *format,
+                         const struct tm *timeptr);
 #endif
 
 #ifndef HAVE_STRNCASECMP_DECL
-extern int strncasecmp P((const char *s1, const char *s2, int n));
+extern int strncasecmp(const char *s1, const char *s2, int n);
 #endif
 
 #ifndef HAVE_SYSLOG_DECL
-extern void syslog P((int priority, const char *logstring, ...))
+extern void syslog(int priority, const char *logstring, ...)
     __attribute__ ((format (printf, 2, 3)));
 #endif
 
 #ifndef HAVE_SYSTEM_DECL
-extern int system P((const char *string));
+extern int system(const char *string);
 #endif
 
 #ifndef HAVE_TIME_DECL
-extern time_t time P((time_t *tloc));
+extern time_t time(time_t *tloc);
 #endif
 
 #ifndef HAVE_TOLOWER_DECL
-extern int tolower P((int c));
+extern int tolower(int c);
 #endif
 
 #ifndef HAVE_TOUPPER_DECL
-extern int toupper P((int c));
+extern int toupper(int c);
 #endif
 
 #ifndef HAVE_UNGETC_DECL
-extern int ungetc P((int c, FILE *stream));
+extern int ungetc(int c, FILE *stream);
 #endif
 
 #ifndef HAVE_VFPRINTF_DECL
 #include "arglist.h"
-extern int vfprintf P((FILE *stream, const char *format, va_list ap));
+extern int vfprintf(FILE *stream, const char *format, va_list ap);
 #endif
 
 #ifndef HAVE_VPRINTF_DECL
 #include "arglist.h"
-extern int vprintf P((const char *format, va_list ap));
+extern int vprintf(const char *format, va_list ap);
 #endif
 
 #if !defined(S_ISCHR) && defined(_S_IFCHR) && defined(_S_IFMT)
@@ -1200,12 +1254,12 @@ extern int vprintf P((const char *format, va_list ap));
 #ifdef HAVE_WAIT4
 #define waitpid(pid,status,options) wait4(pid,status,options,0)
 #else
-extern pid_t waitpid P((pid_t pid, amwait_t *stat_loc, int options));
+extern pid_t waitpid(pid_t pid, amwait_t *stat_loc, int options);
 #endif
 #endif
 
 #ifndef HAVE_WRITEV_DECL
-extern ssize_t writev P((int fd, const struct iovec *iov, int iovcnt));
+extern ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
 #endif
 
 #ifndef STDIN_FILENO
@@ -1225,82 +1279,147 @@ extern ssize_t writev P((int fd, const struct iovec *iov, int iovcnt));
 #if defined(_S_IFMT) && defined(_S_IFDIR)
 #define S_ISDIR(mode)   (((mode) & (_S_IFMT)) == (_S_IFDIR))
 #else
-error: Don t know how to define S_ISDIR
+#error Don t know how to define S_ISDIR
+#endif
+#endif
+
+#if SIZEOF_SIZE_T == SIZEOF_INT
+#  define        SIZE_T_FMT    "%u"
+#  define        SIZE_T_FMT_TYPE unsigned
+#  define        SIZE_T_ATOI   (size_t)atoi
+#  ifndef SIZE_MAX
+#    define      SIZE_MAX      UINT_MAX
+#  endif
+#else
+#  define        SIZE_T_FMT    "%lu"
+#  define        SIZE_T_FMT_TYPE unsigned long
+#  define        SIZE_T_ATOI   (size_t)atol
+#  ifndef SIZE_MAX
+#    define      SIZE_MAX      ULONG_MAX
+#  endif
+#endif
+
+#if SIZEOF_SSIZE_T == SIZEOF_INT
+#  define        SSIZE_T_FMT   "%d"
+#  define        SSIZE_T_FMT_TYPE int
+#  define        SSIZE_T_ATOI  (ssize_t)atoi
+#  ifndef SSIZE_MAX
+#    define      SSIZE_MAX     INT_MAX
+#  endif
+#  ifndef SSIZE_MIN
+#    define      SSIZE_MIN     INT_MIN
+#  endif
+#else
+#  define        SSIZE_T_FMT   "%ld"
+#  define        SSIZE_T_FMT_TYPE long
+#  define        SSIZE_T_ATOI  (ssize_t)atol
+#  ifndef SSIZE_MAX
+#    define      SSIZE_MAX     LONG_MAX
+#  endif
+#  ifndef SSIZE_MIN
+#    define      SSIZE_MIN     LONG_MIN
+#  endif
 #endif
+
+#if SIZEOF_TIME_T == SIZEOF_INT
+#  define        TIME_T_FMT    "%u"
+#  define        TIME_T_FMT_TYPE unsigned
+#  define        TIME_T_ATOI   (time_t)atoi
+#  ifndef TIME_MAX
+#    define      TIME_MAX      UINT_MAX
+#  endif
+#else
+#  define        TIME_T_FMT    "%lu"
+#  define        TIME_T_FMT_TYPE unsigned long
+#  define        TIME_T_ATOI   (time_t)atol
+#  ifndef TIME_MAX
+#    define      TIME_MAX      ULONG_MAX
+#  endif
 #endif
 
 #if SIZEOF_OFF_T > SIZEOF_LONG
-#  define        OFF_T_FMT       LL_FMT
+#  define        OFF_T_FMT       "%lld"
+#  define        OFF_T_RFMT       "lld"
+#  define        OFF_T_FMT_TYPE  long long
+#  define        OFF_T_ATOI     (off_t)atoll
+#  define        OFF_T_STRTOL   (off_t)strtoll
 #else
-#  define        OFF_T_FMT       "%ld"
+#  if SIZEOF_OFF_T == SIZEOF_LONG
+#    define        OFF_T_FMT       "%ld"
+#    define        OFF_T_RFMT      "ld"
+#    define        OFF_T_FMT_TYPE  long
+#    define        OFF_T_ATOI   (off_t)atol
+#    define        OFF_T_STRTOL         (off_t)strtol
+#  else
+#    define        OFF_T_FMT       "%d"
+#    define        OFF_T_RFMT      "d"
+#    define        OFF_T_FMT_TYPE  int
+#    define        OFF_T_ATOI   (off_t)atoi
+#    define        OFF_T_STRTOL         (off_t)strtol
+#  endif
 #endif
 
+#if SIZEOF_OFF_T == 8
+#  ifdef OFF_MAX
+#    define AM64_MAX (off_t)(OFF_MAX)
+#  else
+#    define AM64_MAX (off_t)(9223372036854775807LL)
+#  endif
+#  ifdef OFF_MIN
+#    define AM64_MIN (off_t)(OFF_MIN)
+#  else
+#    define AM64_MIN (off_t)(-9223372036854775807LL -1LL)
+#  endif
+#  define AM64_FMT OFF_T_FMT
+#else
 #if SIZEOF_LONG == 8
-   typedef long am64_t;
 #  ifdef LONG_MAX
-#    define AM64_MAX LONG_MAX
+#    define AM64_MAX (off_t)(LONG_MAX)
 #  else
-#    define AM64_MAX 9223372036854775807L
+#    define AM64_MAX (off_t)9223372036854775807L
 #  endif
 #  ifdef LONG_MIN
-#    define AM64_MIN LONG_MIN
+#    define AM64_MIN (off_t)(LONG_MIN)
 #  else
-#    define AM64_MIN -9223372036854775807L -1L
+#    define AM64_MIN (off_t)(-9223372036854775807L -1L)
 #  endif
 #  define AM64_FMT "%ld"
 #else
 #if SIZEOF_LONG_LONG == 8
-   typedef long long am64_t;
 #  ifdef LONG_LONG_MAX
-#    define AM64_MAX LONG_LONG_MAX
+#    define AM64_MAX (off_t)(LONG_LONG_MAX)
 #  else
-#    define AM64_MAX 9223372036854775807LL
+#    define AM64_MAX (off_t)9223372036854775807LL
 #  endif
 #  ifdef LONG_LONG_MIN
-#    define AM64_MIN LONG_LONG_MIN
+#    define AM64_MIN (off_t)(LONG_LONG_MIN)
 #  else
-#    define AM64_MIN -9223372036854775807LL -1LL
+#    define AM64_MIN (off_t)(-9223372036854775807LL -1LL)
 #  endif
 #  define AM64_FMT LL_FMT
 #else
 #if SIZEOF_INTMAX_T == 8
-   typedef intmax_t am64_t;
 #  ifdef INTMAX_MAX
-#    define AM64_MAX INTMAX_MAX
+#    define AM64_MAX (off_t)(INTMAX_MAX)
 #  else
-#    define AM64_MAX 9223372036854775807LL
+#    define AM64_MAX (off_t)9223372036854775807LL
 #  endif
 #  ifdef INTMAX_MIN
-#    define AM64_MIN INTMAX_MIN
+#    define AM64_MIN (off_t)(INTMAX_MIN)
 #  else
-#    define AM64_MIN -9223372036854775807LL -1LL
+#    define AM64_MIN (off_t)(-9223372036854775807LL -1LL)
 #  endif
 #  define AM64_FMT LL_FMT
-#else
-#if SIZEOF_OFF_T == 8
-   typedef off_t am64_t;
-#  ifdef OFF_MAX
-#    define AM64_MAX OFF_MAX
-#  else
-#    define AM64_MAX 9223372036854775807LL
-#  endif
-#  ifdef OFF_MIN
-#    define AM64_MIN OFF_MIN
-#  else
-#    define AM64_MIN -9223372036854775807LL -1LL
-#  endif
-#  define AM64_FMT OFF_T_FMT
-#else  /* no 64 bits tyupe found, use long. */
-   typedef long am64_t;
+#else  /* no 64 bits type found, use long. */
 #  ifdef LONG_MAX
-#    define AM64_MAX LONG_MAX
+#    define AM64_MAX (off_t)(LONG_MAX)
 #  else
-#    define AM64_MAX 2147483647
+#    define AM64_MAX (off_t)2147483647
 #  endif
 #  ifdef LONG_MIN
-#    define AM64_MIN LONG_MIN
+#    define AM64_MIN (off_t)(LONG_MIN)
 #  else
-#    define AM64_MIN -2147483647 -1
+#    define AM64_MIN (off_t)(-2147483647 -1)
 #  endif
 #  define AM64_FMT "%ld"
 #endif
@@ -1308,4 +1427,33 @@ error: Don t know how to define S_ISDIR
 #endif
 #endif
 
+#ifdef HAVE_LIBREADLINE
+#  ifdef HAVE_READLINE_READLINE_H
+#    include <readline/readline.h>
+#    ifdef HAVE_READLINE_HISTORY_H
+#      include <readline/history.h>
+#    endif
+#  else
+#    ifdef HAVE_READLINE_H
+#      include <readline.h>
+#      ifdef HAVE_HISTORY_H
+#        include <history.h>
+#      endif
+#    else
+#      undef HAVE_LIBREADLINE
+#    endif
+#  endif
+#else
+
+char * readline(const char *prompt);
+void   add_history(const char *line);
+
+#endif
+
+#define BIND_CYCLE_RETRIES     120             /* Total of 30 minutes */
+
+#define DBG_SUBDIR_SERVER  "server"
+#define DBG_SUBDIR_CLIENT  "client"
+#define DBG_SUBDIR_AMANDAD "amandad"
+
 #endif /* !AMANDA_H */
index 94fad87839fb396a2086fd15a0d14f86495bd3f7..89a1c3829dbc542acb02404295665584dc93f554 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*
- * $Id: amfeatures.c,v 1.18 2006/03/14 13:11:58 martinea Exp $
+ * $Id: amfeatures.c,v 1.24 2006/07/19 17:46:07 martinea Exp $
  *
  * Feature test related code.
  */
@@ -45,9 +45,9 @@
  */
 
 am_feature_t *
-am_init_feature_set()
+am_init_feature_set(void)
 {
-    am_feature_t               *f = NULL;
+    am_feature_t               *f;
 
     if ((f = am_allocate_feature_set()) != NULL) {
        /*
@@ -109,13 +109,11 @@ am_init_feature_set()
        am_add_feature(f, fe_amidxtaped_nargs);
        am_add_feature(f, fe_amidxtaped_config);
 
-        am_add_feature(f, fe_recover_splits);
-        am_add_feature(f, fe_amidxtaped_exchange_features);
-
+       am_add_feature(f, fe_recover_splits);
+       am_add_feature(f, fe_amidxtaped_exchange_features);
        am_add_feature(f, fe_partial_estimate);
        am_add_feature(f, fe_calcsize_estimate);
        am_add_feature(f, fe_selfcheck_calcsize);
-
        am_add_feature(f, fe_options_compress_cust);
        am_add_feature(f, fe_options_srvcomp_cust);
        am_add_feature(f, fe_options_encrypt_cust);
@@ -123,11 +121,30 @@ am_init_feature_set()
        am_add_feature(f, fe_options_client_decrypt_option);
        am_add_feature(f, fe_options_server_decrypt_option);
 
-        am_add_feature(f, fe_amindexd_marshall_in_OLSD);
-        am_add_feature(f, fe_amindexd_marshall_in_ORLD);
-        am_add_feature(f, fe_amindexd_marshall_in_DHST);
+       am_add_feature(f, fe_amindexd_marshall_in_OLSD);
+       am_add_feature(f, fe_amindexd_marshall_in_ORLD);
+       am_add_feature(f, fe_amindexd_marshall_in_DHST);
 
         am_add_feature(f, fe_amrecover_FEEDME);
+        am_add_feature(f, fe_amrecover_timestamp);
+
+        am_add_feature(f, fe_interface_quoted_text);
+
+       am_add_feature(f, fe_program_star);
+
+       am_add_feature(f, fe_amindexd_options_hostname);
+       am_add_feature(f, fe_amindexd_options_features);
+       am_add_feature(f, fe_amindexd_options_auth);
+
+       am_add_feature(f, fe_amidxtaped_options_hostname);
+       am_add_feature(f, fe_amidxtaped_options_features);
+       am_add_feature(f, fe_amidxtaped_options_auth);
+
+       am_add_feature(f, fe_amrecover_message);
+       am_add_feature(f, fe_amrecover_feedme_tape);
+
+       am_add_feature(f, fe_req_options_config);
+
     }
     return f;
 }
@@ -192,13 +209,13 @@ am_set_default_feature_set(void)
  */
 
 am_feature_t *
-am_allocate_feature_set()
+am_allocate_feature_set(void)
 {
     size_t                     nbytes;
     am_feature_t               *result;
 
-    result = (am_feature_t *)alloc(sizeof(*result));
-    memset(result, 0, sizeof(*result));
+    result = (am_feature_t *)alloc(SIZEOF(*result));
+    memset(result, 0, SIZEOF(*result));
     nbytes = (((size_t)last_feature) + 8) >> 3;
     result->size = nbytes;
     result->bytes = (unsigned char *)alloc(nbytes);
@@ -218,8 +235,8 @@ am_allocate_feature_set()
  */
 
 void
-am_release_feature_set(f)
-    am_feature_t               *f;
+am_release_feature_set(
+    am_feature_t       *f)
 {
     if (f != NULL) {
        amfree(f->bytes);
@@ -242,9 +259,9 @@ am_release_feature_set(f)
  */
 
 int
-am_add_feature(f, n)
-    am_feature_t               *f;
-    am_feature_e               n;
+am_add_feature(
+    am_feature_t       *f,
+    am_feature_e       n)
 {
     size_t                     byte;
     int                                bit;
@@ -254,7 +271,7 @@ am_add_feature(f, n)
        byte = ((size_t)n) >> 3;
        if (byte < f->size) {
            bit = ((int)n) & 0x7;
-           f->bytes[byte] |= (1 << bit);
+           f->bytes[byte] = (unsigned char)((int)f->bytes[byte] | (unsigned char)(1 << bit));
            result = 1;
        }
     }
@@ -275,9 +292,9 @@ am_add_feature(f, n)
  */
 
 int
-am_remove_feature(f, n)
-    am_feature_t               *f;
-    am_feature_e               n;
+am_remove_feature(
+    am_feature_t       *f,
+    am_feature_e       n)
 {
     size_t                     byte;
     int                                bit;
@@ -287,7 +304,7 @@ am_remove_feature(f, n)
        byte = ((size_t)n) >> 3;
        if (byte < f->size) {
            bit = ((int)n) & 0x7;
-           f->bytes[byte] &= ~(1 << bit);
+           f->bytes[byte] = (unsigned char)((int)f->bytes[byte] & (unsigned char)~(1 << bit));
            result = 1;
        }
     }
@@ -307,9 +324,9 @@ am_remove_feature(f, n)
  */
 
 int
-am_has_feature(f, n)
-    am_feature_t               *f;
-    am_feature_e               n;
+am_has_feature(
+    am_feature_t       *f,
+    am_feature_e       n)
 {
     size_t                     byte;
     int                                bit;
@@ -337,8 +354,8 @@ am_has_feature(f, n)
  */
 
 char *
-am_feature_to_string(f)
-    am_feature_t               *f;
+am_feature_to_string(
+    am_feature_t       *f)
 {
     char                       *result;
     size_t                     i;
@@ -376,8 +393,8 @@ am_feature_to_string(f)
  */
 
 am_feature_t *
-am_string_to_feature(s)
-    char                       *s;
+am_string_to_feature(
+    char               *s)
 {
     am_feature_t               *f = NULL;
     size_t                     i;
@@ -410,7 +427,7 @@ am_string_to_feature(s)
                amfree(f);                              /* bad conversion */
                break;
            }
-           f->bytes[i] = (ch1 << 4) | ch2;
+           f->bytes[i] = (unsigned char)((ch1 << 4) | ch2);
        }
     }
     return f;
@@ -418,9 +435,9 @@ am_string_to_feature(s)
 
 #if defined(TEST)
 int
-main(argc, argv)
-    int                                argc;
-    char                       **argv;
+main(
+    int                argc,
+    char       **argv)
 {
     am_feature_t               *f;
     am_feature_t               *f1;
index 8d9e9bddffd5f275c5bd5d68c9b8bc06f3ab1934..562ca2193d99b5fe687b0b96b3bed429b386dc9e 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*
- * $Id: amfeatures.h,v 1.15 2006/03/14 13:11:58 martinea Exp $
+ * $Id: amfeatures.h,v 1.21 2006/07/19 17:46:07 martinea Exp $
  *
  * Define feature test related items.
  */
@@ -152,6 +152,24 @@ typedef enum {
     fe_amindexd_marshall_in_ORLD,
     fe_amindexd_marshall_in_DHST,
     fe_amrecover_FEEDME,
+    fe_amrecover_timestamp,
+
+    fe_interface_quoted_text,
+
+    fe_program_star,
+
+    fe_amindexd_options_hostname,
+    fe_amindexd_options_features,
+    fe_amindexd_options_auth,
+
+    fe_amidxtaped_options_hostname,
+    fe_amidxtaped_options_features,
+    fe_amidxtaped_options_auth,
+
+    fe_amrecover_message,
+    fe_amrecover_feedme_tape,
+
+    fe_req_options_config,
 
     /*
      * All new features must be inserted immediately *before* this entry.
@@ -167,14 +185,14 @@ typedef struct am_feature_s {
 /*
  * Functions.
  */
-extern am_feature_t *am_init_feature_set P((void));
-extern am_feature_t *am_set_default_feature_set P((void));
-extern am_feature_t *am_allocate_feature_set P((void));
-extern void am_release_feature_set P((am_feature_t *));
-extern int am_add_feature P((am_feature_t *f, am_feature_e n));
-extern int am_remove_feature P((am_feature_t *f, am_feature_e n));
-extern int am_has_feature P((am_feature_t *f, am_feature_e n));
-extern char *am_feature_to_string P((am_feature_t *f));
-extern am_feature_t *am_string_to_feature P((char *s));
+extern am_feature_t *am_init_feature_set(void);
+extern am_feature_t *am_set_default_feature_set(void);
+extern am_feature_t *am_allocate_feature_set(void);
+extern void am_release_feature_set(am_feature_t *);
+extern int am_add_feature(am_feature_t *f, am_feature_e n);
+extern int am_remove_feature(am_feature_t *f, am_feature_e n);
+extern int am_has_feature(am_feature_t *f, am_feature_e n);
+extern char *am_feature_to_string(am_feature_t *f);
+extern am_feature_t *am_string_to_feature(char *s);
 
 #endif /* !AMFEATURES_H */
index 9fe27c7c575397c2e1878c3ef92b524b4bc9dcb0..2a00b38835e33cf4ec3b819b62d41fed8725caf0 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amflock.c,v 1.27 2005/10/06 17:26:21 martinea Exp $
+ * $Id: amflock.c,v 1.28 2006/05/25 01:47:11 johnfranks Exp $
  *
  * file locking routines, put here to hide the system dependant stuff
  * from the rest of the code
@@ -57,7 +57,7 @@
 #  endif
 
 #  if !defined(HAVE_FLOCK_DECL) && !defined(CONFIGURE_TEST)
-     extern int flock P((int fd, int operation));
+     extern int flock(int fd, int operation);
 #  endif
 #endif
 
 ** - returns errors for some non-files like pipes.
 ** - probably only works for files open for writing.
 */
-int use_lockf(fd, op)
-int fd; /* fd of file to operate on */
-int op;        /* true to lock; false to unlock */
+int
+use_lockf(
+    int fd,    /* fd of file to operate on */
+    int op)    /* true to lock; false to unlock */
 {
        off_t pos;
 
@@ -109,8 +110,9 @@ int op;     /* true to lock; false to unlock */
 
 /* Delete a lock file.
 */
-int delete_lock(fn)
-char *fn;
+int
+delete_lock(
+    char *fn)
 {
        int rc;
 
@@ -122,9 +124,10 @@ char *fn;
 
 /* Create a lock file.
 */
-int create_lock(fn, pid)
-char *fn;
-long pid;
+int
+create_lock(
+    char *fn,
+    pid_t pid)
 {
        int fd;
        FILE *f;
@@ -133,7 +136,7 @@ long pid;
        (void)delete_lock(fn);                  /* that's MY file! */
 
        mask = umask(0027);
-       fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0640);
+       fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0640);
        umask(mask);
        if (fd == -1) return -1;
 
@@ -150,8 +153,9 @@ long pid;
 /* Read the pid out of a lock file.
 **   -1=error, otherwise pid.
 */
-long read_lock(fn)
-char *fn; /* name of lock file */
+long
+read_lock(
+    char *     fn) /* name of lock file */
 {
        int save_errno;
        FILE *f;
@@ -175,9 +179,10 @@ char *fn; /* name of lock file */
 /* Link a lock if we can.
 **   0=done, 1=already locked, -1=error.
 */
-int link_lock(lk, tlk)
-char *lk;      /* real lock file */
-char *tlk;     /* temp lock file */
+int
+link_lock(
+    char *     lk,     /* real lock file */
+    char *     tlk)    /* temp lock file */
 {
        int rc;
        int serrno;     /* saved errno */
@@ -205,10 +210,11 @@ char *tlk;        /* temp lock file */
 /* Steal a lock if we can.
 **   0=done; 1=still in use; -1 = error.
 */
-int steal_lock(fn, mypid, sres)
-char *fn;      /* name of lock file to steal */
-long mypid;    /* my process id */
-char *sres;    /* name of steal-resource to lock */
+int
+steal_lock(
+    char *     fn,     /* name of lock file to steal */
+    pid_t      mypid,  /* my process id */
+    char *     sres)   /* name of steal-resource to lock */
 {
        int fd;
        char buff[64];
@@ -258,9 +264,10 @@ error:
 
 /* Locking using existance of a file.
 */
-int ln_lock(res, op)
-char *res; /* name of resource to lock */
-int op;    /* true to lock; false to unlock */
+int
+ln_lock(
+    char *     res, /* name of resource to lock */
+    int                op)  /* true to lock; false to unlock */
 {
        long mypid;
        char *lockfile = NULL;
@@ -284,7 +291,7 @@ int op;    /* true to lock; false to unlock */
 
        /* lock the resource */
 
-       snprintf(pid_str, sizeof(pid_str), "%ld", mypid);
+       snprintf(pid_str, SIZEOF(pid_str), "%ld", mypid);
        tlockfile = vstralloc(AMANDA_TMPDIR, "am", res, ".", pid_str, NULL);
 
        (void)create_lock(tlockfile, mypid);
@@ -313,19 +320,23 @@ int op;    /* true to lock; false to unlock */
 #endif
 
 
-/* Get a file lock (for read-only files).
-*/
-int amroflock(fd, resource)
-int fd;
-char *resource;
+/*
+ * Get a file lock (for read-only files).
+ */
+int
+amroflock(
+    int                fd,
+    char *     resource)
 {
        int r;
 
 #ifdef USE_POSIX_FCNTL
+       (void)resource; /* Quiet unused paramater warning */
        lock.l_type = F_RDLCK;
        lock.l_whence = SEEK_SET;
        r = fcntl(fd, F_SETLKW, &lock);
 #else
+       (void)fd; /* Quiet unused paramater warning */
        r = amflock(fd, resource);
 #endif
 
@@ -335,26 +346,33 @@ char *resource;
 
 /* Get a file lock (for read/write files).
 */
-int amflock(fd, resource)
-int fd;
-char *resource;
+int
+amflock(
+    int                fd,
+    char *     resource)
 {
        int r;
 
 #ifdef USE_POSIX_FCNTL
+       (void)resource; /* Quiet unused paramater warning */
        lock.l_type = F_WRLCK;
        lock.l_whence = SEEK_SET;
        r = fcntl(fd, F_SETLKW, &lock);
 #else
 #ifdef USE_FLOCK
+       (void)resource; /* Quiet unused paramater warning */
        r = flock(fd, LOCK_EX);
 #else
 #ifdef USE_LOCKF
+       (void)resource; /* Quiet unused paramater warning */
        r = use_lockf(fd, 1);
 #else
 #ifdef USE_LNLOCK
+       (void)fd; /* Quiet unused paramater warning */
        r = ln_lock(resource, 1);
 #else
+       (void)fd; /* Quiet unused paramater warning */
+       (void)resource; /* Quiet unused paramater warning */
        r = 0;
 #endif
 #endif
@@ -367,26 +385,33 @@ char *resource;
 
 /* Release a file lock.
 */
-int amfunlock(fd, resource)
-int fd;
-char *resource;
+int
+amfunlock(
+    int                fd,
+    char *     resource)
 {
        int r;
 
 #ifdef USE_POSIX_FCNTL
+       (void)resource; /* Quiet unused paramater warning */
        lock.l_type = F_UNLCK;
        lock.l_whence = SEEK_SET;
        r = fcntl(fd, F_SETLK, &lock);
 #else
 #ifdef USE_FLOCK
+       (void)resource; /* Quiet unused paramater warning */
        r = flock(fd, LOCK_UN);
 #else
 #ifdef USE_LOCKF
+       (void)fd; /* Quiet unused paramater warning */
        r = use_lockf(fd, 0);
 #else
 #ifdef USE_LNLOCK
+       (void)fd; /* Quiet unused paramater warning */
        r = ln_lock(resource, 0);
 #else
+       (void)fd; /* Quiet unused paramater warning */
+       (void)resource; /* Quiet unused paramater warning */
        r = 0;
 #endif
 #endif
@@ -407,15 +432,21 @@ char *resource;
 **     for ever.
 */
 #ifdef CONFIGURE_TEST
-main()
+int
+main(
+    int argc,
+    char **argv)
 {
     int lockfd;
     char *filen = "/tmp/conftest.lock";
     char *resn = "test";
     int fd;
 
+    (void)argc;                /* Quiet compiler warning */
+    (void)argv;                /* Quiet compiler warning */
+
     unlink(filen);
-    if ((lockfd = open(filen, O_RDONLY|O_CREAT|O_EXCL, 0600)) == -1) {
+    if ((lockfd = open(filen, O_RDONLY | O_CREAT | O_EXCL, 0600)) == -1) {
        perror (filen);
        exit(10);
     }
@@ -437,7 +468,7 @@ main()
     close(lockfd);
 
     unlink(filen);
-    if ((lockfd = open(filen, O_WRONLY|O_CREAT|O_EXCL, 0600)) == -1) {
+    if ((lockfd = open(filen, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) {
        perror (filen);
        exit(20);
     }
index 6aa54c6fc4ffb32ea54e0203e9b10bc1041f67be..dfbc3b4e8587db6a701535a7b8a0e51a5c3b33d5 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amregex.h,v 1.10 1999/04/10 06:18:44 kashmir Exp $
+ * $Id: amregex.h,v 1.11 2006/05/25 01:47:11 johnfranks Exp $
  *
  * compatibility header file for Henry Spencer's regex library.
  */
 #define CHAR_BIT 8
 #endif
 
-#if STDC_HEADERS
-#  define P(parms)     parms
-#else
-#  define P(parms)     ()
-#endif
-
 /*
  * So that we can use GNUC attributes (such as to get -Wall warnings
  * for printf-like functions).  Only do this in gcc 2.7 or later ...
 #endif
 
 #ifndef HAVE_BCOPY_DECL
-extern void bcopy P((const void *from, void *to, size_t n));
+extern void bcopy(const void *from, void *to, size_t n);
 #endif
 
 #ifndef HAVE_MEMMOVE_DECL
-extern char *memmove P((char *to, char *from, size_t n));
+extern char *memmove(char *to, char *from, size_t n);
 #endif
 
 #ifndef HAVE_MEMSET_DECL
-extern void *memset P((void *s, int c, size_t n));
+extern void *memset(void *s, int c, size_t n);
 #endif
 
 #if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY)
@@ -94,12 +88,12 @@ extern void *memset P((void *s, int c, size_t n));
 
 #ifndef HAVE_SNPRINTF_DECL
 #include "arglist.h"
-int snprintf  P((char *buf, size_t len, const char *format,...))
+int snprintf (char *buf, size_t len, const char *format,...)
                    __attribute__((format(printf,3,4)));
 #endif
 #ifndef HAVE_VSNPRINTF_DECL
 #include "arglist.h"
-int vsnprintf P((char *buf, size_t len, const char *format, va_list ap));
+int vsnprintf(char *buf, size_t len, const char *format, va_list ap);
 #endif
 
 #define POSIX_MISTAKE
index 1c87202cda094d6697c0d9bd8607691273584140..e18b4a79e5fb485096d33f0b6db03f5d98e53fee 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: arglist.h,v 1.7 2002/12/03 21:36:39 martinea Exp $
+ * $Id: arglist.h,v 1.9 2006/06/16 11:33:43 martinea Exp $
  *
  * support macros for variable argument list declaration and definition
  */
              arg2_type arg2_name, \
              hook_type hook_name, ...)
 
+#define printf_arglist_function3(fdecl, \
+                                arg1_type, arg1_name, \
+                                arg2_type, arg2_name, \
+                                arg3_type, arg3_name, \
+                                hook_type, hook_name) \
+       __attribute__ ((format (printf, 4, 0))) \
+       fdecl(arg1_type arg1_name, \
+             arg2_type arg2_name, \
+             arg3_type arg3_name, \
+             hook_type hook_name, ...)
+
 #define arglist_function(fdecl, \
                         hook_type, hook_name) \
         fdecl(hook_type hook_name, ...)
index 60e63d3eecf49868d0f494838892fe2a8c15bfc4..2d0766d6cacfcdc06769f2521221e776c6e38249 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: bsd-security.c,v 1.54 2006/03/09 16:51:41 martinea Exp $
+ * $Id: bsd-security.c,v 1.75 2006/07/19 17:41:14 martinea Exp $
  *
  * "BSD" security module
  */
@@ -36,6 +36,7 @@
 #include "event.h"
 #include "packet.h"
 #include "security.h"
+#include "security-util.h"
 #include "stream.h"
 #include "version.h"
 
 #define bsdprintf(p)   printf p
 #endif                                                         /* } */
 
-/*
- * This is the private handle data
- */
-struct bsd_handle {
-    /*
-     * This must be first.  Instances of bsd_handle will be cast to
-     * security_handle_t's.
-     */
-    security_handle_t sech;
-
-    /*
-     * protocol handle for this request.  Each request gets its own
-     * handle, so we differentiate packets for them with a "handle" header
-     * in each packet.
-     *
-     */
-    int event_id; /* unique event_id */
-    char *proto_handle;
-
-    /*
-     * sequence number.
-     */
-    int sequence;
-
-    /*
-     * The remote host we're transmitting to
-     */
-    char hostname[256];
-    struct sockaddr_in peer;
-
-    /*
-     * Function to call when recvpkt detects new incoming data for this
-     * handle
-     */
-    void (*fn) P((void *, pkt_t *, security_status_t));
-
-    /*
-     * Argument for previous function
-     */
-    void *arg;
-
-    /*
-     * read (EV_WAIT) handle for a recv
-     */
-    event_handle_t *ev_read;
-
-    /*
-     * Timeout handle for a recv
-     */
-    event_handle_t *ev_timeout;
-
-    struct bsd_handle *prev, *next;
-};
-
-struct bsd_handle *bh_first=NULL, *bh_last=NULL;
-
-/*
- * This is the internal security_stream data
- */
-struct bsd_stream {
-    /*
-     * This must be first, because instances of this will be cast
-     * to security_stream_t's outside of this module.
-     */
-    security_stream_t secstr;
-
-    /*
-     * This is the file descriptor which we will do io on
-     */
-    int fd;
-
-    /*
-     * This is the file descriptor which we will listen for incoming
-     * connections on (for streams which receive connections)
-     */
-    int socket;
-
-    /*
-     * This is the local port this stream is bound to
-     */
-    int port;
-
-    /*
-     * This is the read event handle for this data stream
-     */
-    event_handle_t *ev_read;
-
-    /*
-     * This is the function and argument that is called when this stream
-     * is readable.  It is passed a buffer of data read.
-     */
-    void (*fn) P((void *, void *, ssize_t));
-    void *arg;
-
-    /*
-     * This is the buffer that we read data into that will be passed
-     * to the read callback.
-     */
-    char databuf[NETWORK_BLOCK_BYTES];
-};
-
 /*
  * Interface functions
  */
-static void bsd_connect P((const char *,
-    char *(*)(char *, void *), 
-    void (*)(void *, security_handle_t *, security_status_t), void *));
-static void bsd_accept P((int, int, void (*)(security_handle_t *, pkt_t *)));
-static void bsd_close P((void *));
-static int bsd_sendpkt P((void *, pkt_t *));
-static void bsd_recvpkt P((void *,
-    void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void bsd_recvpkt_cancel P((void *));
-
-static void *bsd_stream_server P((void *));
-static int bsd_stream_accept P((void *));
-static void *bsd_stream_client P((void *, int));
-static void bsd_stream_close P((void *));
-static int bsd_stream_auth P((void *));
-static int bsd_stream_id P((void *));
-static int bsd_stream_write P((void *, const void *, size_t));
-static void bsd_stream_read P((void *, void (*)(void *, void *, ssize_t),
-    void *));
-static void bsd_stream_read_cancel P((void *));
+static void    bsd_connect(const char *, char *(*)(char *, void *), 
+                       void (*)(void *, security_handle_t *, security_status_t),
+                       void *, void *);
+static void    bsd_accept(const struct security_driver *, int, int,
+                       void (*)(security_handle_t *, pkt_t *));
+static void    bsd_close(void *);
+static void *  bsd_stream_server(void *);
+static int     bsd_stream_accept(void *);
+static void *  bsd_stream_client(void *, int);
+static void    bsd_stream_close(void *);
+static int     bsd_stream_auth(void *);
+static int     bsd_stream_id(void *);
+static void    bsd_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
+static ssize_t bsd_stream_read_sync(void *, void **);
+static void    bsd_stream_read_cancel(void *);
 
 /*
  * This is our interface to the outside world
@@ -198,142 +93,54 @@ const security_driver_t bsd_security_driver = {
     bsd_connect,
     bsd_accept,
     bsd_close,
-    bsd_sendpkt,
-    bsd_recvpkt,
-    bsd_recvpkt_cancel,
+    udpbsd_sendpkt,
+    udp_recvpkt,
+    udp_recvpkt_cancel,
     bsd_stream_server,
     bsd_stream_accept,
     bsd_stream_client,
     bsd_stream_close,
     bsd_stream_auth,
     bsd_stream_id,
-    bsd_stream_write,
+    tcp_stream_write,
     bsd_stream_read,
+    bsd_stream_read_sync,
     bsd_stream_read_cancel,
+    sec_close_connection_none,
 };
 
 /*
  * This is data local to the datagram socket.  We have one datagram
  * per process, so it is global.
  */
-static struct {
-    dgram_t dgram;             /* datagram to read/write from */
-    struct sockaddr_in peer;   /* who sent it to us */
-    pkt_t pkt;                 /* parsed form of dgram */
-    char *handle;              /* handle from recvd packet */
-    int sequence;              /* seq no of packet */
-    event_handle_t *ev_read;   /* read event handle from dgram */
-    int refcnt;                        /* number of handles blocked for reading */
-} netfd;
+static udp_handle_t netfd;
+static int not_init = 1;
 
 /* generate new handles from here */
 static int newhandle = 0;
-static int newevent = 0;
-
-/*
- * We register one event handler for our network fd which takes
- * care of all of our async requests.  When all async requests
- * have either been satisfied or cancelled, we unregister our
- * network event handler.
- */
-#define        netfd_addref()  do      {                                       \
-    if (netfd.refcnt++ == 0) {                                         \
-       assert(netfd.ev_read == NULL);                                  \
-       netfd.ev_read = event_register(netfd.dgram.socket, EV_READFD,   \
-           netfd_read_callback, NULL);                                 \
-    }                                                                  \
-    assert(netfd.refcnt > 0);                                          \
-} while (0)
-
-/*
- * If this is the last request to be removed, then remove the
- * reader event from the netfd.
- */
-#define        netfd_delref()  do      {                                       \
-    assert(netfd.refcnt > 0);                                          \
-    if (--netfd.refcnt == 0) {                                         \
-       assert(netfd.ev_read != NULL);                                  \
-       event_release(netfd.ev_read);                                   \
-       netfd.ev_read = NULL;                                           \
-    }                                                                  \
-} while (0)
-
-/*
- * This is the function and argument that is called when new requests
- * arrive on the netfd.
- */
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
 
 /*
  * These are the internal helper functions
  */
-static char *check_user P((struct bsd_handle *, const char *));
-static int inithandle P((struct bsd_handle *, struct hostent *,
-                        int, char *, int));
-static const char *pkthdr2str P((const struct bsd_handle *, const pkt_t *));
-static int str2pkthdr P((void));
-static void netfd_read_callback P((void *));
-static void recvpkt_callback P((void *));
-static void recvpkt_timeout P((void *));
-static int recv_security_ok P((struct bsd_handle *));
-static void stream_read_callback P((void *));
-
-
-#if defined(SHOW_SECURITY_DETAIL)                              /* { */
-/*
- * Display stat() information about a file.
- */
-void show_stat_info(a, b)
-    char *a, *b;
-{
-    char *name = vstralloc(a, b, NULL);
-    struct stat sbuf;
-    struct passwd *pwptr;
-    char *owner;
-    struct group *grptr;
-    char *group;
-
-    if (stat(name, &sbuf) != 0) {
-       bsdprintf(("%s: cannot stat %s: %s\n",
-                  debug_prefix_time(NULL), name, strerror(errno)));
-       amfree(name);
-       return;
-    }
-    if ((pwptr = getpwuid(sbuf.st_uid)) == NULL) {
-       owner = alloc(NUM_STR_SIZE + 1);
-       snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_uid);
-    } else {
-       owner = stralloc(pwptr->pw_name);
-    }
-    if ((grptr = getgrgid(sbuf.st_gid)) == NULL) {
-       group = alloc(NUM_STR_SIZE + 1);
-       snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_gid);
-    } else {
-       group = stralloc(grptr->gr_name);
-    }
-    bsdprintf(("%s: processing file: %s\n", debug_prefix(NULL), name));
-    bsdprintf(("%s:                  owner=%s group=%s mode=%03o\n",
-              debug_prefix(NULL), owner, group, (int) (sbuf.st_mode & 0777)));
-    amfree(name);
-    amfree(owner);
-    amfree(group);
-}
-#endif                                                         /* } */
+static void    stream_read_callback(void *);
+static void    stream_read_sync_callback(void *);
 
 /*
  * Setup and return a handle outgoing to a client
  */
+
 static void
-bsd_connect(hostname, conf_fn, fn, arg)
-    const char *hostname;
-    char *(*conf_fn) P((char *, void *));
-    void (*fn) P((void *, security_handle_t *, security_status_t));
-    void *arg;
-{
-    struct bsd_handle *bh;
+bsd_connect(
+    const char *       hostname,
+    char *             (*conf_fn)(char *, void *),
+    void               (*fn)(void *, security_handle_t *, security_status_t),
+    void *             arg,
+    void *             datap)
+{
+    struct sec_handle *bh;
     struct servent *se;
     struct hostent *he;
-    int port;
+    in_port_t port = 0;
     struct timeval sequence_time;
     amanda_timezone dontcare;
     int sequence;
@@ -341,31 +148,40 @@ bsd_connect(hostname, conf_fn, fn, arg)
 
     assert(hostname != NULL);
 
-    bh = alloc(sizeof(*bh));
+    (void)conf_fn;     /* Quiet unused parameter warning */
+    (void)datap;        /* Quiet unused parameter warning */
+
+    bh = alloc(SIZEOF(*bh));
     bh->proto_handle=NULL;
+    bh->udp = &netfd;
     security_handleinit(&bh->sech, &bsd_security_driver);
 
     /*
      * Only init the socket once
      */
-    if (netfd.dgram.socket == 0) {
+    if (not_init == 1) {
        uid_t euid;
        dgram_zero(&netfd.dgram);
-       
+
        euid = geteuid();
-       seteuid(0);
+       seteuid((uid_t)0);
        dgram_bind(&netfd.dgram, &port);
        seteuid(euid);
+       netfd.handle = NULL;
+       netfd.pkt.body = NULL;
+       netfd.recv_security_ok = &bsd_recv_security_ok;
+       netfd.prefix_packet = &bsd_prefix_packet;
        /*
         * We must have a reserved port.  Bomb if we didn't get one.
         */
        if (port >= IPPORT_RESERVED) {
            security_seterror(&bh->sech,
-               "unable to bind to a reserved port (got port %d)",
-               port);
+               "unable to bind to a reserved port (got port %u)",
+               (unsigned int)port);
            (*fn)(arg, &bh->sech, S_ERROR);
            return;
        }
+       not_init = 0;
     }
 
     if ((he = gethostbyname(hostname)) == NULL) {
@@ -374,32 +190,42 @@ bsd_connect(hostname, conf_fn, fn, arg)
        (*fn)(arg, &bh->sech, S_ERROR);
        return;
     }
+    bsdprintf(("Resolved hostname=%s\n", hostname));
     if ((se = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL)
-       port = htons(AMANDA_SERVICE_DEFAULT);
+       port = (in_port_t)htons(AMANDA_SERVICE_DEFAULT);
     else
-       port = se->s_port;
+       port = (in_port_t)se->s_port;
     amanda_gettimeofday(&sequence_time, &dontcare);
     sequence = (int)sequence_time.tv_sec ^ (int)sequence_time.tv_usec;
-    handle=malloc(15);
-    snprintf(handle,14,"000-%08x", newhandle++);
-    if (inithandle(bh, he, port, handle, sequence) < 0)
+    handle=alloc(15);
+    snprintf(handle, 14, "000-%08x",  (unsigned)newhandle++);
+    if (udp_inithandle(&netfd, bh, he, port, handle, sequence) < 0) {
        (*fn)(arg, &bh->sech, S_ERROR);
+       amfree(bh->hostname);
+       amfree(bh);
+    }
     else
        (*fn)(arg, &bh->sech, S_OK);
+    amfree(handle);
 }
 
 /*
  * Setup to accept new incoming connections
  */
 static void
-bsd_accept(in, out, fn)
-    int in, out;
-    void (*fn) P((security_handle_t *, pkt_t *));
+bsd_accept(
+    const struct security_driver *     driver,
+    int                in,
+    int                out,
+    void       (*fn)(security_handle_t *, pkt_t *))
 {
 
     assert(in >= 0 && out >= 0);
     assert(fn != NULL);
 
+    (void)out; /* Quiet unused parameter warning */
+    (void)driver; /* Quiet unused parameter warning */
+
     /*
      * We assume in and out point to the same socket, and just use
      * in.
@@ -411,983 +237,67 @@ bsd_accept(in, out, fn)
      * the recvpkt callback will call this function when it discovers
      * new incoming connections
      */
-    accept_fn = fn;
-
-    netfd_addref();
-}
-
-/*
- * Given a hostname and a port, setup a bsd_handle
- */
-static int
-inithandle(bh, he, port, handle, sequence)
-    struct bsd_handle *bh;
-    struct hostent *he;
-    int port;
-    char *handle;
-    int sequence;
-{
-    int i;
-
-    assert(he != NULL);
-    assert(port > 0);
-
-    /*
-     * Save the hostname and port info
-     */
-    strncpy(bh->hostname, he->h_name, sizeof(bh->hostname) - 1);
-    bh->hostname[sizeof(bh->hostname) - 1] = '\0';
-    bh->peer.sin_addr = *(struct in_addr *)he->h_addr;
-    bh->peer.sin_port = port;
-    bh->peer.sin_family = AF_INET;
-
-    bh->prev = bh_last;
-    if(bh_last) {bh->prev->next = bh;}
-    if(!bh_first) {bh_first = bh;}
-    bh->next = NULL;
-    bh_last = bh;
-
-    /*
-     * Do a forward lookup of the hostname.  This is unnecessary if we
-     * are initiating the connection, but is very serious if we are
-     * receiving.  We want to make sure the hostname
-     * resolves back to the remote ip for security reasons.
-     */
-    if ((he = gethostbyname(bh->hostname)) == NULL) {
-       security_seterror(&bh->sech,
-           "%s: could not resolve hostname", bh->hostname);
-       return (-1);
-    }
-    /*
-     * Make sure the hostname matches.  This should always work.
-     */
-    if (strncasecmp(bh->hostname, he->h_name, strlen(bh->hostname)) != 0) {
-       security_seterror(&bh->sech,
-           "%s: did not resolve to %s", bh->hostname, bh->hostname);
-       return (-1);
-    }
-
-    /*
-     * Now look for a matching ip address.
-     */
-    for (i = 0; he->h_addr_list[i] != NULL; i++) {
-       if (memcmp(&bh->peer.sin_addr, he->h_addr_list[i],
-           sizeof(struct in_addr)) == 0) {
-           break;
-       }
-    }
-
-    /*
-     * If we didn't find it, try the aliases.  This is a workaround for
-     * Solaris if DNS goes over NIS.
-     */
-    if (he->h_addr_list[i] == NULL) {
-       const char *ipstr = inet_ntoa(bh->peer.sin_addr);
-       for (i = 0; he->h_aliases[i] != NULL; i++) {
-           if (strcmp(he->h_aliases[i], ipstr) == 0)
-               break;
-       }
-       /*
-        * No aliases either.  Failure.  Someone is fooling with us or
-        * DNS is messed up.
-        */
-       if (he->h_aliases[i] == NULL) {
-           security_seterror(&bh->sech,
-               "DNS check failed: no matching ip address for %s",
-               bh->hostname);
-           return (-1);
-       }
-    }
-
-    bh->sequence = sequence;
-    bh->event_id = newevent++;
-    bh->proto_handle = handle;
-    bh->fn = NULL;
-    bh->arg = NULL;
-    bh->ev_read = NULL;
-    bh->ev_timeout = NULL;
-
-    bsdprintf(("%s: adding handle '%s'\n",
-              debug_prefix_time(NULL), bh->proto_handle));
+    netfd.accept_fn = fn;
+    netfd.recv_security_ok = &bsd_recv_security_ok;
+    netfd.prefix_packet = &bsd_prefix_packet;
+    netfd.driver = &bsd_security_driver;
 
-    return(0);
+    udp_addref(&netfd, &udp_netfd_read_callback);
 }
 
 /*
  * Frees a handle allocated by the above
  */
 static void
-bsd_close(cookie)
-    void *cookie;
+bsd_close(
+    void *     cookie)
 {
-    struct bsd_handle *bh = cookie;
+    struct sec_handle *bh = cookie;
 
     if(bh->proto_handle == NULL) {
        return;
     }
 
-    bsdprintf(("%s: close handle '%s'\n",
+    bsdprintf(("%s: bsd: close handle '%s'\n",
               debug_prefix_time(NULL), bh->proto_handle));
 
-    bsd_recvpkt_cancel(bh);
+    udp_recvpkt_cancel(bh);
     if(bh->next) {
        bh->next->prev = bh->prev;
     }
     else {
-       bh_last = bh->prev;
+       netfd.bh_last = bh->prev;
     }
     if(bh->prev) {
        bh->prev->next = bh->next;
     }
     else {
-       bh_first = bh->next;
+       netfd.bh_first = bh->next;
     }
 
+    amfree(bh->proto_handle);
+    amfree(bh->hostname);
     amfree(bh);
 }
 
-/*
- * Transmit a packet.  Add security information first.
- */
-static int
-bsd_sendpkt(cookie, pkt)
-    void *cookie;
-    pkt_t *pkt;
-{
-    struct bsd_handle *bh = cookie;
-    struct passwd *pwd;
-
-    assert(bh != NULL);
-    assert(pkt != NULL);
-
-    /*
-     * Initialize this datagram, and add the header
-     */
-    dgram_zero(&netfd.dgram);
-    dgram_cat(&netfd.dgram, pkthdr2str(bh, pkt));
-
-    /*
-     * Add the security info.  This depends on which kind of packet we're
-     * sending.
-     */
-    switch (pkt->type) {
-    case P_REQ:
-       /*
-        * Requests get sent with our username in the body
-        */
-       if ((pwd = getpwuid(geteuid())) == NULL) {
-           security_seterror(&bh->sech,
-               "can't get login name for my uid %ld", (long)getuid());
-           return (-1);
-       }
-       dgram_cat(&netfd.dgram, "SECURITY USER %s\n", pwd->pw_name);
-       break;
-
-    default:
-       break;
-    }
-
-    /*
-     * Add the body, and send it
-     */
-    dgram_cat(&netfd.dgram, pkt->body);
-    if (dgram_send_addr(bh->peer, &netfd.dgram) != 0) {
-       security_seterror(&bh->sech,
-           "send %s to %s failed: %s", pkt_type2str(pkt->type),
-           bh->hostname, strerror(errno));
-       return (-1);
-    }
-    return (0);
-}
-
-/*
- * Set up to receive a packet asynchronously, and call back when it has
- * been read.
- */
-static void
-bsd_recvpkt(cookie, fn, arg, timeout)
-    void *cookie, *arg;
-    void (*fn) P((void *, pkt_t *, security_status_t));
-    int timeout;
-{
-    struct bsd_handle *bh = cookie;
-
-    assert(bh != NULL);
-    assert(fn != NULL);
-
-
-    /*
-     * Subsequent recvpkt calls override previous ones
-     */
-    if (bh->ev_read == NULL) {
-       netfd_addref();
-       bh->ev_read = event_register(bh->event_id, EV_WAIT,
-           recvpkt_callback, bh);
-    }
-    if (bh->ev_timeout != NULL)
-       event_release(bh->ev_timeout);
-    if (timeout < 0)
-       bh->ev_timeout = NULL;
-    else
-       bh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, bh);
-    bh->fn = fn;
-    bh->arg = arg;
-}
-
-/*
- * Remove a async receive request on this handle from the queue.
- * If it is the last one to be removed, then remove the event
- * handler for our network fd
- */
-static void
-bsd_recvpkt_cancel(cookie)
-    void *cookie;
-{
-    struct bsd_handle *bh = cookie;
-
-    assert(bh != NULL);
-
-    if (bh->ev_read != NULL) {
-       netfd_delref();
-       event_release(bh->ev_read);
-       bh->ev_read = NULL;
-    }
-
-    if (bh->ev_timeout != NULL) {
-       event_release(bh->ev_timeout);
-       bh->ev_timeout = NULL;
-    }
-}
-
-/*
- * Callback for received packets.  This is the function bsd_recvpkt
- * registers with the event handler.  It is called when the event handler
- * realizes that data is waiting to be read on the network socket.
- */
-static void
-netfd_read_callback(cookie)
-    void *cookie;
-{
-    struct bsd_handle *bh;
-    struct hostent *he;
-    int a;
-
-    assert(cookie == NULL);
-
-#ifndef TEST                                                   /* { */
-    /*
-     * Receive the packet.
-     */
-    dgram_zero(&netfd.dgram);
-    if (dgram_recv(&netfd.dgram, 0, &netfd.peer) < 0)
-       return;
-#endif /* !TEST */                                             /* } */
-
-    /*
-     * Parse the packet.
-     */
-    if (str2pkthdr() < 0)
-       return;
-
-    /*
-     * If there are events waiting on this handle, we're done
-     */
-    bh = bh_first;
-    while(bh != NULL && (strcmp(bh->proto_handle, netfd.handle) != 0 ||
-                        bh->sequence != netfd.sequence ||
-                        bh->peer.sin_addr.s_addr != netfd.peer.sin_addr.s_addr ||
-                        bh->peer.sin_port != netfd.peer.sin_port)) {
-       bh = bh->next;
-    }
-    if (bh && event_wakeup(bh->event_id) > 0)
-       return;
-
-    /*
-     * If we didn't find a handle, then check for a new incoming packet.
-     * If no accept handler was setup, then just return.
-     */
-    if (accept_fn == NULL)
-       return;
-
-    he = gethostbyaddr((void *)&netfd.peer.sin_addr,
-       (int)sizeof(netfd.peer.sin_addr), AF_INET);
-    if (he == NULL)
-       return;
-    bh = alloc(sizeof(*bh));
-    bh->proto_handle=NULL;
-    security_handleinit(&bh->sech, &bsd_security_driver);
-    a = inithandle(bh,
-                  he,
-                  netfd.peer.sin_port,
-                  netfd.handle,
-                  netfd.sequence);
-    if (a < 0) {
-       if(bh->next) {
-           bh->next->prev = bh->prev;
-       }
-       else {
-           bh_last = bh->prev;
-       }
-       if(bh->prev) {
-           bh->prev->next = bh->next;
-       }
-       else {
-           bh_first = bh->prev;
-       }
-
-       bsdprintf(("%s: closeX handle '%s'\n",
-                 debug_prefix_time(NULL), bh->proto_handle));
-
-       amfree(bh);
-       return;
-    }
-    /*
-     * Check the security of the packet.  If it is bad, then pass NULL
-     * to the accept function instead of a packet.
-     */
-    if (recv_security_ok(bh) < 0)
-       (*accept_fn)(&bh->sech, NULL);
-    else
-       (*accept_fn)(&bh->sech, &netfd.pkt);
-}
-
-/*
- * This is called when a handle is woken up because data read off of the
- * net is for it.
- */
-static void
-recvpkt_callback(cookie)
-    void *cookie;
-{
-    struct bsd_handle *bh = cookie;
-    void (*fn) P((void *, pkt_t *, security_status_t));
-    void *arg;
-
-    assert(bh != NULL);
-    bsdprintf(("%s: receive handle '%s' netfd '%s'\n",
-              debug_prefix_time(NULL), bh->proto_handle,netfd.handle));
-
-    if(strcmp(bh->proto_handle,netfd.handle) != 0) assert(1);
-
-    /* if it didn't come from the same host/port, forget it */
-    if (memcmp(&bh->peer.sin_addr, &netfd.peer.sin_addr,
-       sizeof(netfd.peer.sin_addr)) != 0 ||
-       bh->peer.sin_port != netfd.peer.sin_port) {
-       netfd.handle = NULL;
-       return;
-    }
-
-    /*
-     * We need to cancel the recvpkt request before calling the callback
-     * because the callback may reschedule us.
-     */
-    fn = bh->fn;
-    arg = bh->arg;
-    bsd_recvpkt_cancel(bh);
-
-    /*
-     * Check the security of the packet.  If it is bad, then pass NULL
-     * to the packet handling function instead of a packet.
-     */
-    if (recv_security_ok(bh) < 0)
-       (*fn)(arg, NULL, S_ERROR);
-    else
-       (*fn)(arg, &netfd.pkt, S_OK);
-}
-
-/*
- * This is called when a handle times out before receiving a packet.
- */
-static void
-recvpkt_timeout(cookie)
-    void *cookie;
-{
-    struct bsd_handle *bh = cookie;
-    void (*fn) P((void *, pkt_t *, security_status_t));
-    void *arg;
-
-    assert(bh != NULL);
-
-    assert(bh->ev_timeout != NULL);
-    fn = bh->fn;
-    arg = bh->arg;
-    bsd_recvpkt_cancel(bh);
-    (*fn)(arg, NULL, S_TIMEOUT);
-
-}
-
-/*
- * Check the security of a received packet.  Returns negative on security
- * violation, or returns 0 if ok.  Removes the security info from the pkt_t.
- */
-static int
-recv_security_ok(bh)
-    struct bsd_handle *bh;
-{
-    char *tok, *security, *body, *result;
-    pkt_t *pkt = &netfd.pkt;
-
-    /*
-     * Set this preempively before we mangle the body.  
-     */
-    security_seterror(&bh->sech,
-       "bad SECURITY line: '%s'", pkt->body);
-
-    /*
-     * Now, find the SECURITY line in the body, and parse it out
-     * into an argv.
-     */
-    if (strncmp(pkt->body, "SECURITY", sizeof("SECURITY") - 1) == 0) {
-       tok = strtok(pkt->body, " ");
-       assert(strcmp(tok, "SECURITY") == 0);
-       /* security info goes until the newline */
-       security = strtok(NULL, "\n");
-       body = strtok(NULL, "");
-       /*
-        * If the body is f-ked, then try to recover
-        */
-       if (body == NULL) {
-           if (security != NULL)
-               body = security + strlen(security) + 2;
-           else
-               body = pkt->body;
-       }
-    } else {
-       security = NULL;
-       body = pkt->body;
-    }
-
-    /*
-     * We need to do different things depending on which type of packet
-     * this is.
-     */
-    switch (pkt->type) {
-    case P_REQ:
-       /*
-        * Request packets must come from a reserved port
-        */
-       if (ntohs(bh->peer.sin_port) >= IPPORT_RESERVED) {
-           security_seterror(&bh->sech,
-               "host %s: port %d not secure", bh->hostname,
-               ntohs(bh->peer.sin_port));
-           return (-1);
-       }
-
-       /*
-        * Request packets contain a remote username.  We need to check
-        * that we allow it in.
-        *
-        * They will look like:
-        *      SECURITY USER [username]
-        */
-
-       /* there must be some security info */
-       if (security == NULL) {
-           security_seterror(&bh->sech,
-               "no bsd SECURITY for P_REQ");
-           return (-1);
-       }
-
-       /* second word must be USER */
-       if ((tok = strtok(security, " ")) == NULL)
-           return (-1);        /* default errmsg */
-       if (strcmp(tok, "USER") != 0) {
-           security_seterror(&bh->sech,
-               "REQ SECURITY line parse error, expecting USER, got %s", tok);
-           return (-1);
-       }
-
-       /* the third word is the username */
-       if ((tok = strtok(NULL, "")) == NULL)
-           return (-1);        /* default errmsg */
-       if ((result = check_user(bh, tok)) != NULL) {
-           security_seterror(&bh->sech, "%s", result);
-           amfree(result);
-           return (-1);
-       }
-
-       /* we're good to go */
-       break;
-    default:
-       break;
-    }
-
-    /*
-     * If there is security info at the front of the packet, we need to
-     * shift the rest of the data up and nuke it.
-     */
-    if (body != pkt->body)
-       memmove(pkt->body, body, strlen(body) + 1);
-    return (0);
-}
-
-static char *
-check_user(bh, remoteuser)
-    struct bsd_handle *bh;
-    const char *remoteuser;
-{
-    struct passwd *pwd;
-    char *r;
-    char *result = NULL;
-    char *localuser = NULL;
-
-    /* lookup our local user name */
-    if ((pwd = getpwnam(CLIENT_LOGIN)) == NULL) {
-       return vstralloc("getpwnam(", CLIENT_LOGIN, ") fails", NULL);
-    }
-
-    /*
-     * Make a copy of the user name in case getpw* is called by
-     * any of the lower level routines.
-     */
-    localuser = stralloc(pwd->pw_name);
-
-#ifndef USE_AMANDAHOSTS
-    r = check_user_ruserok(bh->hostname, pwd, remoteuser);
-#else
-    r = check_user_amandahosts(bh->hostname, pwd, remoteuser);
-#endif
-    if (r != NULL) {
-       result = vstralloc("access as ", localuser, " not allowed",
-                          " from ", remoteuser, "@", bh->hostname,
-                          ": ", r,
-                          NULL);
-       amfree(r);
-    }
-    amfree(localuser);
-    return result;
-}
-
-/*
- * See if a remote user is allowed in.  This version uses ruserok()
- * and friends.
- *
- * Returns 0 on success, or negative on error.
- */
-char *
-check_user_ruserok(host, pwd, remoteuser)
-    const char *host;
-    struct passwd *pwd;
-    const char *remoteuser;
-{
-    int saved_stderr;
-    int fd[2];
-    FILE *fError;
-    amwait_t exitcode;
-    pid_t ruserok_pid;
-    pid_t pid;
-    char *es;
-    char *result;
-    int ok;
-    char number[NUM_STR_SIZE];
-    uid_t myuid = getuid();
-
-    /*
-     * note that some versions of ruserok (eg SunOS 3.2) look in
-     * "./.rhosts" rather than "~CLIENT_LOGIN/.rhosts", so we have to
-     * chdir ourselves.  Sigh.
-     *
-     * And, believe it or not, some ruserok()'s try an initgroup just
-     * for the hell of it.  Since we probably aren't root at this point
-     * it'll fail, and initgroup "helpfully" will blatt "Setgroups: Not owner"
-     * into our stderr output even though the initgroup failure is not a
-     * problem and is expected.  Thanks a lot.  Not.
-     */
-    if (pipe(fd) != 0) {
-       return stralloc2("pipe() fails: ", strerror(errno));
-    }
-    if ((ruserok_pid = fork()) < 0) {
-       return stralloc2("fork() fails: ", strerror(errno));
-    } else if (ruserok_pid == 0) {
-       int ec;
-
-       close(fd[0]);
-       fError = fdopen(fd[1], "w");
-       /* pamper braindead ruserok's */
-       if (chdir(pwd->pw_dir) != 0) {
-           fprintf(fError, "chdir(%s) failed: %s",
-                   pwd->pw_dir, strerror(errno));
-           fclose(fError);
-           exit(1);
-       }
-
-#if defined(SHOW_SECURITY_DETAIL)                              /* { */
-       {
-       char *dir = stralloc(pwd->pw_dir);
-
-       bsdprintf(("%s: calling ruserok(%s, %d, %s, %s)\n",
-                  debug_prefix_time(NULL),
-                  host, myuid == 0, remoteuser, pwd->pw_name));
-       if (myuid == 0) {
-           bsdprintf(("%s: because you are running as root, ",
-                      debug_prefix(NULL)));
-           bsdprintf(("/etc/hosts.equiv will not be used\n"));
-       } else {
-           show_stat_info("/etc/hosts.equiv", NULL);
-       }
-       show_stat_info(dir, "/.rhosts");
-       amfree(dir);
-       }
-#endif                                                         /* } */
-
-       saved_stderr = dup(2);
-       close(2);
-       if (open("/dev/null", O_RDWR) == -1) {
-            dbprintf(("Could not open /dev/null: %s\n",
-                     strerror(errno)));
-           ec = 1;
-       } else {
-           ok = ruserok(host, myuid == 0, remoteuser, CLIENT_LOGIN);
-           if (ok < 0) {
-               ec = 1;
-           } else {
-               ec = 0;
-           }
-       }
-       (void)dup2(saved_stderr,2);
-       close(saved_stderr);
-       exit(ec);
-    }
-    close(fd[1]);
-    fError = fdopen(fd[0], "r");
-
-    result = NULL;
-    while ((es = agets(fError)) != NULL) {
-       if (result == NULL) {
-           result = stralloc("");
-       } else {
-           strappend(result, ": ");
-       }
-       strappend(result, es);
-    }
-    close(fd[0]);
-
-    while (1) {
-       if ((pid = wait(&exitcode)) == (pid_t) -1) {
-           if (errno == EINTR) {
-               continue;
-           }
-           amfree(result);
-           return stralloc2("ruserok wait failed: %s", strerror(errno));
-       }
-       if (pid == ruserok_pid) {
-           break;
-       }
-    }
-    if (WIFSIGNALED(exitcode)) {
-       amfree(result);
-       snprintf(number, sizeof(number), "%d", WTERMSIG(exitcode));
-       return stralloc2("ruserok child got signal ", number);
-    }
-    if (WEXITSTATUS(exitcode) == 0) {
-       amfree(result);
-    } else if (result == NULL) {
-       result = stralloc("ruserok failed");
-    }
-
-    return result;
-}
-
-/*
- * Check to see if a user is allowed in.  This version uses .amandahosts
- * Returns -1 on failure, or 0 on success.
- */
-char *
-check_user_amandahosts(host, pwd, remoteuser)
-    const char *host;
-    struct passwd *pwd;
-    const char *remoteuser;
-{
-    char *line = NULL;
-    char *filehost;
-    const char *fileuser;
-    char *ptmp = NULL;
-    char *result = NULL;
-    FILE *fp = NULL;
-    int found;
-    struct stat sbuf;
-    char n1[NUM_STR_SIZE];
-    char n2[NUM_STR_SIZE];
-    int hostmatch;
-    int usermatch;
-    uid_t localuid;
-    char *localuser = NULL;
-
-    /*
-     * Save copies of what we need from the passwd structure in case
-     * any other code calls getpw*.
-     */
-    localuid = pwd->pw_uid;
-    localuser = stralloc(pwd->pw_name);
-
-    ptmp = stralloc2(pwd->pw_dir, "/.amandahosts");
-#if defined(SHOW_SECURITY_DETAIL)                              /* { */
-    show_stat_info(ptmp, "");;
-#endif                                                         /* } */
-    if ((fp = fopen(ptmp, "r")) == NULL) {
-       result = vstralloc("cannot open ", ptmp, ": ", strerror(errno), NULL);
-       amfree(ptmp);
-       amfree(localuser);
-       return result;
-    }
-
-    /*
-     * Make sure the file is owned by the Amanda user and does not
-     * have any group/other access allowed.
-     */
-    if (fstat(fileno(fp), &sbuf) != 0) {
-       result = vstralloc("cannot fstat ", ptmp, ": ", strerror(errno), NULL);
-       goto common_exit;
-    }
-    if (sbuf.st_uid != localuid) {
-       snprintf(n1, sizeof(n1), "%ld", (long)sbuf.st_uid);
-       snprintf(n2, sizeof(n2), "%ld", (long)localuid);
-       result = vstralloc(ptmp, ": ",
-                          "owned by id ", n1,
-                          ", should be ", n2,
-                          NULL);
-       goto common_exit;
-    }
-    if ((sbuf.st_mode & 077) != 0) {
-       result = stralloc2(ptmp,
-         ": incorrect permissions; file must be accessible only by its owner");
-       goto common_exit;
-    }
-
-    /*
-     * Now, scan the file for the host/user.
-     */
-    found = 0;
-    while ((line = agets(fp)) != NULL) {
-#if defined(SHOW_SECURITY_DETAIL)                              /* { */
-       bsdprintf(("%s: processing line: <%s>\n", debug_prefix(NULL), line));
-#endif                                                         /* } */
-       /* get the host out of the file */
-       if ((filehost = strtok(line, " \t")) == NULL) {
-           amfree(line);
-           continue;
-       }
-
-       /* get the username.  If no user specified, then use the local user */
-       if ((fileuser = strtok(NULL, " \t")) == NULL) {
-           fileuser = localuser;
-       }
-
-       hostmatch = (strcasecmp(filehost, host) == 0);
-       usermatch = (strcasecmp(fileuser, remoteuser) == 0);
-#if defined(SHOW_SECURITY_DETAIL)                              /* { */
-       bsdprintf(("%s: comparing \"%s\" with\n", debug_prefix(NULL), filehost));
-       bsdprintf(("%s:           \"%s\" (%s)\n", host,
-                 debug_prefix(NULL), hostmatch ? "match" : "no match"));
-       bsdprintf(("%s:       and \"%s\" with\n", fileuser, debug_prefix(NULL)));
-       bsdprintf(("%s:           \"%s\" (%s)\n", remoteuser,
-                 debug_prefix(NULL), usermatch ? "match" : "no match"));
-#endif                                                         /* } */
-       amfree(line);
-       /* compare */
-       if (hostmatch && usermatch) {
-           /* success */
-           found = 1;
-           break;
-       }
-    }
-    if (! found) {
-       result = vstralloc(ptmp, ": ",
-                          "\"", host, " ", remoteuser, "\"",
-                          " entry not found",
-                          NULL);
-    }
-
-common_exit:
-
-    afclose(fp);
-    amfree(ptmp);
-    amfree(line);
-    amfree(localuser);
-
-    return result;
-}
-
-/* return 1 on success, 0 on failure */
-int
-check_security(addr, str, cksum, errstr)
-struct sockaddr_in *addr;
-char *str;
-unsigned long cksum;
-char **errstr;
-{
-    char *remotehost = NULL, *remoteuser = NULL;
-    char *bad_bsd = NULL;
-    struct hostent *hp;
-    struct passwd *pwptr;
-    int myuid, i, j;
-    char *s, *fp;
-    int ch;
-
-    *errstr = NULL;
-
-    /* what host is making the request? */
-
-    hp = gethostbyaddr((char *)&addr->sin_addr, sizeof(addr->sin_addr),
-                      AF_INET);
-    if(hp == NULL) {
-       /* XXX include remote address in message */
-       *errstr = vstralloc("[",
-                           "addr ", inet_ntoa(addr->sin_addr), ": ",
-                           "hostname lookup failed",
-                           "]", NULL);
-       return 0;
-    }
-    remotehost = stralloc(hp->h_name);
-
-    /* Now let's get the hostent for that hostname */
-    hp = gethostbyname( remotehost );
-    if(hp == NULL) {
-       /* XXX include remote hostname in message */
-       *errstr = vstralloc("[",
-                           "host ", remotehost, ": ",
-                           "hostname lookup failed",
-                           "]", NULL);
-       amfree(remotehost);
-       return 0;
-    }
-
-    /* Verify that the hostnames match -- they should theoretically */
-    if( strncasecmp( remotehost, hp->h_name, strlen(remotehost)+1 ) != 0 ) {
-       *errstr = vstralloc("[",
-                           "hostnames do not match: ",
-                           remotehost, " ", hp->h_name,
-                           "]", NULL);
-       amfree(remotehost);
-       return 0;
-    }
-
-    /* Now let's verify that the ip which gave us this hostname
-     * is really an ip for this hostname; or is someone trying to
-     * break in? (THIS IS THE CRUCIAL STEP)
-     */
-    for (i = 0; hp->h_addr_list[i]; i++) {
-       if (memcmp(hp->h_addr_list[i],
-                  (char *) &addr->sin_addr, sizeof(addr->sin_addr)) == 0)
-           break;                     /* name is good, keep it */
-    }
-
-    /* If we did not find it, your DNS is messed up or someone is trying
-     * to pull a fast one on you. :(
-     */
-
-   /*   Check even the aliases list. Work around for Solaris if dns goes over NIS */
-
-    if( !hp->h_addr_list[i] ) {
-        for (j = 0; hp->h_aliases[j] !=0 ; j++) {
-            if ( strcmp(hp->h_aliases[j],inet_ntoa(addr->sin_addr)) == 0)
-                break;                          /* name is good, keep it */
-        }
-       if( !hp->h_aliases[j] ) {
-           *errstr = vstralloc("[",
-                               "ip address ", inet_ntoa(addr->sin_addr),
-                               " is not in the ip list for ", remotehost,
-                               "]",
-                               NULL);
-           amfree(remotehost);
-           return 0;
-       }
-    }
-
-    /* next, make sure the remote port is a "reserved" one */
-
-    if(ntohs(addr->sin_port) >= IPPORT_RESERVED) {
-       char number[NUM_STR_SIZE];
-
-       snprintf(number, sizeof(number), "%d", ntohs(addr->sin_port));
-       *errstr = vstralloc("[",
-                           "host ", remotehost, ": ",
-                           "port ", number, " not secure",
-                           "]", NULL);
-       amfree(remotehost);
-       return 0;
-    }
-
-    /* extract the remote user name from the message */
-
-    s = str;
-    ch = *s++;
-
-    bad_bsd = vstralloc("[",
-                       "host ", remotehost, ": ",
-                       "bad bsd security line",
-                       "]", NULL);
-
-#define sc "USER "
-    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
-       *errstr = bad_bsd;
-       bad_bsd = NULL;
-       amfree(remotehost);
-       return 0;
-    }
-    s += sizeof(sc)-1;
-    ch = s[-1];
-#undef sc
-
-    skip_whitespace(s, ch);
-    if(ch == '\0') {
-       *errstr = bad_bsd;
-       bad_bsd = NULL;
-       amfree(remotehost);
-       return 0;
-    }
-    fp = s - 1;
-    skip_non_whitespace(s, ch);
-    s[-1] = '\0';
-    remoteuser = stralloc(fp);
-    s[-1] = ch;
-    amfree(bad_bsd);
-
-    /* lookup our local user name */
-
-    myuid = getuid();
-    if((pwptr = getpwuid(myuid)) == NULL)
-        error("error [getpwuid(%d) fails]", myuid);
-
-    dbprintf(("bsd security: remote host %s user %s local user %s\n",
-             remotehost, remoteuser, pwptr->pw_name));
-
-#ifndef USE_AMANDAHOSTS
-    s = check_user_ruserok(remotehost, pwptr, remoteuser);
-#else
-    s = check_user_amandahosts(remotehost, pwptr, remoteuser);
-#endif
-
-    if (s != NULL) {
-       *errstr = vstralloc("[",
-                           "access as ", pwptr->pw_name, " not allowed",
-                           " from ", remoteuser, "@", remotehost,
-                           ": ", s, "]", NULL);
-    }
-    amfree(s);
-    amfree(remotehost);
-    amfree(remoteuser);
-    return *errstr == NULL;
-}
-
-
 /*
  * Create the server end of a stream.  For bsd, this means setup a tcp
  * socket for receiving a connection.
  */
 static void *
-bsd_stream_server(h)
-    void *h;
+bsd_stream_server(
+    void *     h)
 {
-    struct bsd_stream *bs = NULL;
 #ifndef TEST                                                   /* { */
-    struct bsd_handle *bh = h;
+    struct sec_stream *bs = NULL;
+    struct sec_handle *bh = h;
 
     assert(bh != NULL);
 
-    bs = alloc(sizeof(*bs));
+    bs = alloc(SIZEOF(*bs));
     security_streaminit(&bs->secstr, &bsd_security_driver);
-    bs->socket = stream_server(&bs->port, STREAM_BUFSIZE, STREAM_BUFSIZE);
+    bs->socket = stream_server(&bs->port, (size_t)STREAM_BUFSIZE, 
+                       (size_t)STREAM_BUFSIZE, 0);
     if (bs->socket < 0) {
        security_seterror(&bh->sech,
            "can't create server stream: %s", strerror(errno));
@@ -1396,8 +306,10 @@ bsd_stream_server(h)
     }
     bs->fd = -1;
     bs->ev_read = NULL;
-#endif /* !TEST */                                             /* } */
     return (bs);
+#else
+    return (NULL);
+#endif /* !TEST */                                             /* } */
 }
 
 /*
@@ -1405,17 +317,17 @@ bsd_stream_server(h)
  * block on accept()
  */
 static int
-bsd_stream_accept(s)
-    void *s;
+bsd_stream_accept(
+    void *     s)
 {
 #ifndef TEST                                                   /* { */
-    struct bsd_stream *bs = s;
+    struct sec_stream *bs = s;
 
     assert(bs != NULL);
     assert(bs->socket != -1);
     assert(bs->fd < 0);
 
-    bs->fd = stream_accept(bs->socket, 30, -1, -1);
+    bs->fd = stream_accept(bs->socket, 30, STREAM_BUFSIZE, STREAM_BUFSIZE);
     if (bs->fd < 0) {
        security_stream_seterror(&bs->secstr,
            "can't accept new stream connection: %s", strerror(errno));
@@ -1429,32 +341,26 @@ bsd_stream_accept(s)
  * Return a connected stream
  */
 static void *
-bsd_stream_client(h, id)
-    void *h;
-    int id;
+bsd_stream_client(
+    void *     h,
+    int                id)
 {
-    struct bsd_stream *bs = NULL;
+    struct sec_stream *bs = NULL;
 #ifndef TEST                                                   /* { */
-    struct bsd_handle *bh = h;
+    struct sec_handle *bh = h;
 #ifdef DUMPER_SOCKET_BUFFERING
-    int rcvbuf = sizeof(bs->databuf) * 2;
+    size_t rcvbuf = SIZEOF(bs->databuf) * 2;
 #endif
 
     assert(bh != NULL);
 
-    if (id < 0) {
-       security_seterror(&bh->sech,
-           "%d: invalid security stream id", id);
-       return (NULL);
-    }
-
-    bs = alloc(sizeof(*bs));
+    bs = alloc(SIZEOF(*bs));
     security_streaminit(&bs->secstr, &bsd_security_driver);
-    bs->fd = stream_client(bh->hostname, id, STREAM_BUFSIZE, STREAM_BUFSIZE,
-       &bs->port, 0);
+    bs->fd = stream_client(bh->hostname, (in_port_t)id,
+       STREAM_BUFSIZE, STREAM_BUFSIZE, &bs->port, 0);
     if (bs->fd < 0) {
        security_seterror(&bh->sech,
-           "can't connect stream to %s port %d: %s", bh->hostname,
+           "can't connect stream to %s port %hd: %s", bh->hostname,
            id, strerror(errno));
        amfree(bs);
        return (NULL);
@@ -1462,7 +368,7 @@ bsd_stream_client(h, id)
     bs->socket = -1;   /* we're a client */
     bs->ev_read = NULL;
 #ifdef DUMPER_SOCKET_BUFFERING
-    setsockopt(bs->fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, sizeof(rcvbuf));
+    setsockopt(bs->fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, SIZEOF(rcvbuf));
 #endif
 #endif /* !TEST */                                             /* } */
     return (bs);
@@ -1472,10 +378,10 @@ bsd_stream_client(h, id)
  * Close and unallocate resources for a stream
  */
 static void
-bsd_stream_close(s)
-    void *s;
+bsd_stream_close(
+    void *     s)
 {
-    struct bsd_stream *bs = s;
+    struct sec_stream *bs = s;
 
     assert(bs != NULL);
 
@@ -1491,9 +397,10 @@ bsd_stream_close(s)
  * Authenticate a stream.  bsd streams have no authentication
  */
 static int
-bsd_stream_auth(s)
-    void *s;
+bsd_stream_auth(
+    void *     s)
 {
+    (void)s;           /* Quiet unused parameter warning */
 
     return (0);        /* success */
 }
@@ -1502,37 +409,14 @@ bsd_stream_auth(s)
  * Returns the stream id for this stream.  This is just the local port.
  */
 static int
-bsd_stream_id(s)
-    void *s;
+bsd_stream_id(
+    void *     s)
 {
-    struct bsd_stream *bs = s;
+    struct sec_stream *bs = s;
 
     assert(bs != NULL);
 
-    return (bs->port);
-}
-
-/*
- * Write a chunk of data to a stream.  Blocks until completion.
- */
-static int
-bsd_stream_write(s, buf, size)
-    void *s;
-    const void *buf;
-    size_t size;
-{
-#ifndef TEST                                                   /* { */
-    struct bsd_stream *bs = s;
-
-    assert(bs != NULL);
-
-    if (fullwrite(bs->fd, buf, size) < 0) {
-       security_stream_seterror(&bs->secstr,
-           "write error on stream %d: %s", bs->port, strerror(errno));
-       return (-1);
-    }
-#endif /* !TEST */                                             /* } */
-    return (0);
+    return ((int)bs->port);
 }
 
 /*
@@ -1540,11 +424,12 @@ bsd_stream_write(s, buf, size)
  * and arg when completed.
  */
 static void
-bsd_stream_read(s, fn, arg)
-    void *s, *arg;
-    void (*fn) P((void *, void *, ssize_t));
+bsd_stream_read(
+    void *     s,
+    void       (*fn)(void *, void *, ssize_t),
+    void *     arg)
 {
-    struct bsd_stream *bs = s;
+    struct sec_stream *bs = s;
 
     /*
      * Only one read request can be active per stream.
@@ -1552,41 +437,52 @@ bsd_stream_read(s, fn, arg)
     if (bs->ev_read != NULL)
        event_release(bs->ev_read);
 
-    bs->ev_read = event_register(bs->fd, EV_READFD, stream_read_callback, bs);
+    bs->ev_read = event_register((event_id_t)bs->fd, EV_READFD, stream_read_callback, bs);
     bs->fn = fn;
     bs->arg = arg;
 }
 
 /*
- * Cancel a previous stream read request.  It's ok if we didn't
- * have a read scheduled.
+ * Read a chunk of data to a stream.  Blocks until completion.
  */
-static void
-bsd_stream_read_cancel(s)
-    void *s;
+static ssize_t
+bsd_stream_read_sync(
+    void *     s,
+    void **    buf)
 {
-    struct bsd_stream *bs = s;
+    struct sec_stream *bs = s;
 
     assert(bs != NULL);
 
-    if (bs->ev_read != NULL) {
-       event_release(bs->ev_read);
-       bs->ev_read = NULL;
+    /*
+     * Only one read request can be active per stream.
+     */
+    if(bs->ev_read != NULL) {
+        return -1;
     }
+    bs->ev_read = event_register((event_id_t)bs->fd, EV_READFD,
+                       stream_read_sync_callback, bs);
+    event_wait(bs->ev_read);
+    *buf = bs->databuf;
+    return (bs->len);
 }
 
+
 /*
- * Callback for bsd_stream_read
+ * Callback for bsd_stream_read_sync
  */
 static void
-stream_read_callback(arg)
-    void *arg;
+stream_read_sync_callback(
+    void *     s)
 {
-    struct bsd_stream *bs = arg;
+    struct sec_stream *bs = s;
     ssize_t n;
 
     assert(bs != NULL);
 
+    bsdprintf(("%s: bsd: stream_read_callback_sync: fd %d\n",
+                debug_prefix_time(NULL), bs->fd));
+
     /*
      * Remove the event first, in case they reschedule it in the callback.
      */
@@ -1595,101 +491,51 @@ stream_read_callback(arg)
        n = read(bs->fd, bs->databuf, sizeof(bs->databuf));
     } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
     if (n < 0)
-       security_stream_seterror(&bs->secstr, strerror(errno));
-    (*bs->fn)(bs->arg, bs->databuf, n);
+        security_stream_seterror(&bs->secstr, strerror(errno));
+    bs->len = n;
 }
 
 /*
- * Convert a packet header into a string
+ * Cancel a previous stream read request.  It's ok if we didn't
+ * have a read scheduled.
  */
-static const char *
-pkthdr2str(bh, pkt)
-    const struct bsd_handle *bh;
-    const pkt_t *pkt;
+static void
+bsd_stream_read_cancel(
+    void *     s)
 {
-    static char retbuf[256];
-
-    assert(bh != NULL);
-    assert(pkt != NULL);
+    struct sec_stream *bs = s;
 
-    snprintf(retbuf, sizeof(retbuf), "Amanda %d.%d %s HANDLE %s SEQ %d\n",
-       VERSION_MAJOR, VERSION_MINOR, pkt_type2str(pkt->type),
-       bh->proto_handle, bh->sequence);
-
-    bsdprintf(("%s: pkthdr2str handle '%s'\n",
-              debug_prefix_time(NULL), bh->proto_handle));
-
-    /* check for truncation.  If only we had asprintf()... */
-    assert(retbuf[strlen(retbuf) - 1] == '\n');
-
-    return (retbuf);
+    assert(bs != NULL);
+    if (bs->ev_read != NULL) {
+       event_release(bs->ev_read);
+       bs->ev_read = NULL;
+    }
 }
 
 /*
- * Parses out the header line in 'str' into the pkt and handle
- * Returns negative on parse error.
+ * Callback for bsd_stream_read
  */
-static int
-str2pkthdr()
+static void
+stream_read_callback(
+    void *     arg)
 {
-    char *str;
-    const char *tok;
-    pkt_t *pkt;
-
-    pkt = &netfd.pkt;
-
-    assert(netfd.dgram.cur != NULL);
-    str = stralloc(netfd.dgram.cur);
-
-    /* "Amanda %d.%d <ACK,NAK,...> HANDLE %s SEQ %d\n" */
-
-    /* Read in "Amanda" */
-    if ((tok = strtok(str, " ")) == NULL || strcmp(tok, "Amanda") != 0)
-       goto parse_error;
-
-    /* nothing is done with the major/minor numbers currently */
-    if ((tok = strtok(NULL, " ")) == NULL || strchr(tok, '.') == NULL)
-       goto parse_error;
-
-    /* Read in the packet type */
-    if ((tok = strtok(NULL, " ")) == NULL)
-       goto parse_error;
-    pkt_init(pkt, pkt_str2type(tok), "");
-    if (pkt->type == (pktype_t)-1)    
-       goto parse_error;
-
-    /* Read in "HANDLE" */
-    if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "HANDLE") != 0)
-       goto parse_error;
-
-    /* parse the handle */
-    if ((tok = strtok(NULL, " ")) == NULL)
-       goto parse_error;
-    netfd.handle = stralloc(tok);
-
-    /* Read in "SEQ" */
-    if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "SEQ") != 0)   
-       goto parse_error;
+    struct sec_stream *bs = arg;
+    ssize_t n;
 
-    /* parse the sequence number */   
-    if ((tok = strtok(NULL, "\n")) == NULL)
-       goto parse_error;
-    netfd.sequence = atoi(tok);
+    assert(bs != NULL);
 
-    /* Save the body, if any */       
-    if ((tok = strtok(NULL, "")) != NULL)
-       pkt_cat(pkt, "%s", tok);
+    /*
+     * Remove the event first, in case they reschedule it in the callback.
+     */
+    bsd_stream_read_cancel(bs);
+    do {
+       n = read(bs->fd, bs->databuf, SIZEOF(bs->databuf));
+    } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
 
-    amfree(str);
-    return (0);
+    if (n < 0)
+       security_stream_seterror(&bs->secstr, strerror(errno));
 
-parse_error:
-#if 0 /* XXX we have no way of passing this back up */
-    security_seterror(&bh->sech,
-       "parse error in packet header : '%s'", origstr);
-#endif
-    amfree(str);
-    return (-1);
+    (*bs->fn)(bs->arg, bs->databuf, n);
 }
 
 #endif /* BSD_SECURITY */                                      /* } */
@@ -1701,12 +547,19 @@ parse_error:
  * drag in util.o just for the test program.
  */
 int
-bind_portrange(s, addrp, first_port, last_port, proto)
-    int s;
-    struct sockaddr_in *addrp;
-    int first_port, last_port;
-    char *proto;
-{
+bind_portrange(
+    int                        s,
+    struct sockaddr_in *addrp,
+    in_port_t          first_port,
+    in_port_t          last_port,
+    char *             proto)
+{
+    (void)s;           /* Quiet unused parameter warning */
+    (void)addrp;       /* Quiet unused parameter warning */
+    (void)first_port;  /* Quiet unused parameter warning */
+    (void)last_port;   /* Quiet unused parameter warning */
+    (void)proto;       /* Quiet unused parameter warning */
+
     return 0;
 }
 
@@ -1714,8 +567,8 @@ bind_portrange(s, addrp, first_port, last_port, proto)
  * Construct a datestamp (YYYYMMDD) from a time_t.
  */
 char *
-construct_datestamp(t)
-    time_t *t;
+construct_datestamp(
+    time_t *   t)
 {
     struct tm *tm;
     char datestamp[3*NUM_STR_SIZE];
@@ -1727,7 +580,7 @@ construct_datestamp(t)
        when = *t;
     }
     tm = localtime(&when);
-    snprintf(datestamp, sizeof(datestamp),
+    snprintf(datestamp, SIZEOF(datestamp),
              "%04d%02d%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
     return stralloc(datestamp);
 }
@@ -1736,8 +589,8 @@ construct_datestamp(t)
  * Construct a timestamp (YYYYMMDDHHMMSS) from a time_t.
  */
 char *
-construct_timestamp(t)
-    time_t *t;
+construct_timestamp(
+    time_t *   t)
 {
     struct tm *tm;
     char timestamp[6*NUM_STR_SIZE];
@@ -1749,7 +602,7 @@ construct_timestamp(t)
        when = *t;
     }
     tm = localtime(&when);
-    snprintf(timestamp, sizeof(timestamp),
+    snprintf(timestamp, SIZEOF(timestamp),
             "%04d%02d%02d%02d%02d%02d",
             tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
             tm->tm_hour, tm->tm_min, tm->tm_sec);
@@ -1763,14 +616,17 @@ construct_timestamp(t)
 const security_driver_t krb4_security_driver = {};
 const security_driver_t krb5_security_driver = {};
 const security_driver_t rsh_security_driver = {};
+const security_driver_t ssh_security_driver = {};
+const security_driver_t bsdtcp_security_driver = {};
+const security_driver_t bsdudp_security_driver = {};
 
 /*
  * This function will be called to accept the connection and is used
  * to report success or failure.
  */
-static void fake_accept_function(handle, pkt)
-    security_handle_t *handle;
-    pkt_t *pkt;
+static void fake_accept_function(
+    security_handle_t *        handle,
+    pkt_t *            pkt)
 {
     if (pkt == NULL) {
        fputs(handle->error, stdout);
@@ -1781,12 +637,14 @@ static void fake_accept_function(handle, pkt)
 }
 
 int
-main (argc, argv)
+main (
+    int                argc,
+    char **    argv)
 {
     char *remoteuser;
     char *remotehost;
     struct hostent *hp;
-    struct bsd_handle *bh;
+    struct sec_handle *bh;
     void *save_cur;
     struct passwd *pwent;
 
@@ -1808,6 +666,7 @@ main (argc, argv)
     if (geteuid() == 0) {
        if(client_uid == (uid_t) -1) {
            error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+           /*NOTREACHED*/
        }
        initgroups(CLIENT_LOGIN, client_gid);
        setgid(client_gid);
@@ -1820,19 +679,28 @@ main (argc, argv)
        fputs("Remote user: ", stdout);
        fflush(stdout);
     }
-    if ((remoteuser = agets(stdin)) == NULL) {
-       return 0;
-    }
+    do {
+       amfree(remoteuser);
+       remoteuser = agets(stdin);
+       if (remoteuser == NULL)
+           return 0;
+    } while (remoteuser[0] == '\0');
 
     if (isatty(0)) {
        fputs("Remote host: ", stdout);
        fflush(stdout);
     }
-    if ((remotehost = agets(stdin)) == NULL) {
-       return 0;
-    }
+
+    do {
+       amfree(remotehost);
+       remotehost = agets(stdin);
+       if (remotehost == NULL)
+           return 0;
+    } while (remotehost[0] == '\0');
 
     set_pname("security");
+    dbopen(NULL);
+
     startclock();
 
     if ((hp = gethostbyname(remotehost)) == NULL) {
@@ -1841,14 +709,15 @@ main (argc, argv)
     }
     memcpy((char *)&netfd.peer.sin_addr,
           (char *)hp->h_addr,
-          sizeof(hp->h_addr));
+          SIZEOF(hp->h_addr));
     /*
      * Fake that it is coming from a reserved port.
      */
     netfd.peer.sin_port = htons(IPPORT_RESERVED - 1);
 
-    bh = alloc(sizeof(*bh));
+    bh = alloc(SIZEOF(*bh));
     bh->proto_handle=NULL;
+    bh->udp = &netfd;
     netfd.pkt.type = P_REQ;
     dgram_zero(&netfd.dgram);
     save_cur = netfd.dgram.cur;                                /* cheating */
@@ -1856,8 +725,10 @@ main (argc, argv)
     dgram_cat(&netfd.dgram, "SECURITY USER %s\n", remoteuser);
     netfd.dgram.cur = save_cur;                                /* cheating */
 
-    accept_fn = fake_accept_function;
-    netfd_read_callback(NULL);
+    netfd.accept_fn = fake_accept_function;
+    netfd.recv_security_ok = &bsd_recv_security_ok;
+    netfd.prefix_packet = &bsd_prefix_packet;
+    udp_netfd_read_callback(&netfd);
 
     return 0;
 }
diff --git a/common-src/bsdtcp-security.c b/common-src/bsdtcp-security.c
new file mode 100644 (file)
index 0000000..9ddf90c
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1999 University of Maryland
+ * 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+
+/*
+ * $Id: bsdtcp-security.c,v 1.7 2006/07/13 03:22:20 paddy_s Exp $
+ *
+ * bsdtcp-security.c - security and transport over bsdtcp or a bsdtcp-like command.
+ *
+ * XXX still need to check for initial keyword on connect so we can skip
+ * over shell garbage and other stuff that bsdtcp might want to spew out.
+ */
+
+#include "amanda.h"
+#include "util.h"
+#include "event.h"
+#include "packet.h"
+#include "queue.h"
+#include "security.h"
+#include "security-util.h"
+#include "stream.h"
+#include "version.h"
+
+#ifdef BSDTCP_SECURITY
+
+/*#define      BSDTCP_DEBUG*/
+
+#ifdef BSDTCP_DEBUG
+#define        bsdtcpprintf(x) dbprintf(x)
+#else
+#define        bsdtcpprintf(x)
+#endif
+
+
+/*
+ * Number of seconds bsdtcp has to start up
+ */
+#define        CONNECT_TIMEOUT 20
+
+/*
+ * Interface functions
+ */
+static void bsdtcp_accept(const struct security_driver *, int, int,
+    void (*)(security_handle_t *, pkt_t *));
+static void bsdtcp_connect(const char *,
+    char *(*)(char *, void *), 
+    void (*)(void *, security_handle_t *, security_status_t), void *, void *);
+
+/*
+ * This is our interface to the outside world.
+ */
+const security_driver_t bsdtcp_security_driver = {
+    "BSDTCP",
+    bsdtcp_connect,
+    bsdtcp_accept,
+    sec_close,
+    stream_sendpkt,
+    stream_recvpkt,
+    stream_recvpkt_cancel,
+    tcpma_stream_server,
+    tcpma_stream_accept,
+    tcpma_stream_client,
+    tcpma_stream_close,
+    sec_stream_auth,
+    sec_stream_id,
+    tcpm_stream_write,
+    tcpm_stream_read,
+    tcpm_stream_read_sync,
+    tcpm_stream_read_cancel,
+    tcpm_close_connection,
+};
+
+static int newhandle = 1;
+
+/*
+ * Local functions
+ */
+static int runbsdtcp(struct sec_handle *);
+
+
+/*
+ * bsdtcp version of a security handle allocator.  Logically sets
+ * up a network "connection".
+ */
+static void
+bsdtcp_connect(
+    const char *hostname,
+    char *     (*conf_fn)(char *, void *),
+    void       (*fn)(void *, security_handle_t *, security_status_t),
+    void *     arg,
+    void *     datap)
+{
+    struct sec_handle *rh;
+    struct hostent *he;
+
+    assert(fn != NULL);
+    assert(hostname != NULL);
+    (void)conf_fn;     /* Quiet unused parameter warning */
+    (void)datap;       /* Quiet unused parameter warning */
+
+    bsdtcpprintf(("%s: bsdtcp: bsdtcp_connect: %s\n", debug_prefix_time(NULL),
+              hostname));
+
+    rh = alloc(sizeof(*rh));
+    security_handleinit(&rh->sech, &bsdtcp_security_driver);
+    rh->hostname = NULL;
+    rh->rs = NULL;
+    rh->ev_timeout = NULL;
+    rh->rc = NULL;
+
+    if ((he = gethostbyname(hostname)) == NULL) {
+       security_seterror(&rh->sech,
+           "%s: could not resolve hostname", hostname);
+       (*fn)(arg, &rh->sech, S_ERROR);
+       return;
+    }
+    rh->hostname = stralloc(he->h_name);       /* will be replaced */
+    rh->rs = tcpma_stream_client(rh, newhandle++);
+    rh->rc->recv_security_ok = &bsd_recv_security_ok;
+    rh->rc->prefix_packet = &bsd_prefix_packet;
+
+    if (rh->rs == NULL)
+       goto error;
+
+    amfree(rh->hostname);
+    rh->hostname = stralloc(rh->rs->rc->hostname);
+
+    /*
+     * We need to open a new connection.
+     *
+     * XXX need to eventually limit number of outgoing connections here.
+     */
+    if(rh->rc->read == -1) {
+       if (runbsdtcp(rh) < 0)
+           goto error;
+       rh->rc->refcnt++;
+    }
+
+    /*
+     * The socket will be opened async so hosts that are down won't
+     * block everything.  We need to register a write event
+     * so we will know when the socket comes alive.
+     *
+     * Overload rh->rs->ev_read to provide a write event handle.
+     * We also register a timeout.
+     */
+    rh->fn.connect = fn;
+    rh->arg = arg;
+    rh->rs->ev_read = event_register((event_id_t)(rh->rs->rc->write),
+       EV_WRITEFD, sec_connect_callback, rh);
+    rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
+       sec_connect_timeout, rh);
+
+    return;
+
+error:
+    (*fn)(arg, &rh->sech, S_ERROR);
+}
+
+/*
+ * Setup to handle new incoming connections
+ */
+static void
+bsdtcp_accept(
+    const struct security_driver *driver,
+    int                in,
+    int                out,
+    void       (*fn)(security_handle_t *, pkt_t *))
+{
+    struct sockaddr_in sin;
+    socklen_t len;
+    struct tcp_conn *rc;
+    struct hostent *he;
+
+    len = sizeof(sin);
+    if (getpeername(in, (struct sockaddr *)&sin, &len) < 0)
+       return;
+    he = gethostbyaddr((void *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET);
+    if (he == NULL)
+       return;
+
+    rc = sec_tcp_conn_get(he->h_name, 0);
+    rc->recv_security_ok = &bsd_recv_security_ok;
+    rc->prefix_packet = &bsd_prefix_packet;
+    memcpy(&rc->peer.sin_addr, he->h_addr, sizeof(rc->peer.sin_addr));
+    rc->peer.sin_port = sin.sin_port;
+    rc->read = in;
+    rc->write = out;
+    rc->accept_fn = fn;
+    rc->driver = driver;
+    sec_tcp_conn_read(rc);
+}
+
+/*
+ * Forks a bsdtcp to the host listed in rc->hostname
+ * Returns negative on error, with an errmsg in rc->errmsg.
+ */
+static int
+runbsdtcp(
+    struct sec_handle *        rh)
+{
+    struct servent *   sp;
+    int                        server_socket;
+    in_port_t          my_port;
+    uid_t              euid;
+    struct tcp_conn *  rc = rh->rc;
+
+    if ((sp = getservbyname("amanda", "tcp")) == NULL) {
+       error("%s/tcp unknown protocol", "amanda");
+    }
+
+    euid = geteuid();
+    seteuid(0);
+
+    server_socket = stream_client_privileged(rc->hostname,
+                                    (in_port_t)(ntohs((in_port_t)sp->s_port)),
+                                    STREAM_BUFSIZE,
+                                    STREAM_BUFSIZE,
+                                    &my_port,
+                                    0);
+
+    if(server_socket < 0) {
+       security_seterror(&rh->sech,
+           "%s", strerror(errno));
+       
+       return -1;
+    }
+    seteuid(euid);
+
+    if(my_port >= IPPORT_RESERVED) {
+       security_seterror(&rh->sech,
+                         "did not get a reserved port: %d", my_port);
+    }
+
+    rc->read = rc->write = server_socket;
+    return 0;
+}
+
+#endif /* BSDTCP_SECURITY */
diff --git a/common-src/bsdudp-security.c b/common-src/bsdudp-security.c
new file mode 100644 (file)
index 0000000..ae2325f
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1999 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: bsdudp-security.c,v 1.7 2006/07/05 13:18:20 martinea Exp $
+ *
+ * "BSD" security module
+ */
+
+#include "amanda.h"
+#include "util.h"
+#include "clock.h"
+#include "dgram.h"
+#include "event.h"
+#include "packet.h"
+#include "security.h"
+#include "security-util.h"
+#include "stream.h"
+#include "version.h"
+
+#ifdef BSDUDP_SECURITY
+
+/*#define       BSDUDP_DEBUG*/
+
+#ifdef BSDUDP_DEBUG
+#define bsdudpprintf(x)    dbprintf(x)
+#else
+#define bsdudpprintf(x)
+#endif
+
+#ifndef SO_RCVBUF
+#undef DUMPER_SOCKET_BUFFERING
+#endif
+
+/*
+ * Change the following from #undef to #define to cause detailed logging
+ * of the security steps, e.g. into /tmp/amanda/amandad*debug.
+ */
+#undef SHOW_SECURITY_DETAIL
+
+#if defined(TEST)                                              /* { */
+#define SHOW_SECURITY_DETAIL
+#undef bsdudpprintf
+#define bsdudpprintf(p)        printf p
+#endif                                                         /* } */
+
+/*
+ * Interface functions
+ */
+static void bsdudp_connect(const char *,
+    char *(*)(char *, void *), 
+    void (*)(void *, security_handle_t *, security_status_t), void *, void *);
+static void bsdudp_accept(const struct security_driver *, int, int, void (*)(security_handle_t *, pkt_t *));
+static void bsdudp_close(void *);
+
+/*
+ * This is our interface to the outside world
+ */
+const security_driver_t bsdudp_security_driver = {
+    "BSDUDP",
+    bsdudp_connect,
+    bsdudp_accept,
+    bsdudp_close,
+    udpbsd_sendpkt,
+    udp_recvpkt,
+    udp_recvpkt_cancel,
+    tcp1_stream_server,
+    tcp1_stream_accept,
+    tcp1_stream_client,
+    tcpma_stream_close,
+    sec_stream_auth,
+    sec_stream_id,
+    tcpm_stream_write,
+    tcpm_stream_read,
+    tcpm_stream_read_sync,
+    tcpm_stream_read_cancel,
+    sec_close_connection_none,
+};
+
+/*
+ * This is data local to the datagram socket.  We have one datagram
+ * per process, so it is global.
+ */
+static udp_handle_t netfd;
+static int not_init = 1;
+
+/* generate new handles from here */
+static unsigned int newhandle = 0;
+
+/*
+ * Setup and return a handle outgoing to a client
+ */
+static void
+bsdudp_connect(
+    const char *hostname,
+    char *     (*conf_fn)(char *, void *),
+    void       (*fn)(void *, security_handle_t *, security_status_t),
+    void *     arg,
+    void *     datap)
+{
+    struct sec_handle *bh;
+    struct servent *se;
+    struct hostent *he;
+    in_port_t port;
+    struct timeval sequence_time;
+    amanda_timezone dontcare;
+    int sequence;
+    char *handle;
+
+    (void)conf_fn;     /* Quiet unused parameter warning */
+    (void)datap;       /* Quiet unused parameter warning */
+    assert(hostname != NULL);
+
+    bh = alloc(sizeof(*bh));
+    bh->proto_handle=NULL;
+    bh->udp = &netfd;
+    bh->rc = NULL;
+    security_handleinit(&bh->sech, &bsdudp_security_driver);
+
+    /*
+     * Only init the socket once
+     */
+    if (not_init == 1) {
+       uid_t euid;
+       dgram_zero(&netfd.dgram);
+       
+       euid = geteuid();
+       seteuid(0);
+       dgram_bind(&netfd.dgram, &port);
+       seteuid(euid);
+       netfd.handle = NULL;
+       netfd.pkt.body = NULL;
+       netfd.recv_security_ok = &bsd_recv_security_ok;
+       netfd.prefix_packet = &bsd_prefix_packet;
+       /*
+        * We must have a reserved port.  Bomb if we didn't get one.
+        */
+       if (port >= IPPORT_RESERVED) {
+           security_seterror(&bh->sech,
+               "unable to bind to a reserved port (got port %u)",
+               (unsigned int)port);
+           (*fn)(arg, &bh->sech, S_ERROR);
+           return;
+       }
+       not_init = 0;
+    }
+
+    if ((he = gethostbyname(hostname)) == NULL) {
+       security_seterror(&bh->sech,
+           "%s: could not resolve hostname", hostname);
+       (*fn)(arg, &bh->sech, S_ERROR);
+       return;
+    }
+    if ((se = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL)
+       port = (in_port_t)htons(AMANDA_SERVICE_DEFAULT);
+    else
+       port = (in_port_t)se->s_port;
+    amanda_gettimeofday(&sequence_time, &dontcare);
+    sequence = (int)sequence_time.tv_sec ^ (int)sequence_time.tv_usec;
+    handle=alloc(15);
+    snprintf(handle,14,"000-%08x", newhandle++);
+    if (udp_inithandle(&netfd, bh, he, port, handle, sequence) < 0) {
+       (*fn)(arg, &bh->sech, S_ERROR);
+       amfree(bh->hostname);
+       amfree(bh);
+    } else {
+       (*fn)(arg, &bh->sech, S_OK);
+    }
+    amfree(handle);
+}
+
+/*
+ * Setup to accept new incoming connections
+ */
+static void
+bsdudp_accept(
+    const struct security_driver *driver,
+    int                in,
+    int                out,
+    void       (*fn)(security_handle_t *, pkt_t *))
+{
+    (void)driver;      /* Quiet unused parameter warning */
+    (void)out;         /* Quiet unused parameter warning */
+
+    assert(in >= 0 && out >= 0);
+    assert(fn != NULL);
+
+    /*
+     * We assume in and out point to the same socket, and just use
+     * in.
+     */
+    dgram_socket(&netfd.dgram, in);
+
+    /*
+     * Assign the function and return.  When they call recvpkt later,
+     * the recvpkt callback will call this function when it discovers
+     * new incoming connections
+     */
+    netfd.accept_fn = fn;
+    netfd.recv_security_ok = &bsd_recv_security_ok;
+    netfd.prefix_packet = &bsd_prefix_packet;
+    netfd.driver = &bsdudp_security_driver;
+
+
+    udp_addref(&netfd, &udp_netfd_read_callback);
+}
+
+/*
+ * Frees a handle allocated by the above
+ */
+static void
+bsdudp_close(
+    void *cookie)
+{
+    struct sec_handle *bh = cookie;
+
+    if(bh->proto_handle == NULL) {
+       return;
+    }
+
+    bsdudpprintf(("%s: bsdudp: close handle '%s'\n",
+              debug_prefix_time(NULL), bh->proto_handle));
+
+    udp_recvpkt_cancel(bh);
+    if(bh->next) {
+       bh->next->prev = bh->prev;
+    }
+    else {
+       netfd.bh_last = bh->prev;
+    }
+    if(bh->prev) {
+       bh->prev->next = bh->next;
+    }
+    else {
+       netfd.bh_first = bh->next;
+    }
+
+    amfree(bh->proto_handle);
+    amfree(bh->hostname);
+    amfree(bh);
+}
+
+#endif /* BSDUDP_SECURITY */                                   /* } */
+
index 732b4ef01b578b3b57c1a4e0ca16b53ad572851d..905c68e603a50d6048e4253089e735a1ea7f1021 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: clock.c,v 1.5 2002/04/08 00:16:18 jrjackson Exp $
+ * $Id: clock.c,v 1.7 2006/07/27 18:12:10 martinea Exp $
  *
  * timing functions
  */
 #include "clock.h"
 
 /* local functions */
-static struct timeval timesub P((struct timeval end, struct timeval start));
-static struct timeval timeadd P((struct timeval a, struct timeval b));
+static struct timeval timesub(struct timeval end, struct timeval start);
+static struct timeval timeadd(struct timeval a, struct timeval b);
 
-times_t times_zero = {{0,0}};
+times_t times_zero;
 times_t start_time;
 static int clock_running = 0;
 
-int clock_is_running()
+int
+clock_is_running(void)
 {
     return clock_running;
 }
 
-void startclock()
+void
+startclock(void)
 {
     amanda_timezone dontcare;
 
@@ -54,7 +56,8 @@ void startclock()
     amanda_gettimeofday(&start_time.r, &dontcare);
 }
 
-times_t stopclock()
+times_t
+stopclock(void)
 {
     times_t diff;
     struct timeval end_time;
@@ -70,7 +73,8 @@ times_t stopclock()
     return diff;
 }
 
-times_t curclock()
+times_t
+curclock(void)
 {
     times_t diff;
     struct timeval end_time;
@@ -85,8 +89,10 @@ times_t curclock()
     return diff;
 }
 
-times_t timesadd(a,b)
-times_t a,b;
+times_t
+timesadd(
+    times_t    a,
+    times_t    b)
 {
     times_t sum;
 
@@ -94,8 +100,10 @@ times_t a,b;
     return sum;
 }
 
-times_t timessub(a,b)
-times_t a,b;
+times_t
+timessub(
+    times_t    a,
+    times_t    b)
 {
     times_t dif;
 
@@ -103,43 +111,50 @@ times_t a,b;
     return dif;
 }
 
-char *times_str(t)
-times_t t;
+char *
+times_str(
+    times_t    t)
 {
     static char str[10][NUM_STR_SIZE+10];
-    static int n = 0;
+    static size_t n = 0;
     char *s;
 
     /* tv_sec/tv_usec are longs on some systems */
-    snprintf(str[n], sizeof(str[n]),
-               "rtime %d.%03d", (int)t.r.tv_sec, (int)t.r.tv_usec/1000);
+    snprintf(str[n], SIZEOF(str[n]), "rtime %lu.%03lu",
+            (unsigned long)t.r.tv_sec,
+            (unsigned long)t.r.tv_usec / 1000);
     s = str[n++];
     n %= am_countof(str);
     return s;
 }
 
-char *walltime_str(t)
-times_t t;
+char *
+walltime_str(
+    times_t    t)
 {
     static char str[10][NUM_STR_SIZE+10];
-    static int n = 0;
+    static size_t n = 0;
     char *s;
 
     /* tv_sec/tv_usec are longs on some systems */
-    snprintf(str[n], sizeof(str[n]),
-               "%d.%03d", (int)t.r.tv_sec, (int)t.r.tv_usec/1000);
+    snprintf(str[n], SIZEOF(str[n]), "%lu.%03lu",
+            (unsigned long)t.r.tv_sec,
+            (unsigned long)t.r.tv_usec/1000);
     s = str[n++];
     n %= am_countof(str);
     return s;
 }
 
-static struct timeval timesub(end,start)
-struct timeval end,start;
+static struct timeval
+timesub(
+    struct timeval     end,
+    struct timeval     start)
 {
     struct timeval diff;
 
     if(end.tv_usec < start.tv_usec) { /* borrow 1 sec */
-       end.tv_sec -= 1;
+       if (end.tv_sec > 0)
+           end.tv_sec -= 1;
        end.tv_usec += 1000000;
     }
     diff.tv_usec = end.tv_usec - start.tv_usec;
@@ -147,8 +162,10 @@ struct timeval end,start;
     return diff;
 }
 
-static struct timeval timeadd(a,b)
-struct timeval a,b;
+static struct timeval
+timeadd(
+    struct timeval     a,
+    struct timeval     b)
 {
     struct timeval sum;
 
index 4da1cfca8757559e6f29bb2fbc65653b1e3cb89a..391b3835a4494e2e7276bd948fd408df3878cfe7 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: clock.h,v 1.5 2002/04/08 00:16:18 jrjackson Exp $
+ * $Id: clock.h,v 1.6 2006/05/25 01:47:11 johnfranks Exp $
  *
  * interface for timing functions
  */
@@ -52,13 +52,13 @@ extern times_t times_zero, start_time;
 #  define amanda_gettimeofday(x, y) gettimeofday((x))
 #endif
 
-void startclock P((void));
-times_t stopclock P((void));
-times_t curclock P((void));
-times_t timesadd P((times_t a, times_t b));
-times_t timessub P((times_t a, times_t b));
-char * times_str P((times_t t));
-char * walltime_str P((times_t t));
-int clock_is_running P((void));
+void startclock(void);
+times_t stopclock(void);
+times_t curclock(void);
+times_t timesadd(times_t a, times_t b);
+times_t timessub(times_t a, times_t b);
+char * times_str(times_t t);
+char * walltime_str(times_t t);
+int clock_is_running(void);
 
 #endif /* CLOCK_H */
index 66d31bd42c409247d4e8a5c9f9b847be6703a64c..b958b6325fef1015e2dfa69ab60eccb816780d56 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: debug.c,v 1.36 2006/01/12 01:57:05 paddy_s Exp $
+ * $Id: debug.c,v 1.40 2006/07/26 11:49:32 martinea Exp $
  *
  * debug log subroutines
  */
@@ -47,9 +47,13 @@ int debug = 1;
 
 static int db_fd = 2;                  /* default is stderr */
 static FILE *db_file = NULL;           /* stderr may not be a constant */
-static char *db_filename = NULL;
+static char *db_name  = NULL;          /* filename */
+static char *db_filename = NULL;       /* /path/to/filename */
 
 static pid_t debug_prefix_pid = 0;
+static char *get_debug_name(time_t t, int n);
+static void debug_setup_1(char *config, char *subdir);
+static void debug_setup_2(char *s, int fd, char *notation);
 
 /*
  * Format and write a debug message to the process debug file.
@@ -57,7 +61,6 @@ static pid_t debug_prefix_pid = 0;
 printf_arglist_function(void debug_printf, const char *, format)
 {
     va_list argp;
-    int save_errno;
 
     /*
      * It is common in the code to call dbprintf to write out
@@ -65,19 +68,21 @@ printf_arglist_function(void debug_printf, const char *, format)
      * with errno (e.g. printf() or log()), so we make sure errno goes
      * back out with the same value it came in with.
      */
-    save_errno = errno;
+    if (debug != 0) {
+        int save_errno;
 
-    if(db_file == NULL && db_fd == 2) {
-       db_file = stderr;
-    }
-    if(db_file != NULL) {
-       arglist_start(argp, format);
-       vfprintf(db_file, format, argp);
-       fflush(db_file);
-       arglist_end(argp);
+       save_errno = errno;
+       if(db_file == NULL && db_fd == 2) {
+           db_file = stderr;
+       }
+       if(db_file != NULL) {
+           arglist_start(argp, format);
+           vfprintf(db_file, format, argp);
+           fflush(db_file);
+           arglist_end(argp);
+       }
+       errno = save_errno;
     }
-
-    errno = save_errno;
 }
 
 /*
@@ -85,9 +90,9 @@ printf_arglist_function(void debug_printf, const char *, format)
  * followed by a timestamp, an optional sequence number, and ".debug".
  */
 static char *
-get_debug_name(t, n)
-    time_t t;
-    int n;
+get_debug_name(
+    time_t     t,
+    int                n)
 {
     char number[NUM_STR_SIZE];
     char *ts;
@@ -100,7 +105,7 @@ get_debug_name(t, n)
     if(n == 0) {
        number[0] = '\0';
     } else {
-       snprintf(number, sizeof(number), "%03d", n - 1);
+       snprintf(number, SIZEOF(number), "%03d", n - 1);
     }
     result = vstralloc(get_pname(), ".", ts, number, ".debug", NULL);
     amfree(ts);
@@ -110,7 +115,8 @@ get_debug_name(t, n)
 static char *dbgdir = NULL;
 static time_t curtime;
 
-static void debug_setup_1()
+static void
+debug_setup_1(char *config, char *subdir)
 {
     struct passwd *pwent;
     char *pname;
@@ -120,13 +126,15 @@ static void debug_setup_1()
     DIR *d;
     struct dirent *entry;
     int do_rename;
-    char *test_name = NULL;
+    char *test_name;
     size_t test_name_len;
     size_t d_name_len;
     struct stat sbuf;
     char *dbfilename = NULL;
+    char *sane_config = NULL;
     int i;
 
+    memset(&sbuf, 0, SIZEOF(sbuf));
     if(client_uid == (uid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) {
        client_uid = pwent->pw_uid;
        client_gid = pwent->pw_gid;
@@ -140,11 +148,23 @@ static void debug_setup_1()
      * Create the debug directory if it does not yet exist.
      */
     amfree(dbgdir);
-    dbgdir = stralloc2(AMANDA_DBGDIR, "/");
+    if (config)
+       sane_config = sanitise_filename(config);
+    if (sane_config && subdir)
+       dbgdir = vstralloc(AMANDA_DBGDIR, "/", subdir, "/", sane_config,
+                          "/", NULL);
+    else if (sane_config)
+       dbgdir = vstralloc(AMANDA_DBGDIR, "/", sane_config, "/", NULL);
+    else if (subdir)
+       dbgdir = vstralloc(AMANDA_DBGDIR, "/", subdir, "/", NULL);
+    else
+       dbgdir = stralloc2(AMANDA_DBGDIR, "/");
     if(mkpdir(dbgdir, 02700, client_uid, client_gid) == -1) {
         error("create debug directory \"%s\": %s",
              AMANDA_DBGDIR, strerror(errno));
+        /*NOTREACHED*/
     }
+    amfree(sane_config);
 
     /*
      * Clean out old debug files.  We also rename files with old style
@@ -155,6 +175,7 @@ static void debug_setup_1()
     if((d = opendir(AMANDA_DBGDIR)) == NULL) {
         error("open debug directory \"%s\": %s",
              AMANDA_DBGDIR, strerror(errno));
+        /*NOTREACHED*/
     }
     time(&curtime);
     test_name = get_debug_name(curtime - (AMANDA_DEBUG_DAYS * 24 * 60 * 60), 0);
@@ -202,6 +223,7 @@ static void debug_setup_1()
            }
            if(dbfilename == NULL) {
                error("cannot rename old debug file \"%s\"", entry->d_name);
+               /*NOTREACHED*/
            }
        }
     }
@@ -212,33 +234,40 @@ static void debug_setup_1()
     closedir(d);
 }
 
-static void debug_setup_2(s, fd, notation)
-    char *s;
-    int fd;
-    char *notation;
+static void
+debug_setup_2(
+    char *     s,
+    int                fd,
+    char *     notation)
 {
     int saved_debug;
-    int i;
+    int i, rc;
     int fd_close[MIN_DB_FD+1];
 
     amfree(db_filename);
     db_filename = s;
     s = NULL;
-    (void) chown(db_filename, client_uid, client_gid);
+    if ((rc = chown(db_filename, client_uid, client_gid)) < 0) {
+       dbprintf(("chown(%s, %d, %d) failed. <%s>",
+                 db_filename, client_uid, client_gid, strerror(errno)));
+       (void)rc;
+    }
     amfree(dbgdir);
     /*
      * Move the file descriptor up high so it stays out of the way
      * of other processing, e.g. sendbackup.
      */
-    i = 0;
-    fd_close[i++] = fd;
-    while((db_fd = dup(fd)) < MIN_DB_FD) {
-       fd_close[i++] = db_fd;
-    }
-    while(--i >= 0) {
-       close(fd_close[i]);
+    if (fd >= 0) {
+       i = 0;
+       fd_close[i++] = fd;
+       while((db_fd = dup(fd)) < MIN_DB_FD) {
+           fd_close[i++] = db_fd;
+       }
+       while(--i >= 0) {
+           close(fd_close[i]);
+       }
+       db_file = fdopen(db_fd, "a");
     }
-    db_file = fdopen(db_fd, "a");
 
     if (notation) {
        /*
@@ -254,9 +283,9 @@ static void debug_setup_2(s, fd, notation)
     }
 }
 
-void debug_open()
+void
+debug_open(char *subdir)
 {
-    char *dbfilename = NULL;
     int fd = -1;
     int i;
     char *s = NULL;
@@ -265,29 +294,29 @@ void debug_open()
     /*
      * Do initial setup.
      */
-    debug_setup_1();
+    debug_setup_1(NULL, subdir);
 
     /*
      * Create the new file with a unique sequence number.
      */
-    mask = umask(0037); /* Allow the group read bit through */
+    mask = (mode_t)umask((mode_t)0037); /* Allow the group read bit through */
     for(i = 0; fd < 0; i++) {
-        if ((dbfilename = get_debug_name(curtime, i)) == NULL) {
+       amfree(db_name);
+       if ((db_name = get_debug_name(curtime, i)) == NULL) {
            error("Cannot create %s debug file", get_pname());
-            /* NOTREACHED */
+           /*NOTREACHED*/
         }
 
-        if ((s = newvstralloc(s, dbgdir, dbfilename, NULL)) == NULL) {
+       if ((s = newvstralloc(s, dbgdir, db_name, NULL)) == NULL) {
            error("Cannot allocate %s debug file name memory", get_pname());
-            /* NOTREACHED */
-        }
-        amfree(dbfilename);
+           /*NOTREACHED*/
+       }
 
         if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) {
             if (errno != EEXIST) {
                 error("Cannot create %s debug file: %s",
                        get_pname(), strerror(errno));
-                /* NOTREACHED */
+                /*NOTREACHED*/
             }
             amfree(s);
         }
@@ -302,12 +331,13 @@ void debug_open()
     debug_setup_2(s, fd, "start");
 }
 
-void debug_reopen(dbfilename, notation)
-    char *dbfilename;
-    char *notation;
+void
+debug_reopen(
+    char *     dbfilename,
+    char *     notation)
 {
     char *s = NULL;
-    int fd = -1;
+    int fd;
 
     if (dbfilename == NULL) {
        return;
@@ -316,7 +346,7 @@ void debug_reopen(dbfilename, notation)
     /*
      * Do initial setup.
      */
-    debug_setup_1();
+    debug_setup_1(NULL, NULL);
 
     /*
      * Reopen the file.
@@ -328,6 +358,7 @@ void debug_reopen(dbfilename, notation)
     }
     if ((fd = open(s, O_RDWR|O_APPEND)) < 0) {
        error("cannot reopen %s debug file %s", get_pname(), dbfilename);
+       /*NOTREACHED*/
     }
 
     /*
@@ -338,7 +369,67 @@ void debug_reopen(dbfilename, notation)
     debug_setup_2(s, fd, notation);
 }
 
-void debug_close()
+void
+debug_rename(
+    char *config,
+    char *subdir)
+{
+    int fd = -1;
+    int i;
+    char *s = NULL;
+    mode_t mask;
+
+    if (!db_filename)
+       return;
+
+    /*
+     * Do initial setup.
+     */
+    debug_setup_1(config, subdir);
+
+    s = newvstralloc(s, dbgdir, db_name, NULL);
+
+    if (strcmp(db_filename, s) == 0) {
+       amfree(s);
+       return;
+    }
+
+    mask = (mode_t)umask((mode_t)0037);
+    /* check if a file with the same name already exist */
+    if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) {
+       for(i = 0; fd < 0; i++) {
+           amfree(db_name);
+           if ((db_name = get_debug_name(curtime, i)) == NULL) {
+               dbprintf(("Cannot create %s debug file", get_pname()));
+               break;
+           }
+
+           s = newvstralloc(s, dbgdir, db_name, NULL);
+           if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) {
+               if (errno != EEXIST) {
+                   dbprintf(("Cannot create %s debug file: %s", get_pname(),
+                             strerror(errno)));
+                   break;
+               }
+           }
+       }
+    }
+
+    if (fd >= 0) {
+       rename(db_filename, s);
+    }
+    (void)umask(mask); /* Restore mask */
+    close(fd);
+    /*
+     * Finish setup.
+     *
+     * Note: we release control of the string 's' points to.
+     */
+    debug_setup_2(s, -1, "rename");
+}
+
+void
+debug_close(void)
 {
     time_t curtime;
     int save_debug;
@@ -360,24 +451,28 @@ void debug_close()
        int save_errno = errno;
 
        db_file = NULL;                         /* prevent recursion */
-       error("close debug file: %s", strerror(save_errno));
+       fprintf(stderr, "close debug file: %s", strerror(save_errno));
+       /*NOTREACHED*/
     }
     db_fd = -1;
     db_file = NULL;
     amfree(db_filename);
 }
 
-int debug_fd()
+int
+debug_fd(void)
 {
     return db_fd;
 }
 
-FILE *debug_fp()
+FILE *
+debug_fp(void)
 {
     return db_file;
 }
 
-char *debug_fn()
+char *
+debug_fn(void)
 {
     return db_filename;
 }
@@ -389,14 +484,16 @@ char *debug_fn()
  * time indicator.
  */ 
 
-void set_debug_prefix_pid(p)
-    pid_t p;
+void
+set_debug_prefix_pid(
+    pid_t      p)
 {
     debug_prefix_pid = p;
 }
 
-char *debug_prefix(suffix)
-    char *suffix;
+char *
+debug_prefix(
+    char *     suffix)
 {
     int save_errno;
     static char *s = NULL;
@@ -405,7 +502,7 @@ char *debug_prefix(suffix)
     save_errno = errno;
     s = newvstralloc(s, get_pname(), suffix, NULL);
     if (debug_prefix_pid != (pid_t) 0) {
-       snprintf(debug_pid, sizeof(debug_pid),
+       snprintf(debug_pid, SIZEOF(debug_pid),
                 "%ld",
                 (long) debug_prefix_pid);
        s = newvstralloc(s, s, "[", debug_pid, "]", NULL);
@@ -414,8 +511,9 @@ char *debug_prefix(suffix)
     return s;
 }
 
-char *debug_prefix_time(suffix)
-    char *suffix;
+char *
+debug_prefix_time(
+    char *     suffix)
 {
     int save_errno;
     static char *s = NULL;
index cdf8a09912110f1f414e625c193afe2242b89959..5df3a57a92aead45fef282039b4eec5fbff8a6c4 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /* 
- * $Id: dgram.c,v 1.29 2006/01/12 01:57:05 paddy_s Exp $
+ * $Id: dgram.c,v 1.32 2006/07/05 19:54:20 martinea Exp $
  *
  * library routines to marshall/send, recv/unmarshall UDP packets
  */
 #include "dgram.h"
 #include "util.h"
 
-void dgram_socket(dgram, socket)
-dgram_t *dgram;
-int socket;
+void
+dgram_socket(
+    dgram_t *  dgram,
+    int                socket)
 {
     if(socket < 0 || socket >= FD_SETSIZE) {
        error("dgram_socket: socket %d out of range (0 .. %d)\n",
              socket, FD_SETSIZE-1);
+        /*NOTREACHED*/
     }
     dgram->socket = socket;
 }
 
 
-int dgram_bind(dgram, portp)
-dgram_t *dgram;
-int *portp;
+int
+dgram_bind(
+    dgram_t *  dgram,
+    in_port_t *        portp)
 {
-    int s;
+    int s, retries;
     socklen_t len;
     struct sockaddr_in name;
     int save_errno;
+#if defined(USE_REUSEADDR)
+    const int on = 1;
+    int r;
+#endif
 
+    *portp = (in_port_t)0;
     if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        save_errno = errno;
        dbprintf(("%s: dgram_bind: socket() failed: %s\n",
@@ -63,7 +71,7 @@ int *portp;
        errno = save_errno;
        return -1;
     }
-    if(s < 0 || s >= FD_SETSIZE) {
+    if(s < 0 || s >= (int)FD_SETSIZE) {
        dbprintf(("%s: dgram_bind: socket out of range: %d\n",
                  debug_prefix(NULL),
                  s));
@@ -72,10 +80,20 @@ int *portp;
        return -1;
     }
 
-    memset(&name, 0, sizeof(name));
-    name.sin_family = AF_INET;
+    memset(&name, 0, SIZEOF(name));
+    name.sin_family = (sa_family_t)AF_INET;
     name.sin_addr.s_addr = INADDR_ANY;
 
+#ifdef USE_REUSEADDR
+    r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+       (void *)&on, (socklen_t)sizeof(on));
+    if (r < 0) {
+       dbprintf(("%s: dgram_bind: setsockopt(SO_REUSEADDR) failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(errno)));
+    }
+#endif
+
     /*
      * If a port range was specified, we try to get a port in that
      * range first.  Next, we try to get a reserved port.  If that
@@ -87,29 +105,48 @@ int *portp;
      * to get the desired port, and to make sure we return a port that
      * is within the range it requires.
      */
+    for (retries = 0; ; retries++) {
 #ifdef UDPPORTRANGE
-    if (bind_portrange(s, &name, UDPPORTRANGE, "udp") == 0)
-       goto out;
+       if (bind_portrange(s, &name, UDPPORTRANGE, "udp") == 0)
+           goto out;
+       dbprintf(("%s: dgram_bind: Could to bind to port in range: %d - %d.\n",
+                 debug_prefix(NULL), UDPPORTRANGE));
 #endif
 
-    if (bind_portrange(s, &name, 512, IPPORT_RESERVED - 1, "udp") == 0)
-       goto out;
+       if (bind_portrange(s, &name, (in_port_t)512,
+               (in_port_t)(IPPORT_RESERVED - 1), "udp") == 0)
+           goto out;
+       dbprintf(("%s: dgram_bind: Could to bind to port in range: 512 - %d.\n",
+                 debug_prefix(NULL), IPPORT_RESERVED - 1));
+
+       name.sin_port = INADDR_ANY;
+       if (bind(s, (struct sockaddr *)&name, (socklen_t)sizeof(name)) == 0)
+           goto out;
+       dbprintf(("%s: dgram_bind: Could to bind to any port: %s\n",
+                 debug_prefix(NULL), strerror(errno)));
+
+       if (retries >= BIND_CYCLE_RETRIES) {
+           dbprintf(("%s: dgram_bind: Giving up...\n", debug_prefix(NULL)));
+           break;
+       }
 
-    name.sin_port = INADDR_ANY;
-    if (bind(s, (struct sockaddr *)&name, (socklen_t)sizeof name) == -1) {
-       save_errno = errno;
-       dbprintf(("%s: dgram_bind: bind(INADDR_ANY) failed: %s\n",
+       dbprintf(("%s: dgram_bind: Retrying entire range after 10 second delay.\n",
+                 debug_prefix(NULL)));
+       sleep(15);
+    }
+
+    save_errno = errno;
+    dbprintf(("%s: dgram_bind: bind(INADDR_ANY) failed: %s\n",
                  debug_prefix(NULL),
                  strerror(save_errno)));
-       errno = save_errno;
-       aclose(s);
-       return -1;
-    }
+    aclose(s);
+    errno = save_errno;
+    return -1;
 
 out:
     /* find out what name was actually used */
 
-    len = (socklen_t) sizeof name;
+    len = (socklen_t)sizeof(name);
     if(getsockname(s, (struct sockaddr *)&name, &len) == -1) {
        save_errno = errno;
        dbprintf(("%s: dgram_bind: getsockname() failed: %s\n",
@@ -119,7 +156,7 @@ out:
        aclose(s);
        return -1;
     }
-    *portp = ntohs(name.sin_port);
+    *portp = (in_port_t)ntohs(name.sin_port);
     dgram->socket = s;
 
     dbprintf(("%s: dgram_bind: socket bound to %s.%d\n",
@@ -130,17 +167,27 @@ out:
 }
 
 
-int dgram_send_addr(addr, dgram)
-struct sockaddr_in addr;
-dgram_t *dgram;
+int
+dgram_send_addr(
+    struct sockaddr_in addr,
+    dgram_t *          dgram)
 {
-    int s;
+    int s, rc;
     int socket_opened;
     struct sockaddr_in addr_save;
     int save_errno;
     int max_wait;
     int wait_count;
+#if defined(USE_REUSEADDR)
+    const int on = 1;
+    int r;
+#endif
 
+    dbprintf(("%s: dgram_send_addr(addr=%p, dgram=%p)\n",
+                       debug_prefix(NULL), &addr, dgram));
+    dump_sockaddr(&addr);
+    dbprintf(("%s: dgram_send_addr: %p->socket = %d\n",
+                       debug_prefix(NULL), dgram, dgram->socket));
     if(dgram->socket != -1) {
        s = dgram->socket;
        socket_opened = 0;
@@ -154,82 +201,93 @@ dgram_t *dgram;
            return -1;
        }
        socket_opened = 1;
+#ifdef USE_REUSEADDR
+       r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+               (void *)&on, (socklen_t)sizeof(on));
+       if (r < 0) {
+           dbprintf(("%s: dgram_send_addr: setsockopt(SO_REUSEADDR) failed: %s\n",
+                         debug_prefix(NULL),
+                         strerror(errno)));
+       }
+#endif
     }
 
+    memcpy(&addr_save, &addr, SIZEOF(addr));
     if(s < 0 || s >= FD_SETSIZE) {
        dbprintf(("%s: dgram_send_addr: socket out of range: %d\n",
                  debug_prefix(NULL),
                  s));
-       if(socket_opened) {
-           aclose(s);
-       }
        errno = EMFILE;                         /* out of range */
-       return -1;
-    }
-
-    memcpy(&addr_save, &addr, sizeof(addr));
-    max_wait = 300 / 5;                                /* five minutes */
-    wait_count = 0;
-    while(sendto(s,
+       rc = -1;
+    } else {
+       max_wait = 300 / 5;                             /* five minutes */
+       wait_count = 0;
+       rc = 0;
+       while(sendto(s,
                 dgram->data,
                 dgram->len,
                 0, 
                 (struct sockaddr *)&addr,
-                (socklen_t) sizeof(struct sockaddr_in)) == -1) {
+                (int)sizeof(struct sockaddr_in)) == -1) {
 #ifdef ECONNREFUSED
-       if(errno == ECONNREFUSED && wait_count++ < max_wait) {
-           sleep(5);
-           dbprintf(("%s: dgram_send_addr: sendto(%s.%d): retry %d after ECONNREFUSED\n",
+           if(errno == ECONNREFUSED && wait_count++ < max_wait) {
+               sleep(5);
+               dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after ECONNREFUSED\n",
                      debug_prefix_time(NULL),
                      inet_ntoa(addr_save.sin_addr),
-                     (int) ntohs(addr.sin_port),
+                     (in_port_t)ntohs(addr.sin_port),
                      wait_count));
-           continue;
-       }
+               continue;
+           }
 #endif
 #ifdef EAGAIN
-       if(errno == EAGAIN && wait_count++ < max_wait) {
-           sleep(5);
-           dbprintf(("%s: dgram_send_addr: sendto(%s.%d): retry %d after EAGAIN\n",
+           if(errno == EAGAIN && wait_count++ < max_wait) {
+               sleep(5);
+               dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after EAGAIN\n",
                      debug_prefix_time(NULL),
                      inet_ntoa(addr_save.sin_addr),
-                     (int) ntohs(addr.sin_port),
+                     (in_port_t)ntohs(addr.sin_port),
                      wait_count));
-           continue;
-       }
+               continue;
+           }
 #endif
-       save_errno = errno;
-       dbprintf(("%s: dgram_send_addr: sendto(%s.%d) failed: %s \n",
+           save_errno = errno;
+           dbprintf(("%s: dgram_send_addr: sendto(%s.%d) failed: %s \n",
                  debug_prefix_time(NULL),
                  inet_ntoa(addr_save.sin_addr),
                  (int) ntohs(addr.sin_port),
                  strerror(save_errno)));
-       errno = save_errno;
-        return -1;
+           errno = save_errno;
+           rc = -1;
+           break;
+       }
     }
 
     if(socket_opened) {
+       save_errno = errno;
        if(close(s) == -1) {
-           save_errno = errno;
            dbprintf(("%s: dgram_send_addr: close(%s.%d): failed: %s\n",
                      debug_prefix(NULL),
                      inet_ntoa(addr_save.sin_addr),
                      (int) ntohs(addr.sin_port),
-                     strerror(save_errno)));
-           errno = save_errno;
-           return -1;
+                     strerror(errno)));
+           /*
+            * Calling function should not care that the close failed.
+            * It does care about the send results though.
+            */
        }
-       s = -1;
+       errno = save_errno;
     }
 
-    return 0;
+    return rc;
 }
 
 
-int dgram_send(hostname, port, dgram)
-char *hostname;
-int port;
-dgram_t *dgram;
+int
+dgram_send(
+    char *     hostname,
+    in_port_t  port,
+    dgram_t *  dgram)
 {
     struct sockaddr_in name;
     struct hostent *hp;
@@ -243,25 +301,26 @@ dgram_t *dgram;
        errno = save_errno;
        return -1;
     }
-    memcpy(&name.sin_addr, hp->h_addr, hp->h_length);
-    name.sin_family = AF_INET;
-    name.sin_port = htons(port);
+    memcpy(&name.sin_addr, hp->h_addr, (size_t)hp->h_length);
+    name.sin_family = (sa_family_t)AF_INET;
+    name.sin_port = (in_port_t)htons(port);
 
     return dgram_send_addr(name, dgram);
 }
 
 
-int dgram_recv(dgram, timeout, fromaddr)
-dgram_t *dgram;
-int timeout;
-struct sockaddr_in *fromaddr;
+ssize_t
+dgram_recv(
+    dgram_t *          dgram,
+    int                        timeout,
+    struct sockaddr_in *fromaddr)
 {
-    fd_set ready;
+    SELECT_ARG_TYPE ready;
     struct timeval to;
     ssize_t size;
     int sock;
     socklen_t addrlen;
-    int nfound;
+    ssize_t nfound;
     int save_errno;
 
     sock = dgram->socket;
@@ -271,7 +330,11 @@ struct sockaddr_in *fromaddr;
     to.tv_sec = timeout;
     to.tv_usec = 0;
 
-    nfound = select(sock+1, (SELECT_ARG_TYPE *)&ready, NULL, NULL, &to);
+    dbprintf(("%s: dgram_recv(dgram=%p, timeout=%u, fromaddr=%p)\n",
+               debug_prefix_time(NULL), timeout, fromaddr));
+    dump_sockaddr(fromaddr);
+    
+    nfound = (ssize_t)select(sock+1, &ready, NULL, NULL, &to);
     if(nfound <= 0 || !FD_ISSET(sock, &ready)) {
        save_errno = errno;
        if(nfound < 0) {
@@ -302,8 +365,8 @@ struct sockaddr_in *fromaddr;
        return nfound;
     }
 
-    addrlen = (socklen_t) sizeof(struct sockaddr_in);
-    size = recvfrom(sock, dgram->data, MAX_DGRAM, 0,
+    addrlen = (socklen_t)sizeof(struct sockaddr_in);
+    size = recvfrom(sock, dgram->data, (size_t)MAX_DGRAM, 0,
                    (struct sockaddr *)fromaddr, &addrlen);
     if(size == -1) {
        save_errno = errno;
@@ -313,49 +376,65 @@ struct sockaddr_in *fromaddr;
        errno = save_errno;
        return -1;
     }
-    dgram->len = size;
+    dgram->len = (size_t)size;
     dgram->data[size] = '\0';
     dgram->cur = dgram->data;
     return size;
 }
 
 
-void dgram_zero(dgram)
-dgram_t *dgram;
+void
+dgram_zero(
+    dgram_t *  dgram)
 {
     dgram->cur = dgram->data;
     dgram->len = 0;
     *(dgram->cur) = '\0';
 }
 
-printf_arglist_function1(void dgram_cat, dgram_t *, dgram, const char *, fmt)
+printf_arglist_function1(int dgram_cat, dgram_t *, dgram, const char *, fmt)
 {
-    size_t bufsize;
+    ssize_t bufsize;
     va_list argp;
+    int len;
 
     assert(dgram != NULL);
     assert(fmt != NULL);
 
-    assert(dgram->len == dgram->cur - dgram->data);
-    assert(dgram->len >= 0 && dgram->len < sizeof(dgram->data));
+    assert(dgram->len == (size_t)(dgram->cur - dgram->data));
+    assert(dgram->len < SIZEOF(dgram->data));
 
-    bufsize = sizeof(dgram->data) - dgram->len;
+    bufsize = (ssize_t)(sizeof(dgram->data) - dgram->len);
     if (bufsize <= 0)
-       return;
+       return -1;
 
     arglist_start(argp, fmt);
-    dgram->len += vsnprintf(dgram->cur, bufsize, fmt, argp);
-    dgram->cur = dgram->data + dgram->len;
+    len = vsnprintf(dgram->cur, (size_t)bufsize, fmt, argp);
     arglist_end(argp);
+    if((ssize_t)len > bufsize) {
+       dgram->len = sizeof(dgram->data);
+       dgram->cur = dgram->data + dgram->len;
+       return -1;
+    }
+    else {
+       arglist_start(argp, fmt);
+       dgram->len += vsnprintf(dgram->cur, (size_t)bufsize, fmt, argp);
+       arglist_end(argp);
+       dgram->cur = dgram->data + dgram->len;
+    }
+    return 0;
 }
 
-void dgram_eatline(dgram)
-dgram_t *dgram;
+void
+dgram_eatline(
+    dgram_t *  dgram)
 {
     char *p = dgram->cur;
     char *end = dgram->data + dgram->len;
 
-    while(p < end && *p && *p != '\n') p++;
-    if(*p == '\n') p++;
+    while(p < end && *p && *p != '\n')
+       p++;
+    if(*p == '\n')
+       p++;
     dgram->cur = p;
 }
index 01edece2089ac2143c3e7e0cd11550176c461aff..dbacc9f4b869fd73f1b2a077409468dee39c32b4 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: dgram.h,v 1.13 2001/07/13 22:38:05 jrjackson Exp $
+ * $Id: dgram.h,v 1.15 2006/05/25 01:47:11 johnfranks Exp $
  *
  * interface for datagram module
  */
 typedef struct dgram_s {
     char *cur;
     int socket;
-    int len;
+    size_t len;
     char data[MAX_DGRAM+1];
 } dgram_t;
 
-int dgram_bind P((dgram_t *dgram, int *portp));
-void dgram_socket P((dgram_t *dgram, int sock));
-int dgram_send P((char *hostname, int port, dgram_t *dgram));
-int dgram_send_addr P((struct sockaddr_in addr, dgram_t *dgram));
-int dgram_recv P((dgram_t *dgram, int timeout, struct sockaddr_in *fromaddr));
-void dgram_zero P((dgram_t *dgram));
-void dgram_cat P((dgram_t *dgram, const char *fmt, ...))
+int    dgram_bind(dgram_t *dgram, in_port_t *portp);
+void   dgram_socket(dgram_t *dgram, int sock);
+int    dgram_send(char *hostname, in_port_t port, dgram_t *dgram);
+int    dgram_send_addr(struct sockaddr_in addr, dgram_t *dgram);
+ssize_t        dgram_recv(dgram_t *dgram, int timeout, struct sockaddr_in *fromaddr);
+void   dgram_zero(dgram_t *dgram);
+int    dgram_cat(dgram_t *dgram, const char *fmt, ...)
     __attribute__ ((format (printf, 2, 3)));
-void dgram_eatline P((dgram_t *dgram));
+void dgram_eatline(dgram_t *dgram);
 
 #endif /* ! DGRAM_H */
index 1b6f9478a02e663daa1a2699d1cd6226b3aee251..ade2e40bc53392c16ebf4444e4f0214bbce5e959 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: error.c,v 1.18 2003/04/27 01:17:19 martinea Exp $
+ * $Id: error.c,v 1.19 2006/05/25 01:47:11 johnfranks Exp $
  *
  * error handling common to Amanda programs
  */
@@ -34,7 +34,7 @@
 
 #define MAXFUNCS 8
 
-typedef void (*voidfunc) P((void));
+typedef void (*voidfunc)(void);
 static voidfunc onerr[MAXFUNCS] = 
     { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 
@@ -42,28 +42,34 @@ int erroutput_type = ERR_INTERACTIVE;
 
 static char *pname = "unknown";
 
-static void (*logerror) P((char *)) = NULL;
+static void output_error_message(char *msg);
 
-void set_pname(p)
-char *p;
+static void (*logerror)(char *) = NULL;
+
+void
+set_pname(
+    char *     p)
 {
     pname = p;
 }
 
-char *get_pname()
+char *
+get_pname(void)
 {
     return pname;
 }
 
-void set_logerror(f)
-void (*f) P((char *));
+void
+set_logerror(
+    void (*f)(char *))
 {
     logerror = f;
 }
 
 
-static void output_error_message(msg)
-char *msg;
+static void
+output_error_message(
+    char *     msg)
 {
     /* print and/or log message */
 
@@ -75,7 +81,7 @@ char *msg;
 #ifdef LOG_AUTH
        openlog(get_pname(), LOG_PID, LOG_AUTH);
 #else
-       openlog(get_pname(), LOG_PID);
+       openlog(get_pname(), LOG_PID, 0);
 #endif
        syslog(LOG_NOTICE, "%s", msg);
        closelog();
@@ -107,7 +113,7 @@ printf_arglist_function(void error, const char *, format)
     /* format and output the error message */
 
     arglist_start(argp, format);
-    vsnprintf(linebuf, sizeof(linebuf), format, argp);
+    vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
     arglist_end(argp);
     output_error_message(linebuf);
 
@@ -135,7 +141,7 @@ printf_arglist_function(void errordump, const char *, format)
     /* format error message */
 
     arglist_start(argp, format);
-    vsnprintf(linebuf, sizeof(linebuf), format, argp);
+    vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
     arglist_end(argp);
     output_error_message(linebuf);
 
@@ -150,8 +156,6 @@ printf_arglist_function(void errordump, const char *, format)
 }
 
 
-int onerror(errf)
-void (*errf) P((void));
 /*
  * Register function to be called when error is called.  Up to MAXFUNCS
  * functions can be registered.  If there isn't room in the table, onerror
@@ -160,6 +164,10 @@ void (*errf) P((void));
  * The resemblance to atexit() is on purpose.  I wouldn't need onerror()
  * if everyone had atexit().  Bummer.
  */
+
+int
+onerror(
+    void       (*errf)(void))
 {
     int i;
 
index 6809ca117c3c61c1f9a364014d72dfce42ea417e..4ebdfef3c44092c2fe512679c253b770d2ed0c14 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: event.c,v 1.20 2005/10/02 15:31:07 martinea Exp $
+ * $Id: event.c,v 1.24 2006/06/16 10:55:05 martinea Exp $
  *
  * Event handler.  Serializes different kinds of events to allow for
  * a uniform interface, central state storage, and centralized
@@ -86,53 +86,52 @@ static struct {
 static struct sigtabent {
     event_handle_t *handle;    /* handle for this signal */
     int score;                 /* number of signals recvd since last checked */
-    void (*oldhandler) P((int));/* old handler (for unsetting) */
+    void (*oldhandler)(int);/* old handler (for unsetting) */
 } sigtable[NSIG];
 
 #ifdef EVENT_DEBUG
-static const char *event_type2str P((event_type_t));
+static const char *event_type2str(event_type_t);
 #endif
 #define        fire(eh)        (*(eh)->fn)((eh)->arg)
-static void signal_handler P((int));
-static event_handle_t *gethandle P((void));
-static void puthandle P((event_handle_t *));
+static void signal_handler(int);
+static event_handle_t *gethandle(void);
+static void puthandle(event_handle_t *);
+static int event_loop_wait (event_handle_t *, const int);
 
 /*
  * Add a new event.  See the comment in event.h for what the arguments
  * mean.
  */
 event_handle_t *
-event_register(data, type, fn, arg)
-    event_id_t data;
-    event_type_t type;
-    event_fn_t fn;
-    void *arg;
+event_register(
+    event_id_t data,
+    event_type_t type,
+    event_fn_t fn,
+    void *arg)
 {
     event_handle_t *handle;
 
-    switch (type) {
-    case EV_READFD:
-    case EV_WRITEFD:
+    if ((type == EV_READFD) || (type == EV_WRITEFD)) {
        /* make sure we aren't given a high fd that will overflow a fd_set */
-       assert(data < FD_SETSIZE);
-       break;
-
-    case EV_SIG:
+       if (data >= FD_SETSIZE) {
+           error("event_register: Invalid file descriptor %d", data);
+           /*NOTREACHED*/
+       }
+#if !defined(__lint) /* Global checking knows that these are never called */
+    } else if (type == EV_SIG) {
        /* make sure signals are within range */
-       assert(data < NSIG);
-       /* make sure we don't double-register a signal */
-       assert(sigtable[data].handle == NULL);
-       break;
-
-    case EV_TIME:
-    case EV_WAIT:
-       break;
-
-    case EV_DEAD:
-    default:
-       /* callers can't register EV_DEAD */
-       assert(0);
-       break;
+       if (data >= NSIG) {
+           error("event_register: Invalid signal %d", data);
+           /*NOTREACHED*/
+       }
+       if (sigtable[data].handle != NULL) { 
+           error("event_register: signal %d already registered", data);
+           /*NOTREACHED*/
+       }
+    } else if (type >= EV_DEAD) {
+       error("event_register: Invalid event type %d", type);
+       /*NOTREACHED*/
+#endif
     }
 
     handle = gethandle();
@@ -144,8 +143,9 @@ event_register(data, type, fn, arg)
     eventq_add(eventq, handle);
     eventq.qlength++;
 
-    eventprintf(("%s: event: register: %X data=%lu, type=%s\n", debug_prefix_time(NULL), (int)handle,
-                handle->data, event_type2str(handle->type)));
+    eventprintf(("%s: event: register: %p->data=%lu, type=%s\n",
+               debug_prefix_time(NULL), handle, handle->data,
+               event_type2str(handle->type)));
     return (handle);
 }
 
@@ -155,14 +155,15 @@ event_register(data, type, fn, arg)
  * the event.
  */
 void
-event_release(handle)
-    event_handle_t *handle;
+event_release(
+    event_handle_t *handle)
 {
 
     assert(handle != NULL);
 
-    eventprintf(("%s: event: release (mark): %X data=%lu, type=%s\n", debug_prefix_time(NULL),
-       (int)handle, handle->data, event_type2str(handle->type)));
+    eventprintf(("%s: event: release (mark): %p data=%lu, type=%s\n",
+                debug_prefix_time(NULL), handle, handle->data,
+                event_type2str(handle->type)));
     assert(handle->type != EV_DEAD);
 
     /*
@@ -173,7 +174,7 @@ event_release(handle)
        struct sigtabent *se = &sigtable[handle->data];
 
        assert(se->handle == handle);
-       signal(handle->data, se->oldhandler);
+       signal((int)handle->data, se->oldhandler);
        se->handle = NULL;
        se->score = 0;
     }
@@ -194,20 +195,20 @@ event_release(handle)
  * Fire all EV_WAIT events waiting on the specified id.
  */
 int
-event_wakeup(id)
-    event_id_t id;
+event_wakeup(
+    event_id_t id)
 {
     event_handle_t *eh;
     int nwaken = 0;
 
-    eventprintf(("%s: event: wakeup: enter (%lu)\n", debug_prefix_time(NULL), id));
-
-    assert(id >= 0);
+    eventprintf(("%s: event: wakeup: enter (%lu)\n",
+                debug_prefix_time(NULL), id));
 
     for (eh = eventq_first(eventq); eh != NULL; eh = eventq_next(eh)) {
 
        if (eh->type == EV_WAIT && eh->data == id) {
-           eventprintf(("%s: event: wakeup: %X id=%lu\n", debug_prefix_time(NULL), (int)eh, id));
+           eventprintf(("%s: event: wakeup: %p id=%lu\n",
+                        debug_prefix_time(NULL), eh, id));
            fire(eh);
            nwaken++;
        }
@@ -222,27 +223,53 @@ event_wakeup(id)
  * we need to make sure we don't end up referencing a dead event handle.
  */
 void
-event_loop(dontblock)
-    const int dontblock;
+event_loop(
+    const int dontblock)
+{
+    event_loop_wait((event_handle_t *)NULL, dontblock);
+}
+
+
+
+int
+event_wait(
+    event_handle_t *eh)
+{
+    return event_loop_wait(eh, 0);
+}
+
+/*
+ * The event loop.  We need to be specially careful here with adds and
+ * deletes.  Since adds and deletes will often happen while this is running,
+ * we need to make sure we don't end up referencing a dead event handle.
+ */
+static int
+event_loop_wait(
+    event_handle_t *wait_eh,
+    const int       dontblock)
 {
 #ifdef ASSERTIONS
     static int entry = 0;
 #endif
     fd_set readfds, writefds, errfds, werrfds;
     struct timeval timeout, *tvptr;
-    int ntries, maxfd, rc, interval;
+    int ntries, maxfd, rc;
+    long interval;
     time_t curtime;
     event_handle_t *eh, *nexteh;
     struct sigtabent *se;
+    int event_wait_fired = 0;
+    int see_event;
 
-    eventprintf(("%s: event: loop: enter: dontblock=%d, qlength=%d\n", debug_prefix_time(NULL),
-                dontblock, eventq.qlength));
+    eventprintf(("%s: event: loop: enter: dontblock=%d, qlength=%d, eh=%p\n",
+                debug_prefix_time(NULL),
+                dontblock, eventq.qlength, wait_eh));
 
     /*
      * If we have no events, we have nothing to do
      */
     if (eventq.qlength == 0)
-       return;
+       return 0;
 
     /*
      * We must not be entered twice
@@ -259,11 +286,14 @@ event_loop(dontblock)
 
     do {
 #ifdef EVENT_DEBUG
-       eventprintf(("%s: event: loop: dontblock=%d, qlength=%d\n", debug_prefix_time(NULL), dontblock,
-           eventq.qlength));
+       eventprintf(("%s: event: loop: dontblock=%d, qlength=%d eh=%p\n",
+                    debug_prefix_time(NULL), dontblock, eventq.qlength,
+                    wait_eh));
        for (eh = eventq_first(eventq); eh != NULL; eh = eventq_next(eh)) {
-           eventprintf(("%s: %X: %s data=%lu fn=0x%x arg=0x%x\n", debug_prefix_time(NULL), (int)eh,
-               event_type2str(eh->type), eh->data, (int)eh->fn, (int)eh->arg));
+           eventprintf(("%s: %p): %s data=%lu fn=%p arg=%p\n",
+                        debug_prefix_time(NULL), eh,
+                        event_type2str(eh->type), eh->data, eh->fn,
+                        eh->arg));
        }
 #endif
        /*
@@ -294,6 +324,7 @@ event_loop(dontblock)
        FD_ZERO(&errfds);
        maxfd = 0;
 
+       see_event = (wait_eh == (event_handle_t *)NULL);
        /*
         * Run through each event handle and setup the events.
         * We save our next pointer early in case we GC some dead
@@ -308,18 +339,20 @@ event_loop(dontblock)
             * Read fds just get set into the select bitmask
             */
            case EV_READFD:
-               FD_SET(eh->data, &readfds);
-               FD_SET(eh->data, &errfds);
-               maxfd = max(maxfd, eh->data);
+               FD_SET((int)eh->data, &readfds);
+               FD_SET((int)eh->data, &errfds);
+               maxfd = max(maxfd, (int)eh->data);
+               see_event |= (eh == wait_eh);
                break;
 
            /*
             * Likewise with write fds
             */
            case EV_WRITEFD:
-               FD_SET(eh->data, &writefds);
-               FD_SET(eh->data, &errfds);
-               maxfd = max(maxfd, eh->data);
+               FD_SET((int)eh->data, &writefds);
+               FD_SET((int)eh->data, &errfds);
+               maxfd = max(maxfd, (int)eh->data);
+               see_event |= (eh == wait_eh);
                break;
 
            /*
@@ -328,6 +361,7 @@ event_loop(dontblock)
             */
            case EV_SIG:
                se = &sigtable[eh->data];
+               see_event |= (eh == wait_eh);
 
                if (se->handle == eh)
                    break;
@@ -336,7 +370,9 @@ event_loop(dontblock)
                assert(se->handle == NULL);
                se->handle = eh;
                se->score = 0;
-               se->oldhandler = signal(eh->data, signal_handler);
+               /*@ignore@*/
+               se->oldhandler = signal((int)eh->data, signal_handler);
+               /*@end@*/
                break;
 
            /*
@@ -350,7 +386,7 @@ event_loop(dontblock)
                if (eh->lastfired == -1)
                    eh->lastfired = curtime;
 
-               interval = eh->data - (curtime - eh->lastfired);
+               interval = (long)(eh->data - (curtime - eh->lastfired));
                if (interval < 0)
                    interval = 0;
 
@@ -361,12 +397,14 @@ event_loop(dontblock)
                    tvptr = &timeout;
                    timeout.tv_sec = interval;
                }
+               see_event |= (eh == wait_eh);
                break;
 
            /*
             * Wait events are processed immediately by event_wakeup()
             */
            case EV_WAIT:
+               see_event |= (eh == wait_eh);
                break;
 
            /*
@@ -383,13 +421,21 @@ event_loop(dontblock)
            }
        }
 
+       if(!see_event) {
+           assert(--entry == 0);
+           return 0;
+       }
+
        /*
         * Let 'er rip
         */
-       eventprintf(("%s: event: select: dontblock=%d, maxfd=%d, timeout=%ld\n", debug_prefix_time(NULL),
-           dontblock, maxfd, tvptr != NULL ? timeout.tv_sec : -1));
+       eventprintf((
+                   "%s: event: select: dontblock=%d, maxfd=%d, timeout=%ld\n",
+                   debug_prefix_time(NULL), dontblock, maxfd,
+                   tvptr != NULL ? timeout.tv_sec : -1));
        rc = select(maxfd + 1, &readfds, &writefds, &errfds, tvptr);
-       eventprintf(("%s: event: select returns %d\n", debug_prefix_time(NULL), rc));
+       eventprintf(("%s: event: select returns %d\n",
+                    debug_prefix_time(NULL), rc));
 
        /*
         * Select errors can mean many things.  Interrupted events should
@@ -398,8 +444,10 @@ event_loop(dontblock)
         */
        if (rc < 0) {
            if (errno != EINTR) {
-               if (++ntries > 5)
+               if (++ntries > 5) {
                    error("select failed: %s", strerror(errno));
+                   /*NOTREACHED*/
+               }
                continue;
            }
            /* proceed if errno == EINTR, we may have caught a signal */
@@ -420,24 +468,26 @@ event_loop(dontblock)
         * that are being polled for both reading and writing have
         * both of their poll events 'see' the error.
         */
-       memcpy(&werrfds, &errfds, sizeof(werrfds));
+       memcpy(&werrfds, &errfds, SIZEOF(werrfds));
 
        /*
         * Now run through the events and fire the ones that are ready.
         * Don't handle file descriptor events if the select failed.
         */
        for (eh = eventq_first(eventq); eh != NULL; eh = eventq_next(eh)) {
+
            switch (eh->type) {
 
            /*
             * Read fds: just fire the event if set in the bitmask
             */
            case EV_READFD:
-               if (FD_ISSET(eh->data, &readfds) ||
-                   FD_ISSET(eh->data, &errfds)) {
-                   FD_CLR(eh->data, &readfds);
-                   FD_CLR(eh->data, &errfds);
+               if (FD_ISSET((int)eh->data, &readfds) ||
+                   FD_ISSET((int)eh->data, &errfds)) {
+                   FD_CLR((int)eh->data, &readfds);
+                   FD_CLR((int)eh->data, &errfds);
                    fire(eh);
+                   if(eh == wait_eh) event_wait_fired = 1;
                }
                break;
 
@@ -445,11 +495,12 @@ event_loop(dontblock)
             * Write fds: same as Read fds
             */
            case EV_WRITEFD:
-               if (FD_ISSET(eh->data, &writefds) ||
-                   FD_ISSET(eh->data, &werrfds)) {
-                   FD_CLR(eh->data, &writefds);
-                   FD_CLR(eh->data, &werrfds);
+               if (FD_ISSET((int)eh->data, &writefds) ||
+                   FD_ISSET((int)eh->data, &werrfds)) {
+                   FD_CLR((int)eh->data, &writefds);
+                   FD_CLR((int)eh->data, &werrfds);
                    fire(eh);
+                   if(eh == wait_eh) event_wait_fired = 1;
                }
                break;
 
@@ -463,6 +514,7 @@ event_loop(dontblock)
                    assert(se->handle == eh);
                    se->score = 0;
                    fire(eh);
+                   if(eh == wait_eh) event_wait_fired = 1;
                }
                break;
 
@@ -473,9 +525,10 @@ event_loop(dontblock)
            case EV_TIME:
                if (eh->lastfired == -1)
                    eh->lastfired = curtime;
-               if (curtime - eh->lastfired >= eh->data) {
+               if ((curtime - eh->lastfired) >= (time_t)eh->data) {
                    eh->lastfired = curtime;
                    fire(eh);
+                   if(eh == wait_eh) event_wait_fired = 1;
                }
                break;
 
@@ -492,9 +545,11 @@ event_loop(dontblock)
                break;
            }
        }
-    } while (!dontblock && eventq.qlength > 0);
+    } while (!dontblock && eventq.qlength > 0 && event_wait_fired == 0);
 
     assert(--entry == 0);
+    
+    return (event_wait_fired == 1);
 }
 
 /*
@@ -502,11 +557,11 @@ event_loop(dontblock)
  * loop.
  */
 static void
-signal_handler(signo)
-    int signo;
+signal_handler(
+    int        signo)
 {
 
-    assert(signo >= 0 && signo < sizeof(sigtable) / sizeof(sigtable[0]));
+    assert((signo >= 0) && ((size_t)signo < (size_t)(sizeof(sigtable) / sizeof(sigtable[0]))));
     sigtable[signo].score++;
 }
 
@@ -515,7 +570,7 @@ signal_handler(signo)
  * alloc a new one.
  */
 static event_handle_t *
-gethandle()
+gethandle(void)
 {
     event_handle_t *eh;
 
@@ -526,7 +581,7 @@ gethandle()
        return (eh);
     }
     assert(cache.qlength == 0);
-    return (alloc(sizeof(*eh)));
+    return (alloc(SIZEOF(*eh)));
 }
 
 /*
@@ -534,8 +589,8 @@ gethandle()
  * Otherwise, free it.
  */
 static void
-puthandle(eh)
-    event_handle_t *eh;
+puthandle(
+    event_handle_t *eh)
 {
 
     if (cache.qlength > CACHEDEPTH) {
@@ -551,8 +606,8 @@ puthandle(eh)
  * Convert an event type into a string
  */
 static const char *
-event_type2str(type)
-    event_type_t type;
+event_type2str(
+    event_type_t type)
 {
     static const struct {
        event_type_t type;
@@ -567,9 +622,9 @@ event_type2str(type)
        X(EV_DEAD),
 #undef X
     };
-    int i;
+    size_t i;
 
-    for (i = 0; i < sizeof(event_types) / sizeof(event_types[0]); i++)
+    for (i = 0; i < (size_t)(sizeof(event_types) / sizeof(event_types[0])); i++)
        if (type == event_types[i].type)
            return (event_types[i].name);
     return ("BOGUS EVENT TYPE");
index 367f3b513e04085fdd87f869bba6b08066079511..be64f8931e26733d712691ea881f641987ce9e44 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: event.h,v 1.6 2005/11/30 22:35:11 martinea Exp $
+ * $Id: event.h,v 1.9 2006/06/16 10:55:05 martinea Exp $
  */
 #ifndef EVENT_H
 #define EVENT_H
@@ -66,7 +66,7 @@ typedef enum {
  * The function signature for functions that get called when an event
  * fires.
  */
-typedef void (*event_fn_t) P((void *));
+typedef void (*event_fn_t)(void *);
 
 /*
  * Register an event handler.
@@ -82,23 +82,27 @@ typedef void (*event_fn_t) P((void *));
  * count on the time events being too accurate.  They depend on the
  * caller calling event_loop() often enough.
  */
-event_handle_t *event_register P((event_id_t, event_type_t,
-    event_fn_t, void *));
+event_handle_t *event_register(event_id_t, event_type_t, event_fn_t, void *);
 
 /*
  * Release an event handler.
  */
-void event_release P((event_handle_t *));
+void event_release(event_handle_t *);
 
 /*
  * Wake up all EV_WAIT events waiting on a specific id
  */
-int event_wakeup P((event_id_t));
+int event_wakeup(event_id_t);
+
+/*
+ * Block until the event is terminated.
+ */
+int event_wait(event_handle_t *);
 
 /*
  * Process events.  If the argument is nonzero, then the loop does
  * not block.
  */
-void event_loop P((const int));
+void event_loop(const int);
 
 #endif /* EVENT_H */
index ce4d28bd6695362e4426fd9acc5e9c32663dbfd6..a03197e2793cae42613368103f79bf9485a98cfa 100644 (file)
@@ -23,7 +23,7 @@
  * Author: AMANDA core development group.
  */
 /*
- * $Id: file.c,v 1.35 2006/03/09 16:51:41 martinea Exp $
+ * $Id: file.c,v 1.40 2006/07/19 17:41:15 martinea Exp $
  *
  * file and directory bashing routines
  */
@@ -31,7 +31,9 @@
 #include "amanda.h"
 #include "util.h"
 
-static int mk1dir P((const char *, int, uid_t, gid_t));
+void amanda_setup(int argc, char **argv, int setup_flags);
+static int mk1dir(const char *, mode_t, uid_t, gid_t);
+static void areads_getbuf(const char *s, int l, int fd);
 
 uid_t client_uid = (uid_t) -1;
 gid_t client_gid = (gid_t) -1;
@@ -42,24 +44,25 @@ gid_t client_gid = (gid_t) -1;
 **       it will do nothing - only root is permitted to change the owner
 **       of a file.
 */
-static int mk1dir(dir, mode, uid, gid)
-const char *dir; /* directory to create */
-int mode;      /* mode for new directory */
-uid_t uid;     /* uid for new directory */
-gid_t gid;     /* gid for new directory */
+static int
+mk1dir(
+    const char *dir, /* directory to create */
+    mode_t     mode,   /* mode for new directory */
+    uid_t      uid,    /* uid for new directory */
+    gid_t      gid)    /* gid for new directory */
 {
     int rc;    /* return code */
 
-    rc = 0;    /* assume the best */
-
-    if(mkdir(dir, mode) == 0) {
-       chmod(dir, mode);       /* mkdir() is affected by the umask */
-       chown(dir, uid, gid);   /* XXX - no-op on most systems? */
+    if((rc = mkdir(dir, mode)) == 0) {
+       if ((rc = chmod(dir, mode)) == 0) { /* mkdir() affected by the umask */
+           rc = chown(dir, uid, gid);
+       }
     } else {                   /* maybe someone beat us to it */
        int serrno;
 
        serrno = errno;
-       if(access(dir, F_OK) != 0) rc = -1;
+       if(access(dir, F_OK) != 0)
+           rc = -1;
        errno = serrno; /* pass back the real error */
     }
 
@@ -73,19 +76,20 @@ gid_t gid;  /* gid for new directory */
  * the last element, but not the last element.  So a (potential) file name
  * may be passed to mkpdir and all the parents of that file will be created.
  */
-int mkpdir(file, mode, uid, gid)
-char *file;    /* file to create parent directories for */
-int mode;      /* mode for new directories */
-uid_t uid;     /* uid for new directories */
-gid_t gid;     /* gid for new directories */
+int
+mkpdir(
+    char *     file,   /* file to create parent directories for */
+    mode_t     mode,   /* mode for new directories */
+    uid_t      uid,    /* uid for new directories */
+    gid_t      gid)    /* gid for new directories */
 {
-    char *dir = NULL, *p;
+    char *dir;
+    char *p;
     int rc;    /* return code */
 
     rc = 0;
 
     dir = stralloc(file);      /* make a copy we can play with */
-
     p = strrchr(dir, '/');
     if(p != dir && p != NULL) {        /* got a '/' or a simple name */
        *p = '\0';
@@ -107,12 +111,13 @@ gid_t gid;        /* gid for new directories */
 **  - stops deleting before topdir, ie: topdir will not be removed
 **  - if file is not under topdir this routine will not notice
 */
-int rmpdir(file, topdir)
-char *file;    /* directory hierarchy to remove */
-char *topdir;  /* where to stop removing */
+int
+rmpdir(
+    char *     file,   /* directory hierarchy to remove */
+    char *     topdir) /* where to stop removing */
 {
     int rc;
-    char *p, *dir = NULL;
+    char *p, *dir;
 
     if(strcmp(file, topdir) == 0) return 0; /* all done */
 
@@ -138,10 +143,10 @@ char *topdir;     /* where to stop removing */
     dir = stralloc(file);
 
     p = strrchr(dir, '/');
-    if(p == dir) rc = 0; /* no /'s */
-    else {
+    if (p == NULL || p == dir) {
+        rc = 0;
+    } else {
        *p = '\0';
-
        rc = rmpdir(dir, topdir);
     }
 
@@ -163,11 +168,14 @@ char *topdir;     /* where to stop removing */
  */
 
 void
-amanda_setup (argc, argv, setup_flags)
-    int                        argc;
-    char               **argv;
-    int                        setup_flags;
+amanda_setup (
+    int                argc,
+    char **    argv,
+    int                setup_flags)
 {
+    (void)argc;                /* Quiet unused parameter warning */
+    (void)argv;                /* Quiet unused parameter warning */
+    (void)setup_flags; /* Quiet unused parameter warning */
 }
 
 /*
@@ -197,7 +205,7 @@ amanda_setup (argc, argv, setup_flags)
  */
 
 void
-safe_cd()
+safe_cd(void)
 {
     int                        cd_ok = 0;
     struct stat                sbuf;
@@ -215,11 +223,11 @@ safe_cd()
     if (client_uid != (uid_t) -1) {
 #if defined(AMANDA_DBGDIR)
        d = stralloc2(AMANDA_DBGDIR, "/.");
-       (void) mkpdir(d, 02700, client_uid, client_gid);
+       (void) mkpdir(d, (mode_t)02700, client_uid, client_gid);
        amfree(d);
 #endif
        d = stralloc2(AMANDA_TMPDIR, "/.");
-       (void) mkpdir(d, 02700, client_uid, client_gid);
+       (void) mkpdir(d, (mode_t)02700, client_uid, client_gid);
        amfree(d);
     }
 
@@ -241,7 +249,9 @@ safe_cd()
     if(cd_ok) {
        save_core();                            /* save any old core file */
     } else {
-       (void) chdir("/");                      /* assume this works */
+       if ((cd_ok = chdir("/")) == -1) {
+           (void)cd_ok;        /* Quiet compiler warning if DEBUG disabled */
+       }
     }
 }
 
@@ -263,9 +273,9 @@ safe_cd()
  */
 
 void
-safe_fd(fd_start, fd_count)
-    int                        fd_start;
-    int                        fd_count;
+safe_fd(
+    int                fd_start,
+    int                fd_count)
 {
     int                        fd;
 
@@ -299,7 +309,6 @@ safe_fd(fd_start, fd_count)
            }
        }
     }
-
 }
 
 /*
@@ -324,7 +333,7 @@ safe_fd(fd_start, fd_count)
  */
 
 void
-save_core()
+save_core(void)
 {
     struct stat sbuf;
 
@@ -360,46 +369,32 @@ save_core()
 /*
 ** Sanitise a file name.
 ** 
-** Convert all funny characters to '_' so that we can use,
+** Convert all '/' characters to '_' so that we can use,
 ** for example, disk names as part of file names.
 ** Notes: 
 **  - there is a many-to-one mapping between input and output
-** XXX - We only look for '/' and ' ' at the moment.  May
-** XXX - be we should also do all unprintables.
+**  - Only / and '\0' are disallowed in filenames by POSIX...
 */
-char *sanitise_filename(inp)
-char *inp;
+char *
+sanitise_filename(
+    char *     inp)
 {
     char *buf;
-    int buf_size;
+    size_t buf_size;
     char *s, *d;
     int ch;
 
-    buf_size = 2 * strlen(inp) + 1;            /* worst case */
+    buf_size = strlen(inp) + 1;                /* worst case */
     buf = alloc(buf_size);
     d = buf;
     s = inp;
     while((ch = *s++) != '\0') {
-       if(ch == '_') {
-           if(d >= buf + buf_size) {
-               amfree(buf);
-               return NULL;                    /* cannot happen */
-           }
-           *d++ = '_';                         /* convert _ to __ to try */
-                                               /* and ensure unique output */
-       } else if(ch == '/' || isspace(ch)) {
+       if(ch == '/') {
            ch = '_';   /* convert "bad" to "_" */
        }
-       if(d >= buf + buf_size) {
-           amfree(buf);
-           return NULL;                        /* cannot happen */
-       }
-       *d++ = ch;
-    }
-    if(d >= buf + buf_size) {
-       amfree(buf);
-       return NULL;                            /* cannot happen */
+       *d++ = (char)ch;
     }
+    assert(d < buf + buf_size);
     *d = '\0';
 
     return buf;
@@ -409,84 +404,98 @@ char *inp;
  *=====================================================================
  * Get the next line of input from a stdio file.
  *
- * char *agets (FILE *f)
+ * char *agets (FILE *stream)
  *
- * entry:      f = stdio stream to read
- * exit:       returns a pointer to an alloc'd string or NULL at EOF
- *             or error (errno will be zero on EOF).
+ * entry:      stream  -  stream to read
+ * exit:       returns a pointer to an alloc'd string or NULL
+ *             at EOF or error.  The functions ferror(stream) and
+ *             feof(stream) should be checked by caller to determine
+ *             stream status.
  *
- * Notes:      the newline, if read, is removed from the string
+ * Notes:      the newline at the end of a line, if read, is removed from
+ *             the string. Quoted newlines are left intact.
  *             the caller is responsible for free'ing the string
+ *
  *=====================================================================
  */
 
+#define        AGETS_LINE_INCR 128
+
 char *
-debug_agets(s, l, file)
-    const char *s;
-    int l;
-    FILE *file;
+debug_agets(
+    const char *sourcefile,
+    int                lineno,
+    FILE *     stream)
 {
-    char *line = NULL, *line_ptr;
-    size_t line_size, size_save;
-    int line_free, line_len;
-    char *cp;
-    char *f;
-
-    malloc_enter(dbmalloc_caller_loc(s, l));
+    int        ch;
+    char *line = alloc(AGETS_LINE_INCR);
+    size_t line_size = 0;
+    size_t loffset = 0;
+    int        inquote = 0;
+    int        escape = 0;
+
+    (void)sourcefile;  /* Quiet unused parameter warning if not debugging */
+    (void)lineno;      /* Quiet unused parameter warning if not debugging */
+
+    while ((ch = fgetc(stream)) != EOF) {
+       if (ch == '\n') {
+           if (!inquote) {
+               if (escape) {
+                   escape = 0;
+                   loffset--;  /* Consume escape in buffer */
+                   continue;
+               }
+               /* Reached end of line so exit without passing on LF */
+               break;
+           }
+       }
 
-#define        AGETS_LINE_INCR 128
+       if (ch == '\\') {
+           escape = 1;
+       } else {
+           if (ch == '"') {
+               if (!escape) 
+                   inquote = !inquote;
+           }
+           escape = 0;
+       }
 
-    line_size = AGETS_LINE_INCR;
-    line = debug_alloc (s, l, line_size);
-    line_free = line_size;
-    line_ptr = line;
-    line_len = 0;
+       if ((loffset + 1) >= line_size) {
+           char *tmpline;
 
-    while ((f = fgets(line_ptr, line_free, file)) != NULL) {
-       /*
-        * Note that we only have to search what we just read, not
-        * the whole buffer.
-        */
-       if ((cp = strchr (line_ptr, '\n')) != NULL) {
-           line_len += cp - line_ptr;
-           *cp = '\0';                         /* zap the newline */
-           break;                              /* got to end of line */
-       }
-       line_len += line_free - 1;              /* bytes read minus '\0' */
-       size_save = line_size;
-       if (line_size < 256 * AGETS_LINE_INCR) {
-           line_size *= 2;
-       } else {
-           line_size += 256 * AGETS_LINE_INCR;
+           /*
+            * Reallocate input line.
+            * alloc() never return NULL pointer.
+            */
+           tmpline = alloc(line_size + AGETS_LINE_INCR);
+           memcpy(tmpline, line, line_size);
+           amfree(line);
+           line = tmpline;
+           line_size = line_size + AGETS_LINE_INCR;
        }
-       cp = debug_alloc (s, l, line_size);     /* get more space */
-       memcpy (cp, line, size_save);           /* copy old to new */
-       free (line);                            /* and release the old */
-       line = cp;
-       line_ptr = line + size_save - 1;        /* start at the null byte */
-       line_free = line_size - line_len;       /* and we get to use it */
+       line[loffset++] = (char)ch;
     }
+
+    if ((ch == EOF) && (loffset == 0)) {
+       amfree(line); /* amfree zeros line... */
+    } else {
+       line[loffset] = '\0';
+    }
+
     /*
-     * Return what we got even if there was not a newline.  Only
-     * report done (NULL) when no data was processed.
+     * Return what we got even if there was not a newline.
+     * Only report done (NULL) when no data was processed.
      */
-    if (f == NULL && line_len == 0) {
-       amfree (line);
-       line = NULL;                            /* redundant, but clear */
-       if(!ferror(file)) {
-           errno = 0;                          /* flag EOF vs error */
-       }
-    }
-    malloc_leave(dbmalloc_caller_loc(s, l));
     return line;
 }
 
+
 /*
  *=====================================================================
  * Find/create a buffer for a particular file descriptor for use with
  * areads().
  *
- * void areads_getbuf (const char *file, int line, int fd)
+ * void areads_getbuf (const char *file, size_t line, int fd)
  *
  * entry:      file, line = caller source location
  *             fd = file descriptor to look up
@@ -497,27 +506,27 @@ debug_agets(s, l, file)
 static struct areads_buffer {
     char *buffer;
     char *endptr;
-    ssize_t bufsize;
+    size_t bufsize;
 } *areads_buffer = NULL;
 static int areads_bufcount = 0;
-static ssize_t areads_bufsize = BUFSIZ;                /* for the test program */
+static size_t areads_bufsize = BUFSIZ;         /* for the test program */
 
 static void
-areads_getbuf(s, l, fd)
-    const char *s;
-    int l;
-    int fd;
+areads_getbuf(
+    const char *s,
+    int                l,
+    int                fd)
 {
     struct areads_buffer *new;
-    ssize_t size;
+    size_t size;
 
     assert(fd >= 0);
     if(fd >= areads_bufcount) {
-       size = (fd + 1) * sizeof(*areads_buffer);
+       size = (size_t)(fd + 1) * SIZEOF(*areads_buffer);
        new = (struct areads_buffer *) debug_alloc(s, l, size);
        memset((char *)new, 0, size);
        if(areads_buffer) {
-           size = areads_bufcount * sizeof(*areads_buffer);
+           size = areads_bufcount * SIZEOF(*areads_buffer);
            memcpy(new, areads_buffer, size);
        }
        amfree(areads_buffer);
@@ -545,8 +554,8 @@ areads_getbuf(s, l, fd)
  */
 
 ssize_t
-areads_dataready(fd)
-    int fd;
+areads_dataready(
+    int        fd)
 {
     ssize_t r = 0;
 
@@ -568,8 +577,8 @@ areads_dataready(fd)
  */
 
 void
-areads_relbuf(fd)
-    int fd;
+areads_relbuf(
+    int fd)
 {
     if(fd >= 0 && fd < areads_bufcount) {
        amfree(areads_buffer[fd].buffer);
@@ -594,18 +603,18 @@ areads_relbuf(fd)
  */
 
 char *
-debug_areads (s, l, fd)
-    const char *s;
-    int l;
-    int fd;
+debug_areads (
+    const char *s,
+    int                l,
+    int                fd)
 {
     char *nl;
     char *line;
     char *buffer;
     char *endptr;
     char *newbuf;
-    ssize_t buflen;
-    ssize_t size;
+    size_t buflen;
+    size_t size;
     ssize_t r;
 
     malloc_enter(dbmalloc_caller_loc(s, l));
@@ -617,7 +626,7 @@ debug_areads (s, l, fd)
     areads_getbuf(s, l, fd);
     buffer = areads_buffer[fd].buffer;
     endptr = areads_buffer[fd].endptr;
-    buflen = areads_buffer[fd].bufsize - (endptr - buffer);
+    buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer);
     while((nl = strchr(buffer, '\n')) == NULL) {
        /*
         * No newline yet, so get more data.
@@ -631,13 +640,12 @@ debug_areads (s, l, fd)
            newbuf = debug_alloc(s, l, size + 1);
            memcpy (newbuf, buffer, areads_buffer[fd].bufsize + 1);
            amfree(areads_buffer[fd].buffer);
-           buffer = NULL;
            areads_buffer[fd].buffer = newbuf;
            areads_buffer[fd].endptr = newbuf + areads_buffer[fd].bufsize;
            areads_buffer[fd].bufsize = size;
            buffer = areads_buffer[fd].buffer;
            endptr = areads_buffer[fd].endptr;
-           buflen = areads_buffer[fd].bufsize - (endptr - buffer);
+           buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer);
        }
        if ((r = read(fd, endptr, buflen)) <= 0) {
            if(r == 0) {
@@ -652,7 +660,7 @@ debug_areads (s, l, fd)
     }
     *nl++ = '\0';
     line = stralloc(buffer);
-    size = endptr - nl;                        /* data still left in buffer */
+    size = (size_t)(endptr - nl);      /* data still left in buffer */
     memmove(buffer, nl, size);
     areads_buffer[fd].endptr = buffer + size;
     areads_buffer[fd].endptr[0] = '\0';
@@ -662,9 +670,10 @@ debug_areads (s, l, fd)
 
 #ifdef TEST
 
-int main(argc, argv)
-       int argc;
-       char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
        int rc;
        int fd;
@@ -677,6 +686,8 @@ int main(argc, argv)
 
        set_pname("file test");
 
+       dbopen(NULL);
+
        /* Don't die when child closes pipe */
        signal(SIGPIPE, SIG_IGN);
 
@@ -694,7 +705,7 @@ int main(argc, argv)
        }
 
        fprintf(stderr, "Create parent directories of %s ...", name);
-       rc = mkpdir(name, 02777, (uid_t)-1, (gid_t)-1);
+       rc = mkpdir(name, (mode_t)02777, (uid_t)-1, (gid_t)-1);
        if (rc == 0)
                fprintf(stderr, " done\n");
        else {
index ede34793e14dd587bbf95051c86b35d857dc1266..f6786a891cb128ee7ab5dbb01f9c94167ac30b2b 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: fileheader.c,v 1.34 2006/03/09 16:51:41 martinea Exp $
+ * $Id: fileheader.c,v 1.40 2006/07/01 00:10:38 paddy_s Exp $
  */
 
 #include "amanda.h"
 #include "fileheader.h"
 
-static const char *filetype2str P((filetype_t));
-static filetype_t str2filetype P((const char *));
+static const char *    filetype2str(filetype_t);
+static filetype_t      str2filetype(const char *);
+static void            strange_header(dumpfile_t *, const char *,
+                               size_t, const char *, const char *);
 
 void
-fh_init(file)
-    dumpfile_t *file;
+fh_init(
+    dumpfile_t *file)
 {
-    memset(file, '\0', sizeof(*file));
+    memset(file, '\0', SIZEOF(*file));
     file->blocksize = DISK_BLOCK_BYTES;
 }
 
+static void
+strange_header(
+    dumpfile_t *file,
+    const char *buffer,
+    size_t     buflen,
+    const char *expected,
+    const char *actual)
+{
+    if (actual == NULL)
+       actual = "<null>";
+    if (expected == NULL)
+       expected = "<null>";
+
+    fprintf(stderr, "%s: strange amanda header: \"%.*s\"\n", get_pname(),
+               (int)buflen, buffer);
+
+    fprintf(stderr, "%s: Expected: \"%s\"  Actual: \"%s\"\n", get_pname(),
+               expected, actual);
+
+    file->type = F_WEIRD;
+}
+
+
 void
-parse_file_header(buffer, file, buflen)
-    const char *buffer;
-    dumpfile_t *file;
-    size_t buflen;
+parse_file_header(
+    const char *buffer,
+    dumpfile_t *file,
+    size_t     buflen)
 {
-    char *buf, *line, *tok, *line1=NULL;
-    int lsize;
+    char *buf, *line, *tok, *line1;
+    size_t lsize;
+    char *uqname;
+    int in_quotes;
+
     /* put the buffer into a writable chunk of memory and nul-term it */
     buf = alloc(buflen + 1);
     memcpy(buf, buffer, buflen);
     buf[buflen] = '\0';
-
     fh_init(file); 
 
-    for(line=buf,lsize=0; *line != '\n' && lsize < buflen; line++) {lsize++;};
+    in_quotes = 0;
+    for (line = buf, lsize = 0; lsize < buflen; line++) {
+       if ((*line == '\n') && !in_quotes)
+           break;
+
+       if (*line == '"') {
+           in_quotes = !in_quotes;
+       } else if ((*line == '\\') && (*(line + 1) == '"')) {
+           line++;
+           lsize++;
+       }
+       lsize++;
+    }
     *line = '\0';
-    line1 = alloc(lsize+1);
-    strncpy(line1,buf,lsize);
+    line1 = alloc(lsize + 1);
+    strncpy(line1, buf, lsize);
     line1[lsize] = '\0';
     *line = '\n';
 
     tok = strtok(line1, " ");
-    if (tok == NULL)
-       goto weird_header;
+    if (tok == NULL) {
+        fprintf(stderr, "%s: Empty amanda header: buflen=" SIZE_T_FMT
+           " lsize=" SIZE_T_FMT "\n", get_pname(),
+           (SIZE_T_FMT_TYPE)buflen, 
+           (SIZE_T_FMT_TYPE)lsize);
+       hexdump(buffer, lsize);
+       strange_header(file, buffer, buflen, "<Non-empty line>", tok);
+       goto out;
+    }
+
     if (strcmp(tok, "NETDUMP:") != 0 && strcmp(tok, "AMANDA:") != 0) {
        amfree(buf);
        file->type = F_UNKNOWN;
@@ -74,91 +121,119 @@ parse_file_header(buffer, file, buflen)
     }
 
     tok = strtok(NULL, " ");
-    if (tok == NULL)
-       goto weird_header;
+    if (tok == NULL) {
+       strange_header(file, buffer, buflen, "<file type>", tok);
+       goto out;
+    }
     file->type = str2filetype(tok);
-
+    
     switch (file->type) {
     case F_TAPESTART:
        tok = strtok(NULL, " ");
-       if (tok == NULL || strcmp(tok, "DATE") != 0)
-           goto weird_header;
+       if ((tok == NULL) || (strcmp(tok, "DATE") != 0)) {
+           strange_header(file, buffer, buflen, "DATE", tok);
+           goto out;
+       }
 
        tok = strtok(NULL, " ");
-       if (tok == NULL)
-           goto weird_header;
-       strncpy(file->datestamp, tok, sizeof(file->datestamp) - 1);
+       if (tok == NULL) {
+           strange_header(file, buffer, buflen, "<date stamp>", tok);
+           goto out;
+       }
+       strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);
 
        tok = strtok(NULL, " ");
-       if (tok == NULL || strcmp(tok, "TAPE") != 0)
-           goto weird_header;
+       if ((tok == NULL) || (strcmp(tok, "TAPE") != 0)) {
+           strange_header(file, buffer, buflen, "TAPE", tok);
+           goto out;
+       }
 
        tok = strtok(NULL, " ");
-       if (tok == NULL)
-           goto weird_header;
-       strncpy(file->name, tok, sizeof(file->name) - 1);
+       if (tok == NULL) {
+           strange_header(file, buffer, buflen, "<file type>", tok);
+           goto out;
+       }
+       strncpy(file->name, tok, SIZEOF(file->name) - 1);
        break;
 
     case F_DUMPFILE:
     case F_CONT_DUMPFILE:
     case F_SPLIT_DUMPFILE:
        tok = strtok(NULL, " ");
-       if (tok == NULL)
-           goto weird_header;
-       strncpy(file->datestamp, tok, sizeof(file->datestamp) - 1);
+       if (tok == NULL) {
+           strange_header(file, buffer, buflen, "<date stamp>", tok);
+           goto out;
+       }
+       strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);
 
        tok = strtok(NULL, " ");
-       if (tok == NULL)
-           goto weird_header;
-       strncpy(file->name, tok, sizeof(file->name) - 1);
+       if (tok == NULL) {
+           strange_header(file, buffer, buflen, "<file name>", tok);
+           goto out;
+       }
+       strncpy(file->name, tok, SIZEOF(file->name) - 1);
 
-       tok = strtok(NULL, " ");
-       if (tok == NULL)
-           goto weird_header;
-       strncpy(file->disk, tok, sizeof(file->disk) - 1);
+       tok = strquotedstr();
+       if (tok == NULL) {
+           strange_header(file, buffer, buflen, "<disk name>", tok);
+           goto out;
+       }
+       uqname = unquote_string(tok);
+       strncpy(file->disk, uqname, SIZEOF(file->disk) - 1);
+       amfree(uqname);
        
-       if(file->type == F_SPLIT_DUMPFILE){
+       if(file->type == F_SPLIT_DUMPFILE) {
            tok = strtok(NULL, " ");
-           if (tok == NULL || strcmp(tok, "part") != 0)
-               goto weird_header;
+           if (tok == NULL || strcmp(tok, "part") != 0) {
+               strange_header(file, buffer, buflen, "part", tok);
+               goto out;
+           }
 
            tok = strtok(NULL, "/");
-           if (tok == NULL || sscanf(tok, "%d", &file->partnum) != 1)
-               goto weird_header;
+           if ((tok == NULL) || (sscanf(tok, "%d", &file->partnum) != 1)) {
+               strange_header(file, buffer, buflen, "<part num param>", tok);
+               goto out;
+           }
 
-           tok = strtok(NULL, " ");
-           if (tok == NULL)
-               goto weird_header;
            /* If totalparts == -1, then the original dump was done in 
               streaming mode (no holding disk), thus we don't know how 
                many parts there are. */
-            if(sscanf(tok, "%d", &file->totalparts) != 1){
-               goto weird_header;
+           tok = strtok(NULL, " ");
+            if((tok == NULL) || (sscanf(tok, "%d", &file->totalparts) != 1)) {
+               strange_header(file, buffer, buflen, "<total parts param>", tok);
+               goto out;
            }
        }
-       
 
        tok = strtok(NULL, " ");
-       if (tok == NULL || strcmp(tok, "lev") != 0)
-           goto weird_header;
+       if ((tok == NULL) || (strcmp(tok, "lev") != 0)) {
+           strange_header(file, buffer, buflen, "lev", tok);
+           goto out;
+       }
 
        tok = strtok(NULL, " ");
-       if (tok == NULL || sscanf(tok, "%d", &file->dumplevel) != 1)
-           goto weird_header;
+       if ((tok == NULL) || (sscanf(tok, "%d", &file->dumplevel) != 1)) {
+           strange_header(file, buffer, buflen, "<dump level param>", tok);
+           goto out;
+       }
 
        tok = strtok(NULL, " ");
-       if (tok == NULL || strcmp(tok, "comp") != 0)
-           goto weird_header;
+       if ((tok == NULL) || (strcmp(tok, "comp") != 0)) {
+           strange_header(file, buffer, buflen, "comp", tok);
+           goto out;
+       }
 
        tok = strtok(NULL, " ");
-       if (tok == NULL)
-           goto weird_header;
-       strncpy(file->comp_suffix, tok, sizeof(file->comp_suffix) - 1);
+       if (tok == NULL) {
+           strange_header(file, buffer, buflen, "<comp param>", tok);
+           goto out;
+       }
+       strncpy(file->comp_suffix, tok, SIZEOF(file->comp_suffix) - 1);
 
        file->compressed = strcmp(file->comp_suffix, "N");
        /* compatibility with pre-2.2 amanda */
        if (strcmp(file->comp_suffix, "C") == 0)
-           strncpy(file->comp_suffix, ".Z", sizeof(file->comp_suffix) - 1);
+           strncpy(file->comp_suffix, ".Z", SIZEOF(file->comp_suffix) - 1);
               
        tok = strtok(NULL, " ");
         /* "program" is optional */
@@ -169,22 +244,26 @@ parse_file_header(buffer, file, buflen)
        }
 
         tok = strtok(NULL, " ");
-        if (tok == NULL)
-            goto weird_header;
-        strncpy(file->program, tok, sizeof(file->program) - 1);
+        if (tok == NULL) {
+           strange_header(file, buffer, buflen, "<program name>", tok);
+           goto out;
+       }
+        strncpy(file->program, tok, SIZEOF(file->program) - 1);
         if (file->program[0] == '\0')
-            strncpy(file->program, "RESTORE", sizeof(file->program) - 1);
+            strncpy(file->program, "RESTORE", SIZEOF(file->program) - 1);
 
        if ((tok = strtok(NULL, " ")) == NULL)
-             break;          /* reach the end of the buf */
+             break;          /* reached the end of the buffer */
 
        /* "encryption" is optional */
        if (BSTRNCMP(tok, "crypt") == 0) {
            tok = strtok(NULL, " ");
-           if (tok == NULL)
-               goto weird_header;
+           if (tok == NULL) {
+               strange_header(file, buffer, buflen, "<crypt param>", tok);
+               goto out;
+           }
            strncpy(file->encrypt_suffix, tok,
-                   sizeof(file->encrypt_suffix) - 1);
+                   SIZEOF(file->encrypt_suffix) - 1);
            file->encrypted = BSTRNCMP(file->encrypt_suffix, "N");
            if ((tok = strtok(NULL, " ")) == NULL)
                break;
@@ -193,9 +272,12 @@ parse_file_header(buffer, file, buflen)
        /* "srvcompprog" is optional */
        if (BSTRNCMP(tok, "server_custom_compress") == 0) {
            tok = strtok(NULL, " ");
-           if (tok == NULL)
-               goto weird_header;
-           strncpy(file->srvcompprog, tok, sizeof(file->srvcompprog) - 1);
+           if (tok == NULL) {
+               strange_header(file, buffer, buflen,
+                               "<server custom compress param>", tok);
+               goto out;
+           }
+           strncpy(file->srvcompprog, tok, SIZEOF(file->srvcompprog) - 1);
            if ((tok = strtok(NULL, " ")) == NULL)
                break;      
        }
@@ -203,9 +285,12 @@ parse_file_header(buffer, file, buflen)
        /* "clntcompprog" is optional */
        if (BSTRNCMP(tok, "client_custom_compress") == 0) {
            tok = strtok(NULL, " ");
-           if (tok == NULL)
-               goto weird_header;
-           strncpy(file->clntcompprog, tok, sizeof(file->clntcompprog) - 1);
+           if (tok == NULL) {
+               strange_header(file, buffer, buflen,
+                               "<client custom compress param>", tok);
+               goto out;
+           }
+           strncpy(file->clntcompprog, tok, SIZEOF(file->clntcompprog) - 1);
            if ((tok = strtok(NULL, " ")) == NULL)
                break;
        }
@@ -213,9 +298,12 @@ parse_file_header(buffer, file, buflen)
        /* "srv_encrypt" is optional */
        if (BSTRNCMP(tok, "server_encrypt") == 0) {
            tok = strtok(NULL, " ");
-           if (tok == NULL)
-               goto weird_header;
-           strncpy(file->srv_encrypt, tok, sizeof(file->srv_encrypt) - 1);
+           if (tok == NULL) {
+               strange_header(file, buffer, buflen,
+                               "<server encrypt param>", tok);
+               goto out;
+           }
+           strncpy(file->srv_encrypt, tok, SIZEOF(file->srv_encrypt) - 1);
            if ((tok = strtok(NULL, " ")) == NULL) 
                break;
        }
@@ -223,9 +311,12 @@ parse_file_header(buffer, file, buflen)
        /* "clnt_encrypt" is optional */
        if (BSTRNCMP(tok, "client_encrypt") == 0) {
            tok = strtok(NULL, " ");
-           if (tok == NULL)
-               goto weird_header;
-           strncpy(file->clnt_encrypt, tok, sizeof(file->clnt_encrypt) - 1);
+           if (tok == NULL) {
+               strange_header(file, buffer, buflen,
+                               "<client encrypt param>", tok);
+               goto out;
+           }
+           strncpy(file->clnt_encrypt, tok, SIZEOF(file->clnt_encrypt) - 1);
            if ((tok = strtok(NULL, " ")) == NULL) 
                break;
        }
@@ -233,10 +324,13 @@ parse_file_header(buffer, file, buflen)
        /* "srv_decrypt_opt" is optional */
        if (BSTRNCMP(tok, "server_decrypt_option") == 0) {
            tok = strtok(NULL, " ");
-           if (tok == NULL)
-               goto weird_header;
+           if (tok == NULL) {
+               strange_header(file, buffer, buflen,
+                               "<server decrypt param>", tok);
+               goto out;
+           }
            strncpy(file->srv_decrypt_opt, tok,
-                   sizeof(file->srv_decrypt_opt) - 1);
+                   SIZEOF(file->srv_decrypt_opt) - 1);
            if ((tok = strtok(NULL, " ")) == NULL) 
                break;
        }
@@ -244,10 +338,13 @@ parse_file_header(buffer, file, buflen)
        /* "clnt_decrypt_opt" is optional */
        if (BSTRNCMP(tok, "client_decrypt_option") == 0) {
            tok = strtok(NULL, " ");
-           if (tok == NULL)
-               goto weird_header;
+           if (tok == NULL) {
+               strange_header(file, buffer, buflen,
+                               "<client decrypt param>", tok);
+               goto out;
+           }
            strncpy(file->clnt_decrypt_opt, tok,
-                   sizeof(file->clnt_decrypt_opt) - 1);
+                   SIZEOF(file->clnt_decrypt_opt) - 1);
            if ((tok = strtok(NULL, " ")) == NULL) 
                break;
        }
@@ -257,52 +354,61 @@ parse_file_header(buffer, file, buflen)
     case F_TAPEEND:
        tok = strtok(NULL, " ");
        /* DATE is optional */
-       if (tok == NULL || strcmp(tok, "DATE") != 0) {
-           amfree(buf);
-           amfree(line1);
-           return;
+       if (tok != NULL) {
+           if (strcmp(tok, "DATE") == 0) {
+               tok = strtok(NULL, " ");
+               if(tok == NULL)
+                   file->datestamp[0] = '\0';
+               else
+                   strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);
+           } else {
+               strange_header(file, buffer, buflen, "<DATE>", tok);
+          }
+       } else {
+           file->datestamp[0] = '\0';
        }
-       strncpy(file->datestamp, tok, sizeof(file->datestamp) - 1);
        break;
 
     default:
-       goto weird_header;
+       strange_header(file, buffer, buflen,
+               "TAPESTART|DUMPFILE|CONT_DUMPFILE|SPLIT_DUMPFILE|TAPEEND", tok);
+       goto out;
     }
 
-    line = strtok(buf, "\n"); /* this is the first line */
+    (void)strtok(buf, "\n"); /* this is the first line */
     /* iterate through the rest of the lines */
     while ((line = strtok(NULL, "\n")) != NULL) {
 #define SC "CONT_FILENAME="
-       if (strncmp(line, SC, sizeof(SC) - 1) == 0) {
-           line += sizeof(SC) - 1;
+       if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
+           line += SIZEOF(SC) - 1;
            strncpy(file->cont_filename, line,
-                   sizeof(file->cont_filename) - 1);
+                   SIZEOF(file->cont_filename) - 1);
                    continue;
        }
 #undef SC
 
 #define SC "PARTIAL="
-       if (strncmp(line, SC, sizeof(SC) - 1) == 0) {
-           line += sizeof(SC) - 1;
+       if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
+           line += SIZEOF(SC) - 1;
            file->is_partial = !strcasecmp(line, "yes");
            continue;
        }
 #undef SC
 
 #define SC "To restore, position tape at start of file and run:"
-       if (strncmp(line, SC, sizeof(SC) - 1) == 0)
+       if (strncmp(line, SC, SIZEOF(SC) - 1) == 0)
            continue;
 #undef SC
 
 #define SC "\tdd if=<tape> bs="
-       if (strncmp(line, SC, sizeof(SC) - 1) == 0) {
-           char *cmd1=NULL, *cmd2=NULL, *cmd3=NULL;
+       if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
+           char *cmd1, *cmd2, *cmd3=NULL;
 
            /* skip over dd command */
            if ((cmd1 = strchr(line, '|')) == NULL) {
 
                strncpy(file->recover_cmd, "BUG",
-                       sizeof(file->recover_cmd) - 1);
+                       SIZEOF(file->recover_cmd) - 1);
                continue;
            }
            *cmd1++ = '\0';
@@ -323,72 +429,174 @@ parse_file_header(buffer, file, buflen)
             * one   cmds: recover
             */
 
-           if (cmd3 == NULL) {
+           if ( cmd3 == NULL) {
              if (cmd2 == NULL) {
                strncpy(file->recover_cmd, cmd1,
-                       sizeof(file->recover_cmd) - 1);
+                       SIZEOF(file->recover_cmd) - 1);
              } else {
                snprintf(file->uncompress_cmd,
-                        sizeof(file->uncompress_cmd), "%s|", cmd1);
+                        SIZEOF(file->uncompress_cmd), "%s|", cmd1);
                strncpy(file->recover_cmd, cmd2,
-                       sizeof(file->recover_cmd) - 1);
+                       SIZEOF(file->recover_cmd) - 1);
              }
            } else {    /* cmd3 presents:  decrypt | uncompress | recover */
              snprintf(file->decrypt_cmd,
-                      sizeof(file->decrypt_cmd), "%s|", cmd1);
+                      SIZEOF(file->decrypt_cmd), "%s|", cmd1);
              snprintf(file->uncompress_cmd,
-                      sizeof(file->uncompress_cmd), "%s|", cmd2);
+                      SIZEOF(file->uncompress_cmd), "%s|", cmd2);
              strncpy(file->recover_cmd, cmd3,
-                     sizeof(file->recover_cmd) - 1);
+                     SIZEOF(file->recover_cmd) - 1);
            }
            continue;
        }
 #undef SC
        /* XXX complain about weird lines? */
     }
-    amfree(buf);
-    amfree(line1);
-    return;
 
-weird_header:
-    fprintf(stderr, "%s: strange amanda header: \"%.*s\"\n", get_pname(),
-       (int) buflen, buffer);
-    file->type = F_WEIRD;
+out:
     amfree(buf);
     amfree(line1);
 }
 
 void
-build_header(buffer, file, buflen)
-    char *buffer;
-    const dumpfile_t *file;
-    size_t buflen;
+dump_dumpfile_t(
+    const dumpfile_t *file)
+{
+       const char *pname = get_pname();
+
+       dbprintf(("%s: Contents of *(dumpfile_t *)%p:\n", pname, file));
+       dbprintf(("%s:     type             = %d (%s)\n", pname,
+                       file->type, filetype2str(file->type)));
+       dbprintf(("%s:     datestamp        = '%s'\n", pname,
+                       file->datestamp));
+       dbprintf(("%s:     dumplevel        = %d\n", pname, file->dumplevel));
+       dbprintf(("%s:     compressed       = %d\n", pname, file->compressed));
+       dbprintf(("%s:     encrypted        = %d\n", pname, file->encrypted));
+       dbprintf(("%s:     comp_suffix      = '%s'\n", pname,
+                       file->comp_suffix));
+       dbprintf(("%s:     encrypt_suffix   = '%s'\n", pname,
+                       file->encrypt_suffix));
+       dbprintf(("%s:     name             = '%s'\n", pname, file->name));
+       dbprintf(("%s:     disk             = '%s'\n", pname, file->disk));
+       dbprintf(("%s:     program          = '%s'\n", pname, file->program));
+       dbprintf(("%s:     srvcompprog      = '%s'\n", pname,
+                       file->srvcompprog));
+       dbprintf(("%s:     clntcompprog     = '%s'\n", pname,
+                       file->clntcompprog));
+       dbprintf(("%s:     srv_encrypt      = '%s'\n", pname,
+                       file->srv_encrypt));
+       dbprintf(("%s:     clnt_encrypt     = '%s'\n", pname,
+                       file->clnt_encrypt));
+       dbprintf(("%s:     recover_cmd      = '%s'\n", pname,
+                       file->recover_cmd));
+       dbprintf(("%s:     uncompress_cmd   = '%s'\n", pname,
+                       file->uncompress_cmd));
+       dbprintf(("%s:     encrypt_cmd      = '%s'\n", pname,
+                       file->encrypt_cmd));
+       dbprintf(("%s:     decrypt_cmd      = '%s'\n", pname,
+                       file->decrypt_cmd));
+       dbprintf(("%s:     srv_decrypt_opt  = '%s'\n", pname,
+                       file->srv_decrypt_opt));
+       dbprintf(("%s:     clnt_decrypt_opt = '%s'\n", pname,
+                       file->clnt_decrypt_opt));
+       dbprintf(("%s:     cont_filename    = '%s'\n", pname,
+                       file->cont_filename));
+       dbprintf(("%s:     is_partial       = %d\n", pname, file->is_partial));
+       dbprintf(("%s:     partnum          = %d\n", pname, file->partnum));
+       dbprintf(("%s:     totalparts       = %d\n", pname, file->totalparts));
+       dbprintf(("%s:     blocksize        = " SIZE_T_FMT "\n", pname,
+                       (SIZE_T_FMT_TYPE)file->blocksize));
+}
+
+static void
+validate_name(
+    const char *name)
+{
+       if (strlen(name) == 0) {
+           error("Invalid name '%s'\n", name);
+           /*NOTREACHED*/
+       }
+}
+
+static void
+validate_datestamp(
+    const char *datestamp)
+{
+       if (strcmp(datestamp, "X") == 0) {
+           return;
+       }
+
+       if ((strlen(datestamp) == 8) && match("^[0-9]{8}$", datestamp)) {
+           return;
+       }
+       if ((strlen(datestamp) == 14) && match("^[0-9]{14}$", datestamp)) {
+           return;
+       }
+       error("Invalid datestamp '%s'\n", datestamp);
+       /*NOTREACHED*/
+}
+
+static void
+validate_parts(
+    const int partnum,
+    const int totalparts)
+{
+       if (partnum < 1) {
+           error("Invalid partnum (%d)\n", partnum);
+           /*NOTREACHED*/
+       }
+
+       if (partnum > totalparts && totalparts >= 0) {
+           error("Invalid partnum (%d) > totalparts (%d)\n",
+                       partnum, totalparts);
+           /*NOTREACHED*/
+       }
+}
+
+void
+build_header(
+    char *             buffer,
+    const dumpfile_t * file,
+    size_t             buflen)
 {
     int n;
+    char *qname;
     char split_data[128] = "";
 
+    dbprintf(("%s: Building type %d (%s) header of size " SIZE_T_FMT " using:\n",
+               get_pname(), file->type, filetype2str(file->type),
+               (SIZE_T_FMT_TYPE)buflen));
+    dump_dumpfile_t(file);
+
     memset(buffer,'\0',buflen);
 
     switch (file->type) {
     case F_TAPESTART:
+       validate_name(file->name);
+       validate_datestamp(file->datestamp);
        snprintf(buffer, buflen,
            "AMANDA: TAPESTART DATE %s TAPE %s\n014\n",
            file->datestamp, file->name);
        break;
 
     case F_SPLIT_DUMPFILE:
-       snprintf(split_data, sizeof(split_data),
+       validate_parts(file->partnum, file->totalparts);
+       snprintf(split_data, SIZEOF(split_data),
                 " part %d/%d ", file->partnum, file->totalparts);
-    /* FALLTHROUGH */
+       /*FALLTHROUGH*/
        
     case F_CONT_DUMPFILE:
     case F_DUMPFILE :
+       validate_name(file->name);
+       validate_datestamp(file->datestamp);
+       qname = quote_string(file->disk);
         n = snprintf(buffer, buflen,
                      "AMANDA: %s %s %s %s %s lev %d comp %s program %s",
                         filetype2str(file->type),
-                        file->datestamp, file->name, file->disk,
+                        file->datestamp, file->name, qname,
                         split_data,
                         file->dumplevel, file->comp_suffix, file->program); 
+       amfree(qname);
        if ( n ) {
          buffer += n;
          buflen -= n;
@@ -461,22 +669,26 @@ build_header(buffer, file, buflen)
        buffer += n;
        buflen -= n;
 
-       /* \014 == ^L */
+       /* \014 == ^L == form feed */
        n = snprintf(buffer, buflen,
-           "\tdd if=<tape> bs=%ldk skip=1 |%s %s %s\n\014\n",
-           file->blocksize / 1024, file->decrypt_cmd, file->uncompress_cmd, file->recover_cmd);
-       buffer += n;
-       buflen -= n;
+           "\tdd if=<tape> bs=" SIZE_T_FMT "k skip=1 | %s %s %s\n\014\n",
+           (SIZE_T_FMT_TYPE)file->blocksize / 1024, file->decrypt_cmd,
+           file->uncompress_cmd, file->recover_cmd);
        break;
 
     case F_TAPEEND:
+       validate_datestamp(file->datestamp);
        snprintf(buffer, buflen, "AMANDA: TAPEEND DATE %s\n\014\n",
            file->datestamp);
        break;
 
     case F_UNKNOWN:
+    case F_EMPTY:
     case F_WEIRD:
-       break;
+    default:
+       error("Invalid header type: %d (%s)",
+               file->type, filetype2str(file->type));
+       /*NOTREACHED*/
     }
 }
 
@@ -484,27 +696,37 @@ build_header(buffer, file, buflen)
  * Prints the contents of the file structure.
  */
 void
-print_header(outf, file)
-    FILE *outf;
-    const dumpfile_t *file;
+print_header(
+    FILE *             outf,
+    const dumpfile_t * file)
 {
+    char *qdisk;
     char number[NUM_STR_SIZE*2];
+
     switch(file->type) {
+    case F_EMPTY:
+       fprintf(outf, "EMPTY file\n");
+       break;
+
     case F_UNKNOWN:
        fprintf(outf, "UNKNOWN file\n");
        break;
+
     case F_WEIRD:
        fprintf(outf, "WEIRD file\n");
        break;
+
     case F_TAPESTART:
        fprintf(outf, "start of tape: date %s label %s\n",
               file->datestamp, file->name);
        break;
+
     case F_DUMPFILE:
     case F_CONT_DUMPFILE:
+       qdisk = quote_string(file->disk);
        fprintf(outf, "%s: date %s host %s disk %s lev %d comp %s",
            filetype2str(file->type), file->datestamp, file->name,
-           file->disk, file->dumplevel, file->comp_suffix);
+           qdisk, file->dumplevel, file->comp_suffix);
        if (*file->program)
            fprintf(outf, " program %s",file->program);
        if (strcmp(file->encrypt_suffix, "enc") == 0)
@@ -522,14 +744,17 @@ print_header(outf, file)
        if (*file->clnt_decrypt_opt)
            fprintf(outf, " client_decrypt_option %s", file->clnt_decrypt_opt);
        fprintf(outf, "\n");
+       amfree(qdisk);
        break;
+
     case F_SPLIT_DUMPFILE:
         if(file->totalparts > 0){
-            snprintf(number, sizeof(number), "%d", file->totalparts);
+            snprintf(number, SIZEOF(number), "%d", file->totalparts);
         }   
-        else snprintf(number, sizeof(number), "UNKNOWN");
+        else snprintf(number, SIZEOF(number), "UNKNOWN");
+       qdisk = quote_string(file->disk);
         fprintf(outf, "split dumpfile: date %s host %s disk %s part %d/%s lev %d comp %s",
-                      file->datestamp, file->name, file->disk, file->partnum,
+                      file->datestamp, file->name, qdisk, file->partnum,
                       number, file->dumplevel, file->comp_suffix);
         if (*file->program)
             fprintf(outf, " program %s",file->program);
@@ -548,7 +773,9 @@ print_header(outf, file)
        if (*file->clnt_decrypt_opt)
            fprintf(outf, " client_decrypt_option %s", file->clnt_decrypt_opt);
         fprintf(outf, "\n");
+       amfree(qdisk);
         break;
+
     case F_TAPEEND:
        fprintf(outf, "end of tape: date %s\n", file->datestamp);
        break;
@@ -556,8 +783,8 @@ print_header(outf, file)
 }
 
 int
-known_compress_type(file)
-    const dumpfile_t *file;
+known_compress_type(
+    const dumpfile_t * file)
 {
     if(strcmp(file->comp_suffix, ".Z") == 0)
        return 1;
@@ -582,27 +809,27 @@ static const struct {
     { F_CONT_DUMPFILE, "CONT_FILE" },
     { F_SPLIT_DUMPFILE, "SPLIT_FILE" }
 };
-#define        NFILETYPES      (sizeof(filetypetab) / sizeof(filetypetab[0]))
+#define        NFILETYPES      (size_t)(sizeof(filetypetab) / sizeof(filetypetab[0]))
 
 static const char *
-filetype2str(type)
-    filetype_t type;
+filetype2str(
+    filetype_t type)
 {
     int i;
 
-    for (i = 0; i < NFILETYPES; i++)
+    for (i = 0; i < (int)NFILETYPES; i++)
        if (filetypetab[i].type == type)
            return (filetypetab[i].str);
     return ("UNKNOWN");
 }
 
 static filetype_t
-str2filetype(str)
-    const char *str;
+str2filetype(
+    const char *str)
 {
     int i;
 
-    for (i = 0; i < NFILETYPES; i++)
+    for (i = 0; i < (int)NFILETYPES; i++)
        if (strcmp(filetypetab[i].str, str) == 0)
            return (filetypetab[i].type);
     return (F_UNKNOWN);
index 8398aeafd1899ff9e2522eadb94d07b52600477b..c6213fec31854d42936f2b1c6adc942b60a64783 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: fileheader.h,v 1.15 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: fileheader.h,v 1.16 2006/05/25 01:47:12 johnfranks Exp $
  *
  */
 
@@ -39,7 +39,7 @@
 typedef char string_t[STRMAX];
 typedef enum {
     F_UNKNOWN, F_WEIRD, F_TAPESTART, F_TAPEEND, 
-    F_DUMPFILE, F_CONT_DUMPFILE, F_SPLIT_DUMPFILE
+    F_DUMPFILE, F_CONT_DUMPFILE, F_SPLIT_DUMPFILE, F_EMPTY
 } filetype_t;
 
 typedef struct file_s {
@@ -67,17 +67,16 @@ typedef struct file_s {
     int is_partial;
     int partnum;
     int totalparts; /* -1 == UNKNOWN */
-    long blocksize;
+    size_t blocksize;
 } dumpfile_t;
 
 /* local functions */
 
-void  fh_init             P((dumpfile_t *file));
-void  parse_file_header   P((const char *buffer, dumpfile_t *file, size_t buflen));
-void  build_header        P((char *buffer,
-                            const dumpfile_t *file,
-                            size_t buflen));
-void  print_header        P((FILE *outf, const dumpfile_t *file));
-int   known_compress_type P((const dumpfile_t *file));
+void   fh_init(dumpfile_t *file);
+void   parse_file_header(const char *buffer, dumpfile_t *file, size_t buflen);
+void   build_header(char *buffer, const dumpfile_t *file, size_t buflen);
+void   print_header(FILE *outf, const dumpfile_t *file);
+int    known_compress_type(const dumpfile_t *file);
+void   dump_dumpfile_t(const dumpfile_t *file);
 
 #endif /* !FILEHEADER_H */
index 074296bd3a79058550b1b7649f9b7eb88734bb94..21243b96fcb9c6d14f71aaff728f6fc98a888a5a 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: genversion.c,v 1.31 2003/10/07 17:09:46 martinea Exp $
+ * $Id: genversion.c,v 1.36 2006/07/13 03:22:20 paddy_s Exp $
  *
  * dump the current Amanda version info
  */
 #define        LMARGIN         6
 #define RMARGIN        70
 
-static int linelen;
+static size_t linelen;
 
 #define        startline(title)        printf("  \"%-*s", LMARGIN, title); linelen = 0
 #define        endline()               printf("\\n\",\n")
 
-static void prstr P((const char *));
-static void prvar P((const char *, const char *));
-int main P((void));
+static void prstr(const char *);
+static void prvar(const char *, const char *);
+static void prundefvar(const char *var);
+static void prnum(const char *var, long val);
+
+int main(int, char **);
 
 /* Print a string */
 static void
-prstr(string)
-    const char *string;
+prstr(
+    const char *string)
 {
     size_t len = strlen(string) + 1;
 
@@ -68,82 +71,108 @@ static size_t buf_len = 0;
 
 /* Print a text variable */
 static void
-prvar(var, val)
-    const char *var, *val;
+prvar(
+    const char *var,
+    const char *val)
 {
     size_t new_len;
 
     new_len = strlen(var)
-             + sizeof("=\\\"")
+             + SIZEOF("=\\\"")
              + strlen(val)
-             + sizeof("\\\"")
+             + SIZEOF("\\\"")
              + 1;
     if(new_len > buf_len) {
        free(buf);
        buf_len = new_len;
-       buf = malloc(new_len);          /* let it die if malloc() fails */
+       buf = malloc(new_len);
+       if (!buf) {
+           fprintf(stderr, "genversion: Not enough memory");
+           abort();
+           /*NOTREACHED*/
+       }
     }
-    sprintf(buf, "%s=\\\"%s\\\"", var, val);   /* safe */
+    snprintf(buf, buf_len, "%s=\\\"%s\\\"", var, val); /* safe */
     prstr(buf);
 }
 
 /* Print a undef variable */
 static void
-prundefvar(var)
-    const char *var;
+prundefvar(
+    const char *var)
 {
     size_t new_len;
 
     new_len = strlen(var)
-             + sizeof("=UNDEF")
+             + SIZEOF("=UNDEF")
              + 1;
     if(new_len > buf_len) {
        free(buf);
        buf_len = new_len;
        buf = malloc(new_len);          /* let it die if malloc() fails */
+       if (!buf) {
+           fprintf(stderr, "genversion: Not enough memory");
+           abort();
+           /*NOTREACHED*/
+       }
     }
-    sprintf(buf, "%s=UNDEF", var);     /* safe */
+    snprintf(buf, buf_len, "%s=UNDEF", var);   /* safe */
     prstr(buf);
 }
 
 /* Print a numeric variable */
 static void
-prnum(var, val)
-    const char *var;
-    long val;
+prnum(
+    const char *var,
+    long       val)
 {
     static char number[NUM_STR_SIZE];
     size_t new_len;
 
-    snprintf(number, sizeof(number), "%ld", val);
+    snprintf(number, SIZEOF(number), "%ld", val);
     new_len = strlen(var)
-             + sizeof("=")
+             + SIZEOF("=")
              + strlen(number)
              + 1;
     if(new_len > buf_len) {
        free(buf);
        buf_len = new_len;
        buf = malloc(new_len);          /* let it die if malloc() fails */
+       if (!buf) {
+           fprintf(stderr, "genversion: Not enough memory");
+           abort();
+           /*NOTREACHED*/
+       }
     }
-    sprintf(buf, "%s=%s", var, number);                /* safe */
+    snprintf(buf, buf_len, "%s=%s", var, number);              /* safe */
     prstr(buf);
 }
 
 int
-main()
+main(
+    int                argc,
+    char **    argv)
 {
     const char *v;
     char *verstr;
     size_t v_len;
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
+
     printf("/* version.c - generated by genversion.c - DO NOT EDIT! */\n");
     printf("const char * const version_info[] = {\n");
 
     startline("build:");
     v = version();
-    v_len = sizeof("Amanda-") + strlen(v) + 1;
+    v_len = SIZEOF("Amanda-") + strlen(v) + 1;
     verstr = malloc(v_len);
-    sprintf(verstr, "Amanda-%s", v);           /* safe */
+    if (!verstr) {
+       fprintf(stderr, "genversion: Not enough memory");
+       abort();
+       /*NOTREACHED*/
+    }
+    snprintf(verstr, v_len, "Amanda-%s", v);           /* safe */
     prvar("VERSION", verstr);
     free(verstr);
 
@@ -275,7 +304,10 @@ main()
     prvar("DEFAULT_SERVER", DEFAULT_SERVER);
     prvar("DEFAULT_CONFIG", DEFAULT_CONFIG);
     prvar("DEFAULT_TAPE_SERVER", DEFAULT_TAPE_SERVER);
+
+#ifdef DEFAULT_TAPE_DEVICE
     prvar("DEFAULT_TAPE_DEVICE", DEFAULT_TAPE_DEVICE);
+#endif
 
 #ifdef AIX_BACKUP
     prstr("AIX_BACKUP");
@@ -411,5 +443,5 @@ main()
 
     printf("  0\n};\n");
 
-    exit(0);
+    return (0); /* exit */
 }
index a7601c638d75717698790da4ba53b54cbeceb3c7..74baeb984261d1dcbb865b56f7c52e68bfe39c99 100644 (file)
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  */
 
-/* $Id: getcwd.c,v 1.4 2002/02/11 01:32:10 jrjackson Exp $ */
+/* $Id: getcwd.c,v 1.5 2006/05/25 01:47:12 johnfranks Exp $ */
 
 #ifndef lint
-static char rcsid[] = "$Header: /cvsroot/amanda/amanda/common-src/getcwd.c,v 1.4 2002/02/11 01:32:10 jrjackson Exp $ SPRITE (Berkeley)";
+static char rcsid[] = "$Header: /cvsroot/amanda/amanda/common-src/getcwd.c,v 1.5 2006/05/25 01:47:12 johnfranks Exp $ SPRITE (Berkeley)";
 #endif /* not lint */
 
-#include <stdio.h>
-#include <errno.h>
-#include <sys/param.h>
+#include "amanda.h"
 
 extern char *getwd();
 extern int errno;
index db6e702097f112c893714570c6ec007f01e2e1f7..6a3dad380be0713e9afabfafcb66dbc24a70ad4f 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*
- * $Id: krb4-security.c,v 1.9.2.1 2006/04/11 11:11:16 martinea Exp $
+ * $Id: krb4-security.c,v 1.18 2006/07/13 03:22:20 paddy_s Exp $
  *
  * krb4-security.c - helper functions for kerberos v4 security.
  */
@@ -42,6 +42,7 @@
 #include "packet.h"
 #include "queue.h"
 #include "security.h"
+#include "security-util.h"
 #include "protocol.h"
 #include "stream.h"
 #include "version.h"
@@ -60,8 +61,8 @@
 #endif /* HAVE_ON_EXIT */
 #endif /* ! HAVE_ATEXIT */
 
-int krb_set_lifetime P((int));
-int kuserok P((AUTH_DAT *, char *));
+int krb_set_lifetime(int);
+int kuserok(AUTH_DAT *, char *);
 
 /*
  * This is the private handle data
@@ -81,7 +82,7 @@ struct krb4_handle {
      * The rest is used for the async recvpkt/recvpkt_cancel
      * interface.
      */
-    void (*fn) P((void *, pkt_t *, security_status_t));
+    void (*fn)(void *, pkt_t *, security_status_t);
                                        /* func to call when packet recvd */
     void *arg;                         /* argument to pass function */
     event_handle_t *ev_timeout;                /* timeout handle for recv */
@@ -99,7 +100,8 @@ struct krb4_stream {
     int socket;                                /* fd for server-side accepts */
     event_handle_t *ev_read;           /* read event handle */
     char databuf[MAX_TAPE_BLOCK_BYTES];        /* read buffer */
-    void (*fn) P((void *, void *, int));       /* read event fn */
+    int len;                           /* */
+    void (*fn)(void *, void *, ssize_t);/* read event fn */
     void *arg;                         /* arg for previous */
 };
 
@@ -111,26 +113,25 @@ struct krb4_stream {
 /*
  * Interface functions
  */
-static void krb4_connect P((const char *,
-    char *(*)(char *, void *),  
-    void (*)(void *, security_handle_t *, security_status_t), void *));
-static void krb4_accept P((int, int, void (*)(security_handle_t *, pkt_t *)));
-static void krb4_close P((void *));
-static int krb4_sendpkt P((void *, pkt_t *));
-static void krb4_recvpkt P((void *,
-    void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void krb4_recvpkt_cancel P((void *));
-
-static void *krb4_stream_server P((void *));
-static int krb4_stream_accept P((void *));
-static void *krb4_stream_client P((void *, int));
-static void krb4_stream_close P((void *));
-static int krb4_stream_auth P((void *));
-static int krb4_stream_id P((void *));
-static int krb4_stream_write P((void *, const void *, size_t));
-static void krb4_stream_read P((void *, void (*)(void *, void *, int),
-    void *));
-static void krb4_stream_read_cancel P((void *));
+static void    krb4_connect(const char *, char *(*)(char *, void *),  
+                       void (*)(void *, security_handle_t *, security_status_t),
+                       void *, void *);
+static void    krb4_accept(const struct security_driver *, int, int, void (*)(security_handle_t *, pkt_t *));
+static void    krb4_close(void *);
+static int     krb4_sendpkt(void *, pkt_t *);
+static void    krb4_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
+                       void *, int);
+static void    krb4_recvpkt_cancel(void *);
+static void *  krb4_stream_server(void *);
+static int     krb4_stream_accept(void *);
+static void *  krb4_stream_client(void *, int);
+static void    krb4_stream_close(void *);
+static int     krb4_stream_auth(void *);
+static int     krb4_stream_id(void *);
+static int     krb4_stream_write(void *, const void *, size_t);
+static void    krb4_stream_read(void *, void (*)(void *, void *, int), void *);
+static int     krb4_stream_read_sync(void *, void **);
+static void    krb4_stream_read_cancel(void *);
 
 
 /*
@@ -152,7 +153,9 @@ const security_driver_t krb4_security_driver = {
     krb4_stream_id,
     krb4_stream_write,
     krb4_stream_read,
+    krb4_stream_read_sync,
     krb4_stream_read_cancel,
+    sec_close_connection_none,
 };
 
 /*
@@ -196,7 +199,7 @@ static struct {
 
 #define        handleq_first()         TAILQ_FIRST(&handleq.tailq)
 #define        handleq_next(kh)        TAILQ_NEXT(kh, tq)
-       
+
 
 /*
  * This is the event manager's handle for our netfd
@@ -208,7 +211,7 @@ static event_handle_t *ev_netfd;
  * created.  If NULL, no new handles are created.
  * It is passed the new handle and the received pkt
  */
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
+static void (*accept_fn)(security_handle_t *, pkt_t *);
 
 
 /*
@@ -219,41 +222,42 @@ static void (*accept_fn) P((security_handle_t *, pkt_t *));
  */
 union mutual {
     char pad[8];
-    unsigned long cksum;
+    long cksum;
 };
 
 /*
  * Private functions
  */
-static unsigned long krb4_cksum P((const char *));
-static void krb4_getinst P((const char *, char *, size_t));
-static void host2key P((const char *, const char *, des_cblock *));
-static void init P((void));
-static void inithandle P((struct krb4_handle *, struct hostent *, int,
-    const char *));
-static void get_tgt P((void));
-static void killtickets P((void));
-static void recvpkt_callback P((void *));
-static void recvpkt_timeout P((void *));
-static int recv_security_ok P((struct krb4_handle *, pkt_t *));
-static void stream_read_callback P((void *));
-static int net_write P((int, const void *, size_t));
-static int net_read P((int, void *, size_t, int));
-
-static int add_ticket P((struct krb4_handle *, const pkt_t *, dgram_t *));
-static void add_mutual_auth P((struct krb4_handle *, dgram_t *));
-static int check_ticket P((struct krb4_handle *, const pkt_t *,
-    const char *, unsigned long));
-static int check_mutual_auth P((struct krb4_handle *, const char *));
-
-static const char *pkthdr2str P((const struct krb4_handle *, const pkt_t *));
-static int str2pkthdr P((const char *, pkt_t *, char *, size_t, int *));
-
-static const char *bin2astr P((const unsigned char *, int));
-static void astr2bin P((const char *, unsigned char *, int *));
-
-static void encrypt_data P((void *, int, des_cblock *));
-static void decrypt_data P((void *, int, des_cblock *));
+static unsigned long krb4_cksum(const char *);
+static void krb4_getinst(const char *, char *, size_t);
+static void host2key(const char *, const char *, des_cblock *);
+static void init(void);
+static void inithandle(struct krb4_handle *, struct hostent *, int,
+    const char *);
+static void get_tgt(void);
+static void killtickets(void);
+static void recvpkt_callback(void *);
+static void recvpkt_timeout(void *);
+static int recv_security_ok(struct krb4_handle *, pkt_t *);
+static void stream_read_callback(void *);
+static void stream_read_sync_callback(void *);
+static int net_write(int, const void *, size_t);
+static int net_read(int, void *, size_t, int);
+
+static int add_ticket(struct krb4_handle *, const pkt_t *, dgram_t *);
+static void add_mutual_auth(struct krb4_handle *, dgram_t *);
+static int check_ticket(struct krb4_handle *, const pkt_t *,
+    const char *, unsigned long);
+static int check_mutual_auth(struct krb4_handle *, const char *);
+
+static const char *pkthdr2str(const struct krb4_handle *, const pkt_t *);
+static int str2pkthdr(const char *, pkt_t *, char *, size_t, int *);
+
+static const char *bin2astr(const unsigned char *, int);
+static void astr2bin(const unsigned char *, unsigned char *, int *);
+
+static void encrypt_data(void *, size_t, des_cblock *);
+static void decrypt_data(void *, size_t, des_cblock *);
 
 #define HOSTNAME_INSTANCE inst
 
@@ -271,7 +275,7 @@ killtickets(void)
  * Setup some things about krb4.  This should only be called once.
  */
 static void
-init()
+init(void)
 {
     char tktfile[256];
     int port;
@@ -281,8 +285,8 @@ init()
        return;
     beenhere = 1;
 
-    gethostname(hostname, sizeof(hostname) - 1);
-    hostname[sizeof(hostname) - 1] = '\0';
+    gethostname(hostname, SIZEOF(hostname) - 1);
+    hostname[SIZEOF(hostname) - 1] = '\0';
 
     if (atexit(killtickets) < 0)
        error("could not setup krb4 exit handler: %s", strerror(errno));
@@ -293,7 +297,7 @@ init()
      * This file also needs to be removed so that no extra tickets are
      * hanging around.
      */
-    snprintf(tktfile, sizeof(tktfile), "/tmp/tkt%ld-%ld.amanda",
+    snprintf(tktfile, SIZEOF(tktfile), "/tmp/tkt%ld-%ld.amanda",
        (long)getuid(), (long)getpid());
     ticketfilename = stralloc(tktfile);
     unlink(ticketfilename);
@@ -315,13 +319,13 @@ init()
  * Get a ticket granting ticket and stuff it in the cache
  */
 static void
-get_tgt()
+get_tgt(void)
 {
     char realm[REALM_SZ];
     int rc;
 
-    strncpy(realm, krb_realmofhost(hostname), sizeof(realm) - 1);
-    realm[sizeof(realm) - 1] = '\0';
+    strncpy(realm, krb_realmofhost(hostname), SIZEOF(realm) - 1);
+    realm[SIZEOF(realm) - 1] = '\0';
 
     rc = krb_get_svc_in_tkt(SERVER_HOST_PRINCIPLE, SERVER_HOST_INSTANCE,
        realm, "krbtgt", realm, TICKET_LIFETIME, SERVER_HOST_KEY_FILE);
@@ -341,11 +345,12 @@ get_tgt()
  * up a network "connection".
  */
 static void
-krb4_connect(hostname, conf_fn, fn, arg)
-    const char *hostname;
-    char *(*conf_fn) P((char *, void *));
-    void (*fn) P((void *, security_handle_t *, security_status_t));
-    void *arg;
+krb4_connect(
+    const char *hostname,
+    char *     (*conf_fn)(char *, void *),
+    void       (*fn)(void *, security_handle_t *, security_status_t),
+    void *     arg,
+    void *     datap)
 {
     struct krb4_handle *kh;
     char handle[32];
@@ -360,7 +365,7 @@ krb4_connect(hostname, conf_fn, fn, arg)
      */
     init();
 
-    kh = alloc(sizeof(*kh));
+    kh = alloc(SIZEOF(*kh));
     security_handleinit(&kh->sech, &krb4_security_driver);
 
     if ((he = gethostbyname(hostname)) == NULL) {
@@ -370,11 +375,11 @@ krb4_connect(hostname, conf_fn, fn, arg)
        return;
     }
     if ((se = getservbyname(KAMANDA_SERVICE_NAME, "udp")) == NULL)
-       port = htons(KAMANDA_SERVICE_DEFAULT);
+       port = (int)htons(KAMANDA_SERVICE_DEFAULT);
     else
        port = se->s_port;
-    snprintf(handle, sizeof(handle), "%ld", (long)time(NULL));
-    inithandle(kh, he, port, handle);
+    snprintf(handle, SIZEOF(handle), "%ld", (long)time(NULL));
+    inithandle(kh, he, (int)port, handle);
     (*fn)(arg, &kh->sech, S_OK);
 }
 
@@ -382,9 +387,11 @@ krb4_connect(hostname, conf_fn, fn, arg)
  * Setup to handle new incoming connections
  */
 static void
-krb4_accept(in, out, fn)
-    int in, out;
-    void (*fn) P((security_handle_t *, pkt_t *));
+krb4_accept(
+    const struct security_driver *driver,
+    int                in,
+    int                out,
+    void       (*fn)(security_handle_t *, pkt_t *))
 {
 
     /*
@@ -405,50 +412,50 @@ krb4_accept(in, out, fn)
     accept_fn = fn;
 
     if (ev_netfd == NULL)
-       ev_netfd = event_register(netfd.socket, EV_READFD,
-           recvpkt_callback, NULL);
+       ev_netfd = event_register((event_id_t)netfd.socket, EV_READFD,
+                           recvpkt_callback, NULL);
 }
 
 /*
  * Given a hostname and a port, setup a krb4_handle
  */
 static void
-inithandle(kh, he, port, handle)
-    struct krb4_handle *kh;
-    struct hostent *he;
-    int port;
-    const char *handle;
+inithandle(
+    struct krb4_handle *kh,
+    struct hostent *   he,
+    int                        port,
+    const char *       handle)
 {
 
     /*
      * Get the instance and realm for this host
      * (krb_realmofhost always returns something)
      */
-    krb4_getinst(he->h_name, kh->inst, sizeof(kh->inst));
-    strncpy(kh->realm, krb_realmofhost(he->h_name), sizeof(kh->realm) - 1);
-    kh->realm[sizeof(kh->realm) - 1] = '\0';
+    krb4_getinst(he->h_name, kh->inst, SIZEOF(kh->inst));
+    strncpy(kh->realm, krb_realmofhost(he->h_name), SIZEOF(kh->realm) - 1);
+    kh->realm[SIZEOF(kh->realm) - 1] = '\0';
 
     /*
      * Save a copy of the hostname
      */
-    strncpy(kh->hostname, he->h_name, sizeof(kh->hostname) - 1);
-    kh->hostname[sizeof(kh->hostname) - 1] = '\0';
+    strncpy(kh->hostname, he->h_name, SIZEOF(kh->hostname) - 1);
+    kh->hostname[SIZEOF(kh->hostname) - 1] = '\0';
 
     /*
      * We have no checksum or session key at this point
      */
     kh->cksum = 0;
-    memset(kh->session_key, 0, sizeof(kh->session_key));
+    memset(kh->session_key, 0, SIZEOF(kh->session_key));
 
     /*
      * Setup our peer info.  We don't do anything with the sequence yet,
      * so just leave it at 0.
      */
-    kh->peer.sin_family = AF_INET;
-    kh->peer.sin_port = port;
+    kh->peer.sin_family = (sa_family_t)AF_INET;
+    kh->peer.sin_port = (in_port_t)port;
     kh->peer.sin_addr = *(struct in_addr *)he->h_addr;
-    strncpy(kh->proto_handle, handle, sizeof(kh->proto_handle) - 1);
-    kh->proto_handle[sizeof(kh->proto_handle) - 1] = '\0';
+    strncpy(kh->proto_handle, handle, SIZEOF(kh->proto_handle) - 1);
+    kh->proto_handle[SIZEOF(kh->proto_handle) - 1] = '\0';
     kh->sequence = 0;
     kh->fn = NULL;
     kh->arg = NULL;
@@ -459,8 +466,8 @@ inithandle(kh, he, port, handle)
  * frees a handle allocated by the above
  */
 static void
-krb4_close(inst)
-    void *inst;
+krb4_close(
+    void *     inst)
 {
 
     krb4_recvpkt_cancel(inst);
@@ -470,10 +477,10 @@ krb4_close(inst)
 /*
  * Transmit a packet.  Add security information first.
  */
-static int
-krb4_sendpkt(cookie, pkt)
-    void *cookie;
-    pkt_t *pkt;
+static ssize_t
+krb4_sendpkt(
+    void *     cookie,
+    pkt_t *    pkt)
 {
     struct krb4_handle *kh = cookie;
 
@@ -539,10 +546,11 @@ krb4_sendpkt(cookie, pkt)
  * it has been read.
  */
 static void
-krb4_recvpkt(cookie, fn, arg, timeout)
-    void *cookie, *arg;
-    void (*fn) P((void *, pkt_t *, security_status_t));
-    int timeout;
+krb4_recvpkt(
+    void *     cookie,
+    void       (*fn)(void *, pkt_t *, security_status_t),
+    void *     arg,
+    int                timeout)
 {
     struct krb4_handle *kh = cookie;
 
@@ -557,8 +565,8 @@ krb4_recvpkt(cookie, fn, arg, timeout)
      */
     if (ev_netfd == NULL) {
        assert(handleq.qlength == 0);
-       ev_netfd = event_register(netfd.socket, EV_READFD,
-           recvpkt_callback, NULL);
+       ev_netfd = event_register((event_id_t)netfd.socket, EV_READFD,
+                           recvpkt_callback, NULL);
     }
 
     /*
@@ -572,7 +580,8 @@ krb4_recvpkt(cookie, fn, arg, timeout)
     if (timeout < 0)
        kh->ev_timeout = NULL;
     else
-       kh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, kh);
+       kh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
+                               recvpkt_timeout, kh);
     kh->fn = fn;
     kh->arg = arg;
 }
@@ -583,8 +592,8 @@ krb4_recvpkt(cookie, fn, arg, timeout)
  * for our network fd.
  */
 static void
-krb4_recvpkt_cancel(cookie)
-    void *cookie;
+krb4_recvpkt_cancel(
+    void *     cookie)
 {
     struct krb4_handle *kh = cookie;
 
@@ -611,17 +620,17 @@ krb4_recvpkt_cancel(cookie)
  * socket for receiving a connection.
  */
 static void *
-krb4_stream_server(h)
-    void *h;
+krb4_stream_server(
+    void *     h)
 {
     struct krb4_handle *kh = h;
     struct krb4_stream *ks;
 
     assert(kh != NULL);
 
-    ks = alloc(sizeof(*ks));
+    ks = alloc(SIZEOF(*ks));
     security_streaminit(&ks->secstr, &krb4_security_driver);
-    ks->socket = stream_server(&ks->port, STREAM_BUFSIZE, STREAM_BUFSIZE);
+    ks->socket = stream_server(&ks->port, STREAM_BUFSIZE, STREAM_BUFSIZE, 1);
     if (ks->socket < 0) {
        security_seterror(&kh->sech,
            "can't create server stream: %s", strerror(errno));
@@ -638,8 +647,8 @@ krb4_stream_server(h)
  * Accept an incoming connection on a stream_server socket
  */
 static int
-krb4_stream_accept(s)
-    void *s;
+krb4_stream_accept(
+    void *     s)
 {
     struct krb4_stream *ks = s;
     struct krb4_handle *kh;
@@ -650,7 +659,7 @@ krb4_stream_accept(s)
     assert(ks->socket >= 0);
     assert(ks->fd == -1);
 
-    ks->fd = stream_accept(ks->socket, 30, -1, -1);
+    ks->fd = stream_accept(ks->socket, 30, STREAM_BUFSIZE, STREAM_BUFSIZE);
     if (ks->fd < 0) {
        security_stream_seterror(&ks->secstr,
            "can't accept new stream connection: %s", strerror(errno));
@@ -663,22 +672,16 @@ krb4_stream_accept(s)
  * Return a connected stream.
  */
 static void *
-krb4_stream_client(h, id)
-    void *h;
-    int id;
+krb4_stream_client(
+    void *     h,
+    int                id)
 {
     struct krb4_handle *kh = h;
     struct krb4_stream *ks;
 
     assert(kh != NULL);
 
-    if (id < 0) {
-       security_seterror(&kh->sech,
-           "%d: invalid security stream id", id);
-       return (NULL);
-    }
-
-    ks = alloc(sizeof(*ks));
+    ks = alloc(SIZEOF(*ks));
     security_streaminit(&ks->secstr, &krb4_security_driver);
     ks->fd = stream_client(kh->hostname, id, STREAM_BUFSIZE, STREAM_BUFSIZE,
        &ks->port, 0);
@@ -700,8 +703,8 @@ krb4_stream_client(h, id)
  * Close and unallocate resources for a stream.
  */
 static void
-krb4_stream_close(s)
-    void *s;
+krb4_stream_close(
+    void *     s)
 {
     struct krb4_stream *ks = s;
 
@@ -723,8 +726,8 @@ krb4_stream_close(s)
  * into byte arrays and send those.
  */
 static int
-krb4_stream_auth(s)
-    void *s;
+krb4_stream_auth(
+    void *     s)
 {
     struct krb4_stream *ks = s;
     struct krb4_handle *kh;
@@ -742,17 +745,17 @@ krb4_stream_auth(s)
     assert(fd >= 0);
 
     /* make sure our timeval is what we're expecting, see above */
-    assert(sizeof(struct timeval) == 8);
+    assert(SIZEOF(struct timeval) == 8);
 
     /*
      * Get the current time, put it in network byte order, encrypt it
      * and present it to the other side.
      */
     gettimeofday(&local, &tz);
-    enc.tv_sec = htonl(local.tv_sec);
-    enc.tv_usec = htonl(local.tv_usec);
-    encrypt_data(&enc, sizeof(enc), &kh->session_key);
-    if (net_write(fd, &enc, sizeof(enc)) < 0) {
+    enc.tv_sec = (long)htonl((uint32_t)local.tv_sec);
+    enc.tv_usec = (long)htonl((uint32_t)local.tv_usec);
+    encrypt_data(&enc, SIZEOF(enc), &kh->session_key);
+    if (net_write(fd, &enc, SIZEOF(enc)) < 0) {
        security_stream_seterror(&ks->secstr,
            "krb4 stream handshake write error: %s", strerror(errno));
        return (-1);
@@ -763,18 +766,18 @@ krb4_stream_auth(s)
      * and useconds by one.  Reencrypt, and present to the other side.
      * Timeout in 10 seconds.
      */
-    if (net_read(fd, &enc, sizeof(enc), 60) < 0) {
+    if (net_read(fd, &enc, SIZEOF(enc), 60) < 0) {
        security_stream_seterror(&ks->secstr,
            "krb4 stream handshake read error: %s", strerror(errno));
        return (-1);
     }
-    decrypt_data(&enc, sizeof(enc), &kh->session_key);
+    decrypt_data(&enc, SIZEOF(enc), &kh->session_key);
     /* XXX do timestamp checking here */
-    enc.tv_sec = htonl(ntohl(enc.tv_sec) + 1);
-    enc.tv_usec = htonl(ntohl(enc.tv_usec) + 1);
-    encrypt_data(&enc, sizeof(enc), &kh->session_key);
+    enc.tv_sec = (long)htonl(ntohl((uint32_t)enc.tv_sec) + 1);
+    enc.tv_usec =(long)htonl(ntohl((uint32_t)enc.tv_usec) + 1);
+    encrypt_data(&enc, SIZEOF(enc), &kh->session_key);
 
-    if (net_write(fd, &enc, sizeof(enc)) < 0) {
+    if (net_write(fd, &enc, SIZEOF(enc)) < 0) {
        security_stream_seterror(&ks->secstr,
            "krb4 stream handshake write error: %s", strerror(errno));
        return (-1);
@@ -785,20 +788,21 @@ krb4_stream_auth(s)
      * If they incremented it properly, then succeed.
      * Timeout in 10 seconds.
      */
-    if (net_read(fd, &enc, sizeof(enc), 60) < 0) {
+    if (net_read(fd, &enc, SIZEOF(enc), 60) < 0) {
        security_stream_seterror(&ks->secstr,
            "krb4 stream handshake read error: %s", strerror(errno));
        return (-1);
     }
-    decrypt_data(&enc, sizeof(enc), &kh->session_key);
-    if (ntohl(enc.tv_sec)  == local.tv_sec + 1 &&
-       ntohl(enc.tv_usec) == local.tv_usec + 1)
+    decrypt_data(&enc, SIZEOF(enc), &kh->session_key);
+    if ((ntohl((uint32_t)enc.tv_sec)  == (uint32_t)(local.tv_sec + 1)) &&
+       (ntohl((uint32_t)enc.tv_usec) == (uint32_t)(local.tv_usec + 1)))
            return (0);
 
     security_stream_seterror(&ks->secstr,
        "krb4 handshake failed: sent %ld,%ld - recv %ld,%ld",
            (long)(local.tv_sec + 1), (long)(local.tv_usec + 1),
-           (long)ntohl(enc.tv_sec), (long)ntohl(enc.tv_usec));
+           (long)ntohl((uint32_t)enc.tv_sec),
+           (long)ntohl((uint32_t)enc.tv_usec));
     return (-1);
 }
 
@@ -807,8 +811,8 @@ krb4_stream_auth(s)
  * port.
  */
 static int
-krb4_stream_id(s)
-    void *s;
+krb4_stream_id(
+    void *     s)
 {
     struct krb4_stream *ks = s;
 
@@ -821,10 +825,10 @@ krb4_stream_id(s)
  * Write a chunk of data to a stream.  Blocks until completion.
  */
 static int
-krb4_stream_write(s, buf, size)
-    void *s;
-    const void *buf;
-    size_t size;
+krb4_stream_write(
+    void *     s,
+    const void *buf,
+    size_t     size)
 {
     struct krb4_stream *ks = s;
     struct krb4_handle *kh = ks->krb4_handle;
@@ -845,9 +849,10 @@ krb4_stream_write(s, buf, size)
  * function and arg when completed.
  */
 static void
-krb4_stream_read(s, fn, arg)
-    void *s, *arg;
-    void (*fn) P((void *, void *, int));
+krb4_stream_read(
+    void *     s,
+    void       (*fn)(void *, void *, ssize_t),
+    void *     arg)
 {
     struct krb4_stream *ks = s;
 
@@ -859,18 +864,67 @@ krb4_stream_read(s, fn, arg)
     if (ks->ev_read != NULL)
        event_release(ks->ev_read);
 
-    ks->ev_read = event_register(ks->fd, EV_READFD, stream_read_callback, ks);
+    ks->ev_read = event_register((event_id_t)ks->fd, EV_READFD,
+                       stream_read_callback, ks);
     ks->fn = fn;
     ks->arg = arg;
 }
 
+/*
+ * Write a chunk of data to a stream.  Blocks until completion.
+ */
+static ssize_t
+krb4_stream_read_sync(
+    void *     s,
+    void **    buf)
+{
+    struct krb4_stream *ks = s;
+
+    (void)buf; /* Quiet unused variable warning */
+    assert(ks != NULL);
+
+    if (ks->ev_read != NULL)
+       event_release(ks->ev_read);
+
+    ks->ev_read = event_register((event_id_t)ks->fd, EV_READFD,
+                       stream_read_sync_callback, ks);
+    event_wait(ks->ev_read);
+    return((ssize_t)ks->len);
+}
+
+/*
+ * Callback for krb4_stream_read_sync
+ */
+static void
+stream_read_sync_callback(
+    void *     arg)
+{
+    struct krb4_stream *ks = arg;
+    ssize_t n;
+
+    assert(ks != NULL);
+    assert(ks->fd != -1);
+
+    /*
+     * Remove the event first, and then call the callback.
+     * We remove it first because we don't want to get in their
+     * way if they reschedule it.
+     */
+    krb4_stream_read_cancel(ks);
+    n = read(ks->fd, ks->databuf, sizeof(ks->databuf));
+    if (n < 0)
+       security_stream_seterror(&ks->secstr,
+           strerror(errno));
+    ks->len = (int)n;
+}
+
 /*
  * Cancel a previous stream read request.  It's ok if we didn't have a read
  * scheduled.
  */
 static void
-krb4_stream_read_cancel(s)
-    void *s;
+krb4_stream_read_cancel(
+    void *     s)
 {
     struct krb4_stream *ks = s;
 
@@ -886,11 +940,11 @@ krb4_stream_read_cancel(s)
  * Callback for krb4_stream_read
  */
 static void
-stream_read_callback(arg)
-    void *arg;
+stream_read_callback(
+    void *     arg)
 {
     struct krb4_stream *ks = arg;
-    int n;
+    ssize_t n;
 
     assert(ks != NULL);
     assert(ks->fd != -1);
@@ -901,7 +955,7 @@ stream_read_callback(arg)
      * way if they reschedule it.
      */
     krb4_stream_read_cancel(ks);
-    n = read(ks->fd, ks->databuf, sizeof(ks->databuf));
+    n = read(ks->fd, ks->databuf, SIZEOF(ks->databuf));
     if (n < 0)
        security_stream_seterror(&ks->secstr,
            strerror(errno));
@@ -914,8 +968,8 @@ stream_read_callback(arg)
  * and does the real callback if so.
  */
 static void
-recvpkt_callback(cookie)
-    void *cookie;
+recvpkt_callback(
+    void *     cookie)
 {
     char handle[32];
     struct sockaddr_in peer;
@@ -923,7 +977,7 @@ recvpkt_callback(cookie)
     int sequence;
     struct krb4_handle *kh;
     struct hostent *he;
-    void (*fn) P((void *, pkt_t *, security_status_t));
+    void (*fn)(void *, pkt_t *, security_status_t);
     void *arg;
 
     assert(cookie == NULL);
@@ -936,13 +990,13 @@ recvpkt_callback(cookie)
     dgram_zero(&netfd);
     if (dgram_recv(&netfd, 0, &peer) < 0)
        return;
-    if (str2pkthdr(netfd.cur, &pkt, handle, sizeof(handle), &sequence) < 0)
+    if (str2pkthdr(netfd.cur, &pkt, handle, SIZEOF(handle), &sequence) < 0)
        return;
 
     for (kh = handleq_first(); kh != NULL; kh = handleq_next(kh)) {
        if (strcmp(kh->proto_handle, handle) == 0 &&
            memcmp(&kh->peer.sin_addr, &peer.sin_addr,
-           sizeof(peer.sin_addr)) == 0 &&
+           SIZEOF(peer.sin_addr)) == 0 &&
            kh->peer.sin_port == peer.sin_port) {
            kh->sequence = sequence;
 
@@ -967,12 +1021,12 @@ recvpkt_callback(cookie)
     if (accept_fn == NULL)
        return;
 
-    he = gethostbyaddr((void *)&peer.sin_addr, sizeof(peer.sin_addr), AF_INET);
+    he = gethostbyaddr((void *)&peer.sin_addr, SIZEOF(peer.sin_addr), AF_INET);
     if (he == NULL)
        return;
-    kh = alloc(sizeof(*kh));
+    kh = alloc(SIZEOF(*kh));
     security_handleinit(&kh->sech, &krb4_security_driver);
-    inithandle(kh, he, peer.sin_port, handle);
+    inithandle(kh, he, (int)peer.sin_port, handle);
 
     /*
      * Check the security of the packet.  If it is bad, then pass NULL
@@ -988,11 +1042,11 @@ recvpkt_callback(cookie)
  * This is called when a handle times out before receiving a packet.
  */
 static void
-recvpkt_timeout(cookie)
-    void *cookie;
+recvpkt_timeout(
+    void *     cookie)
 {
     struct krb4_handle *kh = cookie;
-    void (*fn) P((void *, pkt_t *, security_status_t));
+    void (*fn)(void *, pkt_t *, security_status_t);
     void *arg;
 
     assert(kh != NULL);
@@ -1008,30 +1062,30 @@ recvpkt_timeout(cookie)
  * Add a ticket to the message
  */
 static int
-add_ticket(kh, pkt, msg)
-    struct krb4_handle *kh;
-    const pkt_t *pkt;
-    dgram_t *msg;
+add_ticket(
+    struct krb4_handle *kh,
+    const pkt_t *      pkt,
+    dgram_t *          msg)
 {
     char inst[INST_SZ];
     KTEXT_ST ticket;
     char *security;
     int rc;
 
-    kh->cksum = krb4_cksum(pkt->body);
+    kh->cksum = (long)krb4_cksum(pkt->body);
 #if CLIENT_HOST_INSTANCE == HOSTNAME_INSTANCE
     /*
      * User requested that all instances be based on the target
      * hostname.
      */
-    strncpy(inst, kh->inst, sizeof(inst) - 1);
+    strncpy(inst, kh->inst, SIZEOF(inst) - 1);
 #else
     /*
      * User requested a fixed instance.
      */
-    strncpy(inst, CLIENT_HOST_INSTANCE, sizeof(inst) - 1);
+    strncpy(inst, CLIENT_HOST_INSTANCE, SIZEOF(inst) - 1);
 #endif
-    inst[sizeof(inst) - 1] = '\0';
+    inst[SIZEOF(inst) - 1] = '\0';
 
     /*
      * Get a ticket with the user-defined service and instance,
@@ -1067,9 +1121,9 @@ add_ticket(kh, pkt, msg)
  * the req, + 1
  */
 static void
-add_mutual_auth(kh, msg)
-    struct krb4_handle *kh;
-    dgram_t *msg;
+add_mutual_auth(
+    struct krb4_handle *kh,
+    dgram_t *          msg)
 {
     union mutual mutual;
     char *security;
@@ -1079,12 +1133,13 @@ add_mutual_auth(kh, msg)
     assert(kh->cksum != 0);
     assert(kh->session_key[0] != '\0');
 
-    memset(&mutual, 0, sizeof(mutual));
-    mutual.cksum = htonl(kh->cksum + 1);
-    encrypt_data(&mutual, sizeof(mutual), &kh->session_key);
+    memset(&mutual, 0, SIZEOF(mutual));
+    mutual.cksum = (unsigned long)htonl((uint32_t)kh->cksum + 1);
+    encrypt_data(&mutual, SIZEOF(mutual), &kh->session_key);
 
     security = vstralloc("SECURITY MUTUAL-AUTH ",
-       bin2astr(mutual.pad, sizeof(mutual.pad)), "\n", NULL);
+       bin2astr((unsigned char *)mutual.pad,
+                       (int)sizeof(mutual.pad)), "\n", NULL);
     dgram_cat(msg, security);
     amfree(security);
 }
@@ -1095,9 +1150,9 @@ add_mutual_auth(kh, msg)
  * passed packet.
  */
 static int
-recv_security_ok(kh, pkt)
-    struct krb4_handle *kh;
-    pkt_t *pkt;
+recv_security_ok(
+    struct krb4_handle *kh,
+    pkt_t *            pkt)
 {
     char *tok, *security, *body;
     unsigned long cksum;
@@ -1121,7 +1176,7 @@ recv_security_ok(kh, pkt)
      * Increment the cur pointer past it to the data section after
      * parsing is finished.
      */
-    if (strncmp(pkt->body, "SECURITY", sizeof("SECURITY") - 1) == 0) {
+    if (strncmp(pkt->body, "SECURITY", SIZEOF("SECURITY") - 1) == 0) {
        tok = strtok(pkt->body, " ");
        assert(strcmp(tok, "SECURITY") == 0);
        /* security info goes until the newline */
@@ -1142,7 +1197,7 @@ recv_security_ok(kh, pkt)
     }
 
     /*
-     * Get a checksum of the non-security parts of the body 
+     * Get a checksum of the non-security parts of the body
      */
     cksum = krb4_cksum(body);
 
@@ -1229,11 +1284,11 @@ recv_security_ok(kh, pkt)
  * Check the ticket in a REQ packet for authenticity
  */
 static int
-check_ticket(kh, pkt, ticket_str, cksum)
-    struct krb4_handle *kh;
-    const pkt_t *pkt;
-    const char *ticket_str;
-    unsigned long cksum;
+check_ticket(
+    struct krb4_handle *kh,
+    const pkt_t *      pkt,
+    const char *       ticket_str,
+    unsigned long      cksum)
 {
     char inst[INST_SZ];
     KTEXT_ST ticket;
@@ -1246,17 +1301,17 @@ check_ticket(kh, pkt, ticket_str, cksum)
     assert(pkt != NULL);
     assert(ticket_str != NULL);
 
-    ticket.length = sizeof(ticket.dat);
-    astr2bin(ticket_str, ticket.dat, &ticket.length);
+    ticket.length = (int)sizeof(ticket.dat);
+    astr2bin((unsigned char *)ticket_str, ticket.dat, &ticket.length);
     assert(ticket.length > 0);
 
     /* get a copy of the instance into writable memory */
 #if CLIENT_HOST_INSTANCE == HOSTNAME_INSTANCE
-    strncpy(inst, krb_get_phost(hostname), sizeof(inst) - 1);
+    strncpy(inst, krb_get_phost(hostname), SIZEOF(inst) - 1);
 #else
-    strncpy(inst, CLIENT_HOST_INSTANCE, sizeof(inst) - 1);
+    strncpy(inst, CLIENT_HOST_INSTANCE, SIZEOF(inst) - 1);
 #endif
-    inst[sizeof(inst) - 1] = '\0';
+    inst[SIZEOF(inst) - 1] = '\0';
 
     /* get the checksum out of the ticket */
     rc = krb_rd_req(&ticket, CLIENT_HOST_PRINCIPLE, inst,
@@ -1275,8 +1330,8 @@ check_ticket(kh, pkt, ticket_str, cksum)
            kh->hostname, (long)auth.checksum, cksum);
        return (-1);
     }
-    kh->cksum = cksum;
-    memcpy(kh->session_key, auth.session, sizeof(kh->session_key));
+    kh->cksum = (unsigned long)cksum;
+    memcpy(kh->session_key, auth.session, SIZEOF(kh->session_key));
 
     /*
      * If FORCE_USERID is set, then we need to specifically
@@ -1313,9 +1368,9 @@ check_ticket(kh, pkt, ticket_str, cksum)
  * the same checksum as our request + 1.
  */
 static int
-check_mutual_auth(kh, mutual_auth_str)
-    struct krb4_handle *kh;
-    const char *mutual_auth_str;
+check_mutual_auth(
+    struct krb4_handle *kh,
+    const char *       mutual_auth_str)
 {
     union mutual mutual;
     int len;
@@ -1327,16 +1382,16 @@ check_mutual_auth(kh, mutual_auth_str)
     assert(kh->cksum != 0);
 
     /* convert the encoded string into binary data */
-    len = sizeof(mutual);
-    astr2bin(mutual_auth_str, (unsigned char *)&mutual, &len);
+    len = (int)sizeof(mutual);
+    astr2bin((unsigned char *)mutual_auth_str, (unsigned char *)&mutual, &len);
 
     /* unencrypt the string using the key in the ticket file */
     host2key(kh->hostname, kh->inst, &kh->session_key);
-    decrypt_data(&mutual, len, &kh->session_key);
-    mutual.cksum = ntohl(mutual.cksum);
+    decrypt_data(&mutual, (size_t)len, &kh->session_key);
+    mutual.cksum = (unsigned long)ntohl((uint32_t)mutual.cksum);
 
     /* the data must be the same as our request cksum + 1 */
-    if (mutual.cksum != kh->cksum + 1) {
+    if (mutual.cksum != (kh->cksum + 1)) {
        security_seterror(&kh->sech,
            "krb4 checksum mismatch from %s (remote=%lu, local=%lu)",
            kh->hostname, mutual.cksum, kh->cksum + 1);
@@ -1350,16 +1405,16 @@ check_mutual_auth(kh, mutual_auth_str)
  * Convert a pkt_t into a header string for our packet
  */
 static const char *
-pkthdr2str(kh, pkt)
-    const struct krb4_handle *kh;
-    const pkt_t *pkt;
+pkthdr2str(
+    const struct krb4_handle * kh,
+    const pkt_t *              pkt)
 {
     static char retbuf[256];
 
     assert(kh != NULL);
     assert(pkt != NULL);
 
-    snprintf(retbuf, sizeof(retbuf), "Amanda %d.%d %s HANDLE %s SEQ %d\n",
+    snprintf(retbuf, SIZEOF(retbuf), "Amanda %d.%d %s HANDLE %s SEQ %d\n",
        VERSION_MAJOR, VERSION_MINOR, pkt_type2str(pkt->type),
        kh->proto_handle, kh->sequence);
 
@@ -1374,12 +1429,12 @@ pkthdr2str(kh, pkt)
  * Returns negative on parse error.
  */
 static int
-str2pkthdr(origstr, pkt, handle, handlesize, sequence)
-    const char *origstr;
-    pkt_t *pkt;
-    char *handle;
-    size_t handlesize;
-    int *sequence;
+str2pkthdr(
+    const char *origstr,
+    pkt_t *    pkt,
+    char *     handle,
+    size_t     handlesize,
+    int *      sequence)
 {
     char *str;
     const char *tok;
@@ -1442,20 +1497,21 @@ parse_error:
 }
 
 static void
-host2key(hostname, inst, key)
-    const char *hostname, *inst;
-    des_cblock *key;
+host2key(
+    const char *hostname,
+    const char *inst,
+    des_cblock *key)
 {
     char realm[256];
     CREDENTIALS cred;
 
-    strncpy(realm, krb_realmofhost((char *)hostname), sizeof(realm) - 1);
-    realm[sizeof(realm) - 1] = '\0';
+    strncpy(realm, krb_realmofhost((char *)hostname), SIZEOF(realm) - 1);
+    realm[SIZEOF(realm) - 1] = '\0';
 #if CLIENT_HOST_INSTANCE != HOSTNAME_INSTANCE
     inst = CLIENT_HOST_INSTANCE
 #endif
     krb_get_cred(CLIENT_HOST_PRINCIPLE, (char *)inst, realm, &cred);
-    memcpy(key, cred.session, sizeof(des_cblock));
+    memcpy(key, cred.session, SIZEOF(des_cblock));
 }
 
 
@@ -1463,22 +1519,23 @@ host2key(hostname, inst, key)
  * Convert a chunk of data into a string.
  */
 static const char *
-bin2astr(buf, len)
-    const unsigned char *buf;
-    int len;
+bin2astr(
+    const unsigned char *buf,
+    int                        len)
 {
     static const char tohex[] = "0123456789ABCDEF";
     static char *str = NULL;
     char *q;
     const unsigned char *p;
-    int slen, i;
+    size_t slen;
+    int        i;
 
     /*
      * calculate output string len
      * We quote everything, so each input byte == 3 output chars, plus
      * two more for quotes
      */
-    slen = (len * 3) + 2;
+    slen = ((size_t)len * 3) + 2;
 
     /* allocate string and fill it in */
     if (str != NULL)
@@ -1497,7 +1554,7 @@ bin2astr(buf, len)
     *q = '\0';
 
     /* make sure we didn't overrun our allocated buffer */
-    assert(q - str == slen);
+    assert((size_t)(q - str) == slen);
 
     return (str);
 }
@@ -1506,12 +1563,12 @@ bin2astr(buf, len)
  * Convert an encoded string into a block of data bytes
  */
 static void
-astr2bin(astr, buf, lenp)
-    const char *astr;
-    unsigned char *buf;
-    int *lenp;
+astr2bin(
+    const unsigned char *astr,
+    unsigned char *    buf,
+    int *              lenp)
 {
-    const char *p;
+    const unsigned char *p;
     unsigned char *q;
 #define fromhex(h)     (isdigit((int)h) ? (h) - '0' : (h) - 'A' + 10)
 
@@ -1532,32 +1589,32 @@ astr2bin(astr, buf, lenp)
            *q++ = (fromhex(p[1]) << 4) + fromhex(p[2]);
             p += 3;
        }
-       if (q - buf >= *lenp)
+       if ((int)(q - buf) >= *lenp)
            break;
     }
     *lenp = q - buf;
 }
 
 static unsigned long
-krb4_cksum(str)
-    const char *str;
+krb4_cksum(
+    const char *str)
 {
     des_cblock seed;
 
-    memset(seed, 0, sizeof(seed));
+    memset(seed, 0, SIZEOF(seed));
     /*
      * The first arg is an unsigned char * in some krb4 implementations,
      * and in others, it's a des_cblock *.  Just make it void here
      * to shut them all up.
      */
-    return (quad_cksum((void *)str, NULL, strlen(str), 1, &seed));
+    return (quad_cksum((void *)str, NULL, (long)strlen(str), 1, &seed));
 }
 
 static void
-krb4_getinst(hname, inst, size)
-    const char *hname;
-    char *inst;
-    size_t size;
+krb4_getinst(
+    const char *hname,
+    char *     inst,
+    size_t     size)
 {
 
     /*
@@ -1573,10 +1630,10 @@ krb4_getinst(hname, inst, size)
 }
 
 static void
-encrypt_data(data, length, key)
-    void *data;
-    int length;
-    des_cblock *key;
+encrypt_data(
+    void *     data,
+    size_t     length,
+    des_cblock *key)
 {
     des_key_schedule sched;
 
@@ -1587,33 +1644,33 @@ encrypt_data(data, length, key)
      * arrays should be outlawed.
      */
     des_key_sched((void *)key, sched);
-    des_pcbc_encrypt(data, data, length, sched, key, DES_ENCRYPT);
+    des_pcbc_encrypt(data, data, (long)length, sched, key, DES_ENCRYPT);
 }
 
 
 static void
-decrypt_data(data, length, key)
-    void *data;
-    int length;
-    des_cblock *key;
+decrypt_data(
+    void *     data,
+    size_t     length,
+    des_cblock *key)
 {
     des_key_schedule sched;
 
     des_key_sched((void *)key, sched);
-    des_pcbc_encrypt(data, data, length, sched, key, DES_DECRYPT);
+    des_pcbc_encrypt(data, data, (long)length, sched, key, DES_DECRYPT);
 }
 
 /*
  * like write(), but always writes out the entire buffer.
  */
 static int
-net_write(fd, vbuf, size)
-    int fd;
-    const void *vbuf;
-    size_t size;
+net_write(
+    int                fd,
+    const void *vbuf,
+    size_t     size)
 {
     const char *buf = vbuf;    /* so we can do ptr arith */
-    int n;
+    ssize_t n;
 
     while (size > 0) {
        n = write(fd, buf, size);
@@ -1629,14 +1686,15 @@ net_write(fd, vbuf, size)
  * Like read(), but waits until the entire buffer has been filled.
  */
 static int
-net_read(fd, vbuf, size, timeout)
-    int fd;
-    void *vbuf;
-    size_t size;
-    int timeout;
+net_read(
+    int                fd,
+    void *     vbuf,
+    size_t     size,
+    int                timeout)
 {
     char *buf = vbuf;  /* ptr arith */
-    int n, neof = 0;
+    ssize_t n;
+    int neof = 0;
     fd_set readfds;
     struct timeval tv;
 
@@ -1677,10 +1735,10 @@ net_read(fd, vbuf, size, timeout)
 /* debug routines */
 
 static void
-print_hex(str,buf,len)
-const char *str;
-const unsigned char *buf;
-int len;
+print_hex(
+    const char *               str,
+    const unsigned char *      buf,
+    size_t                     len)
 {
     int i;
 
@@ -1693,9 +1751,9 @@ int len;
 }
 
 static void
-print_ticket(str, tktp)
-const char *str;
-KTEXT tktp;
+print_ticket(
+    const char *str,
+    KTEXT      tktp)
 {
     dbprintf(("%s: length %d chk %lX\n", str, tktp->length, tktp->mbz));
     print_hex("ticket data", tktp->dat, tktp->length);
@@ -1703,32 +1761,39 @@ KTEXT tktp;
 }
 
 static void
-print_auth(authp)
-AUTH_DAT *authp;
+print_auth(
+    AUTH_DAT *authp)
 {
     printf("\nAuth Data:\n");
     printf("  Principal \"%s\" Instance \"%s\" Realm \"%s\"\n",
           authp->pname, authp->pinst, authp->prealm);
     printf("  cksum %d life %d keylen %ld\n", authp->checksum,
-          authp->life, sizeof(authp->session));
-    print_hex("session key", authp->session, sizeof(authp->session));
+          authp->life, SIZEOF(authp->session));
+    print_hex("session key", authp->session, SIZEOF(authp->session));
     fflush(stdout);
 }
 
 static void
-print_credentials(credp)
-CREDENTIALS *credp;
+print_credentials(
+    CREDENTIALS *credp)
 {
     printf("\nCredentials:\n");
     printf("  service \"%s\" instance \"%s\" realm \"%s\" life %d kvno %d\n",
           credp->service, credp->instance, credp->realm, credp->lifetime,
           credp->kvno);
-    print_hex("session key", credp->session, sizeof(credp->session));
+    print_hex("session key", credp->session, SIZEOF(credp->session));
     print_hex("ticket", credp->ticket_st.dat, credp->ticket_st.length);
     fflush(stdout);
 }
 #endif
 
 #else
-void krb4_security_dummy (void) {}
+
+void krb4_security_dummy(void);
+
+void
+krb4_security_dummy(void)
+{
+}
+
 #endif /* KRB4_SECURITY */
index e1e78a0ca0138748c28a1930ebda8e5d0f823550..b7e6e710caaccad17d03783922071156b5aeafff 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*
- * $Id: krb5-security.c,v 1.12 2006/02/21 04:13:55 ktill Exp $
+ * $Id: krb5-security.c,v 1.22 2006/06/16 10:55:05 martinea Exp $
  *
  * krb5-security.c - kerberos V5 security module
  */
 #include "config.h"
 #ifdef KRB5_SECURITY
 #include "amanda.h"
+#include "util.h"
 #include "arglist.h"
 #include "event.h"
 #include "packet.h"
 #include "queue.h"
 #include "security.h"
+#include "security-util.h"
 #include "stream.h"
 #include "version.h"
 
@@ -192,14 +194,15 @@ struct krb5_handle {
     struct krb5_stream *ks;            /* virtual stream we xmit over */
 
     union {
-       void (*recvpkt) P((void *, pkt_t *, security_status_t));
+       void (*recvpkt)(void *, pkt_t *, security_status_t);
                                        /* func to call when packet recvd */
-       void (*connect) P((void *, security_handle_t *, security_status_t));
+       void (*connect)(void *, security_handle_t *, security_status_t);
                                        /* func to call when connected */
     } fn;
     void *arg;                         /* argument to pass function */
+    void *datap;                       /* argument to pass function */
     event_handle_t *ev_wait;           /* wait handle for connects */
-    char *(*conf_fn) P((char *, void *)); /* used to get config info */
+    char *(*conf_fn)(char *, void *); /* used to get config info */
     event_handle_t *ev_timeout;                /* timeout handle for recv */
 };
 
@@ -211,33 +214,35 @@ struct krb5_stream {
     struct krb5_conn *kc;              /* physical connection */
     int handle;                                /* protocol handle */
     event_handle_t *ev_read;           /* read (EV_WAIT) event handle */
-    void (*fn) P((void *, void *, int));       /* read event fn */
+    void (*fn)(void *, void *, ssize_t);/* read event fn */
     void *arg;                         /* arg for previous */
+    char buf[KRB5_STREAM_BUFSIZE];
+    ssize_t len;
 };
 
 /*
  * Interface functions
  */
-static int krb5_sendpkt P((void *, pkt_t *));
-static int krb5_stream_accept P((void *));
-static int krb5_stream_auth P((void *));
-static int krb5_stream_id P((void *));
-static int krb5_stream_write P((void *, const void *, size_t));
-static void *krb5_stream_client P((void *, int));
-static void *krb5_stream_server P((void *));
-static void krb5_accept P((int, int,
-    void (*)(security_handle_t *, pkt_t *)));
-static void krb5_close P((void *));
-static void krb5_connect P((const char *,
-    char *(*)(char *, void *),
-    void (*)(void *, security_handle_t *, security_status_t), void *));
-static void krb5_recvpkt P((void *,
-    void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void krb5_recvpkt_cancel P((void *));
-static void krb5_stream_close P((void *));
-static void krb5_stream_read P((void *, void (*)(void *, void *, int),
-    void *));
-static void krb5_stream_read_cancel P((void *));
+static ssize_t krb5_sendpkt(void *, pkt_t *);
+static int     krb5_stream_accept(void *);
+static int     krb5_stream_auth(void *);
+static int     krb5_stream_id(void *);
+static int     krb5_stream_write(void *, const void *, size_t);
+static void *  krb5_stream_client(void *, int);
+static void *  krb5_stream_server(void *);
+static void    krb5_accept(const struct security_driver *, int, int,
+                       void (*)(security_handle_t *, pkt_t *));
+static void    krb5_close(void *);
+static void    krb5_connect(const char *, char *(*)(char *, void *),
+                       void (*)(void *, security_handle_t *, security_status_t),
+                       void *, void *);
+static void    krb5_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
+                       void *, int);
+static void    krb5_recvpkt_cancel(void *);
+static void    krb5_stream_close(void *);
+static void    krb5_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
+static ssize_t krb5_stream_read_sync(void *, void **);
+static void    krb5_stream_read_cancel(void *);
 
 /*
  * This is our interface to the outside world.
@@ -258,7 +263,9 @@ const security_driver_t krb5_security_driver = {
     krb5_stream_id,
     krb5_stream_write,
     krb5_stream_read,
+    krb5_stream_read_sync,
     krb5_stream_read_cancel,
+    sec_close_connection_none,
 };
 
 /*
@@ -272,19 +279,19 @@ static char hostname[MAX_HOSTNAME_LENGTH+1];
 static struct {
     TAILQ_HEAD(, krb5_conn) tailq;
     int qlength;
-} connq = {
-    TAILQ_HEAD_INITIALIZER(connq.tailq), 0
+} krb5_connq = {
+    TAILQ_HEAD_INITIALIZER(krb5_connq.tailq), 0
 };
-#define        connq_first()           TAILQ_FIRST(&connq.tailq)
-#define        connq_next(kc)          TAILQ_NEXT(kc, tq)
-#define        connq_append(kc)        do {                                    \
-    TAILQ_INSERT_TAIL(&connq.tailq, kc, tq);                           \
-    connq.qlength++;                                                   \
+#define        krb5_connq_first()              TAILQ_FIRST(&krb5_connq.tailq)
+#define        krb5_connq_next(kc)             TAILQ_NEXT(kc, tq)
+#define        krb5_connq_append(kc)   do {                                    \
+    TAILQ_INSERT_TAIL(&krb5_connq.tailq, kc, tq);                              \
+    krb5_connq.qlength++;                                                      \
 } while (0)
-#define        connq_remove(kc)        do {                                    \
-    assert(connq.qlength > 0);                                         \
-    TAILQ_REMOVE(&connq.tailq, kc, tq);                                        \
-    connq.qlength--;                                                   \
+#define        krb5_connq_remove(kc)   do {                                    \
+    assert(krb5_connq.qlength > 0);                                            \
+    TAILQ_REMOVE(&krb5_connq.tailq, kc, tq);                                   \
+    krb5_connq.qlength--;                                                      \
 } while (0)
 
 static int newhandle = 1;
@@ -294,45 +301,40 @@ static int newhandle = 1;
  * created.  If NULL, no new handles are created.
  * It is passed the new handle and the received pkt
  */
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
+static void (*accept_fn)(security_handle_t *, pkt_t *);
 
 /*
  * Local functions
  */
-static void init P((void));
+static void init(void);
 #ifdef BROKEN_MEMORY_CCACHE
-static void cleanup P((void));
+static void cleanup(void);
 #endif
-static const char *get_tgt P((char *, char *));
-static void open_callback P((void *));
-static void connect_callback P((void *));
-static void connect_timeout P((void *));
-static int send_token P((struct krb5_conn *, int, const gss_buffer_desc *));
-static int recv_token P((struct krb5_conn *, int *, gss_buffer_desc *, int));
-static void recvpkt_callback P((void *, void *, ssize_t));
-static void recvpkt_timeout P((void *));
-static void stream_read_callback P((void *));
-static int gss_server P((struct krb5_conn *));
-static int gss_client P((struct krb5_handle *));
-static const char *gss_error P((OM_uint32, OM_uint32));
+static const char *get_tgt(char *, char *);
+static void    open_callback(void *);
+static void    connect_callback(void *);
+static void    connect_timeout(void *);
+static int     send_token(struct krb5_conn *, int, const gss_buffer_desc *);
+static ssize_t recv_token(struct krb5_conn *, int *, gss_buffer_desc *, int);
+static void    recvpkt_callback(void *, void *, ssize_t);
+static void    recvpkt_timeout(void *);
+static void    stream_read_callback(void *);
+static void    stream_read_sync_callback2(void *, void *, ssize_t);
+static int     gss_server(struct krb5_conn *);
+static int     gss_client(struct krb5_handle *);
+static const char *gss_error(OM_uint32, OM_uint32);
 
 #ifdef AMANDA_KRB5_ENCRYPT
-static int kdecrypt P((struct krb5_stream *, gss_buffer_desc *,
-    gss_buffer_desc *));
-static int kencrypt P((struct krb5_stream *, gss_buffer_desc *,
-    gss_buffer_desc *));
+static int     kdecrypt(struct krb5_stream *, gss_buffer_desc *, gss_buffer_desc *);
+static int     kencrypt(struct krb5_stream *, gss_buffer_desc *, gss_buffer_desc *);
 #endif
-static struct krb5_conn *conn_get P((const char *));
-static void conn_put P((struct krb5_conn *));
-static void conn_read P((struct krb5_conn *));
-static void conn_read_cancel P((struct krb5_conn *));
-static void conn_read_callback P((void *));
-static int conn_run_frameq P((struct krb5_conn *, struct krb5_stream *));
-static int net_writev P((int, struct iovec *, int));
-static ssize_t net_read P((struct krb5_conn *, void *, size_t, int));
-static int net_read_fillbuf P((struct krb5_conn *, int));
-static char *krb5_checkuser(char *, char *, char *);
-static void parse_pkt P((pkt_t *, const void *, size_t));
+static struct krb5_conn *conn_get(const char *);
+static void    conn_put(struct krb5_conn *);
+static void    conn_read(struct krb5_conn *);
+static void    conn_read_cancel(struct krb5_conn *);
+static void    conn_read_callback(void *);
+static int     conn_run_frameq(struct krb5_conn *, struct krb5_stream *);
+static char *  krb5_checkuser(char *, char *, char *);
 
 
 /*
@@ -340,16 +342,18 @@ static void parse_pkt P((pkt_t *, const void *, size_t));
  * up a network "connection".
  */
 static void
-krb5_connect(hostname, conf_fn, fn, arg)
-    const char *hostname;
-    char *(*conf_fn) P((char *, void *));
-    void (*fn) P((void *, security_handle_t *, security_status_t));
-    void *arg;
+krb5_connect(
+    const char *hostname,
+    char *     (*conf_fn)(char *, void *),
+    void       (*fn)(void *, security_handle_t *, security_status_t),
+    void *     arg,
+    void *     datap)
 {
     struct krb5_handle *kh;
     struct hostent *he;
     struct servent *se;
-    int port, fd;
+    int fd;
+    int port;
     const char *err;
     char *keytab_name = NULL;
     char *principal_name = NULL;
@@ -363,7 +367,7 @@ krb5_connect(hostname, conf_fn, fn, arg)
      */
     init();
 
-    kh = alloc(sizeof(*kh));
+    kh = alloc(SIZEOF(*kh));
     security_handleinit(&kh->sech, &krb5_security_driver);
     kh->hostname = NULL;
     kh->ks = NULL;
@@ -374,14 +378,14 @@ krb5_connect(hostname, conf_fn, fn, arg)
     keytab_name = AMANDA_KEYTAB;
 #else
     if(conf_fn) {
-       keytab_name = conf_fn("krb5keytab", arg);
+       keytab_name = conf_fn("krb5keytab", datap);
     }
 #endif
 #ifdef AMANDA_PRINCIPAL
     principal_name = AMANDA_PRINCIPAL;
 #else
     if(conf_fn) {
-       principal_name = conf_fn("krb5principal", arg);
+       principal_name = conf_fn("krb5principal", datap);
     }
 #endif
 
@@ -401,6 +405,7 @@ krb5_connect(hostname, conf_fn, fn, arg)
     kh->fn.connect = fn;
     kh->conf_fn = conf_fn;
     kh->arg = arg;
+    kh->datap = datap;
     kh->hostname = stralloc(he->h_name);
     kh->ks = krb5_stream_client(kh, newhandle++);
 
@@ -414,9 +419,9 @@ krb5_connect(hostname, conf_fn, fn, arg)
         * We need to open a new connection.  See if we have too
         * many connections open.
         */
-       if (connq.qlength > AMANDA_KRB5_MAXCONN) {
+       if (krb5_connq.qlength > AMANDA_KRB5_MAXCONN) {
            k5printf(("krb5_connect: too many conections (%d), delaying %s\n",
-               connq.qlength, kh->hostname));
+               krb5_connq.qlength, kh->hostname));
            krb5_stream_close(kh->ks);
            kh->ev_wait = event_register((event_id_t)open_callback,
                EV_WAIT, open_callback, kh);
@@ -447,8 +452,10 @@ krb5_connect(hostname, conf_fn, fn, arg)
      * so we will know when the socket comes alive.
      * We also register a timeout.
      */
-    kh->ev_wait = event_register(fd, EV_WRITEFD, connect_callback, kh);
-    kh->ev_timeout = event_register(GSS_TIMEOUT, EV_TIME, connect_timeout, kh);
+    kh->ev_wait = event_register((event_id_t)fd, EV_WRITEFD,
+               connect_callback, kh);
+    kh->ev_timeout = event_register((event_id_t)GSS_TIMEOUT, EV_TIME,
+               connect_timeout, kh);
 
     return;
 
@@ -461,8 +468,8 @@ error:
  * we can open more.
  */
 static void
-open_callback(cookie)
-    void *cookie;
+open_callback(
+    void *     cookie)
 {
     struct krb5_handle *kh = cookie;
 
@@ -470,7 +477,7 @@ open_callback(cookie)
 
     k5printf(("krb5: open_callback: possible connections available, retry %s\n",
        kh->hostname));
-    krb5_connect(kh->hostname, kh->conf_fn, kh->fn.connect, kh->arg);
+    krb5_connect(kh->hostname, kh->conf_fn, kh->fn.connect, kh->arg,kh->datap);
     amfree(kh->hostname);
     amfree(kh);
 }
@@ -480,8 +487,8 @@ open_callback(cookie)
  * to be authenticated.
  */
 static void
-connect_callback(cookie)
-    void *cookie;
+connect_callback(
+    void *     cookie)
 {
     struct krb5_handle *kh = cookie;
 
@@ -506,8 +513,8 @@ connect_callback(cookie)
  * Called if a connection times out before completion.
  */
 static void
-connect_timeout(cookie)
-    void *cookie;
+connect_timeout(
+    void *     cookie)
 {
     struct krb5_handle *kh = cookie;
 
@@ -523,12 +530,14 @@ connect_timeout(cookie)
  * Setup to handle new incoming connections
  */
 static void
-krb5_accept(in, out, fn)
-    int in, out;
-    void (*fn) P((security_handle_t *, pkt_t *));
+krb5_accept(
+    const struct security_driver *driver,
+    int                in,
+    int                out,
+    void       (*fn)(security_handle_t *, pkt_t *))
 {
     struct sockaddr_in sin;
-    size_t len;
+    socklen_t len;
     struct krb5_conn *kc;
     struct hostent *he;
 
@@ -537,10 +546,14 @@ krb5_accept(in, out, fn)
      */
     init();
 
-    len = sizeof(sin);
+    /* shut up compiler */
+    driver=driver;
+    out=out;
+
+    len = SIZEOF(sin);
     if (getpeername(in, (struct sockaddr *)&sin, &len) < 0)
        return;
-    he = gethostbyaddr((void *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET);
+    he = gethostbyaddr((void *)&sin.sin_addr, SIZEOF(sin.sin_addr), AF_INET);
     if (he == NULL)
        return;
 
@@ -559,14 +572,14 @@ krb5_accept(in, out, fn)
  * for the lack of a connection (kc->fd == -1) and set one up.
  */
 static struct krb5_conn *
-conn_get(hostname)
-    const char *hostname;
+conn_get(
+    const char *       hostname)
 {
     struct krb5_conn *kc;
 
     k5printf(("krb5: conn_get: %s\n", hostname));
 
-    for (kc = connq_first(); kc != NULL; kc = connq_next(kc)) {
+    for (kc = krb5_connq_first(); kc != NULL; kc = krb5_connq_next(kc)) {
        if (strcasecmp(hostname, kc->hostname) == 0)
            break;
     }
@@ -583,14 +596,14 @@ conn_get(hostname)
      * We can't be creating a new handle if we are the client
      */
     assert(accept_fn == NULL);
-    kc = alloc(sizeof(*kc));
+    kc = alloc(SIZEOF(*kc));
     kc->fd = -1;
     kc->readbuf.left = 0;
     kc->readbuf.size = 0;
     kc->state = unauthed;
     kc->ev_read = NULL;
-    strncpy(kc->hostname, hostname, sizeof(kc->hostname) - 1);
-    kc->hostname[sizeof(kc->hostname) - 1] = '\0';
+    strncpy(kc->hostname, hostname, SIZEOF(kc->hostname) - 1);
+    kc->hostname[SIZEOF(kc->hostname) - 1] = '\0';
     kc->errmsg = NULL;
     kc->gss_context = GSS_C_NO_CONTEXT;
     /*
@@ -601,7 +614,7 @@ conn_get(hostname)
      */
     kc->refcnt = 2;
     TAILQ_INIT(&kc->frameq);
-    connq_append(kc);
+    krb5_connq_append(kc);
     return (kc);
 }
 
@@ -610,8 +623,8 @@ conn_get(hostname)
  * reference.
  */
 static void
-conn_put(kc)
-    struct krb5_conn *kc;
+conn_put(
+    struct krb5_conn * kc)
 {
     OM_uint32 min_stat;
     struct krb5_frame *kf;
@@ -636,7 +649,7 @@ conn_put(kc)
            amfree(kf->tok.value);
        amfree(kf);
     }
-    connq_remove(kc);
+    krb5_connq_remove(kc);
     amfree(kc);
     /* signal that a connection is available */
     event_wakeup((event_id_t)open_callback);
@@ -647,8 +660,8 @@ conn_put(kc)
  * already receiving read events.
  */
 static void
-conn_read(kc)
-    struct krb5_conn *kc;
+conn_read(
+    struct krb5_conn *kc)
 {
 
     if (kc->ev_read != NULL) {
@@ -659,13 +672,13 @@ conn_read(kc)
     }
     k5printf(("krb5: conn_read registering event handler for %s\n",
        kc->hostname));
-    kc->ev_read = event_register(kc->fd, EV_READFD, conn_read_callback, kc);
+    kc->ev_read = event_register((event_id_t)kc->fd, EV_READFD, conn_read_callback, kc);
     kc->ev_read_refcnt = 1;
 }
 
 static void
-conn_read_cancel(kc)
-    struct krb5_conn *kc;
+conn_read_cancel(
+    struct krb5_conn * kc)
 {
 
     if (--kc->ev_read_refcnt > 0) {
@@ -683,8 +696,8 @@ conn_read_cancel(kc)
  * frees a handle allocated by the above
  */
 static void
-krb5_close(inst)
-    void *inst;
+krb5_close(
+    void *     inst)
 {
     struct krb5_handle *kh = inst;
 
@@ -704,15 +717,15 @@ krb5_close(inst)
 /*
  * Transmit a packet.  Encrypt first.
  */
-static int
-krb5_sendpkt(cookie, pkt)
-    void *cookie;
-    pkt_t *pkt;
+static ssize_t
+krb5_sendpkt(
+    void *     cookie,
+    pkt_t *    pkt)
 {
     struct krb5_handle *kh = cookie;
     gss_buffer_desc tok;
     int rval;
-    unsigned char c, *buf;
+    unsigned char *buf;
 
     assert(kh != NULL);
     assert(pkt != NULL);
@@ -720,15 +733,15 @@ krb5_sendpkt(cookie, pkt)
     k5printf(("krb5: sendpkt: enter\n"));
 
     if (pkt->body[0] == '\0') {
-       c = (unsigned char)pkt->type;
        tok.length = 1;
-       tok.value = &c;
+       tok.value = alloc(SIZEOF(pkt->type));
+       memcpy(tok.value, &pkt->type, sizeof(unsigned char));
     } else {
        tok.length = strlen(pkt->body) + 2;
        tok.value = alloc(tok.length);
        buf = tok.value;
        *buf++ = (unsigned char)pkt->type;
-       strncpy(buf, pkt->body, tok.length - 2);
+       strncpy((char *)buf, pkt->body, tok.length - 2);
        buf[tok.length - 2] = '\0';
     }
 
@@ -738,8 +751,9 @@ krb5_sendpkt(cookie, pkt)
     rval = krb5_stream_write(kh->ks, tok.value, tok.length);
     if (rval < 0)
        security_seterror(&kh->sech, security_stream_geterror(&kh->ks->secstr));
-    if (tok.length > 1)
-       amfree(tok.value);
+    /*@ignore@*/
+    amfree(tok.value);
+    /*@end@*/
     return (rval);
 }
 
@@ -748,10 +762,11 @@ krb5_sendpkt(cookie, pkt)
  * it has been read.
  */
 static void
-krb5_recvpkt(cookie, fn, arg, timeout)
-    void *cookie, *arg;
-    void (*fn) P((void *, pkt_t *, security_status_t));
-    int timeout;
+krb5_recvpkt(
+    void *     cookie,
+    void       (*fn)(void *, pkt_t *, security_status_t),
+    void *     arg,
+    int                timeout)
 {
     struct krb5_handle *kh = cookie;
 
@@ -771,7 +786,8 @@ krb5_recvpkt(cookie, fn, arg, timeout)
     if (timeout < 0)
        kh->ev_timeout = NULL;
     else
-       kh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, kh);
+       kh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
+               recvpkt_timeout, kh);
 
     kh->fn.recvpkt = fn;
     kh->arg = arg;
@@ -782,8 +798,8 @@ krb5_recvpkt(cookie, fn, arg, timeout)
  * Remove a async receive request from the queue
  */
 static void
-krb5_recvpkt_cancel(cookie)
-    void *cookie;
+krb5_recvpkt_cancel(
+    void *     cookie)
 {
     struct krb5_handle *kh = cookie;
 
@@ -803,9 +819,10 @@ krb5_recvpkt_cancel(cookie)
  * net is for it.
  */
 static void
-recvpkt_callback(cookie, buf, bufsize)
-    void *cookie, *buf;
-    ssize_t bufsize;
+recvpkt_callback(
+    void *cookie,
+    void *buf,
+    ssize_t bufsize)
 {
     pkt_t pkt;
     struct krb5_handle *kh = cookie;
@@ -829,7 +846,7 @@ recvpkt_callback(cookie, buf, bufsize)
        (*kh->fn.recvpkt)(kh->arg, NULL, S_ERROR);
        return;
     default:
-       parse_pkt(&pkt, buf, bufsize);
+       parse_pkt(&pkt, buf, (size_t)bufsize);
        k5printf(("krb5: received %s pkt (%d) from %s, contains:\n\n\"%s\"\n\n",
            pkt_type2str(pkt.type), pkt.type, kh->hostname, pkt.body));
        (*kh->fn.recvpkt)(kh->arg, &pkt, S_OK);
@@ -841,8 +858,8 @@ recvpkt_callback(cookie, buf, bufsize)
  * This is called when a handle times out before receiving a packet.
  */
 static void
-recvpkt_timeout(cookie)
-    void *cookie;
+recvpkt_timeout(
+    void *     cookie)
 {
     struct krb5_handle *kh = cookie;
 
@@ -859,15 +876,15 @@ recvpkt_timeout(cookie)
  * object and allocate a new handle for it.
  */
 static void *
-krb5_stream_server(h)
-    void *h;
+krb5_stream_server(
+    void *     h)
 {
     struct krb5_handle *kh = h;
     struct krb5_stream *ks;
 
     assert(kh != NULL);
 
-    ks = alloc(sizeof(*ks));
+    ks = alloc(SIZEOF(*ks));
     security_streaminit(&ks->secstr, &krb5_security_driver);
     ks->kc = conn_get(kh->hostname);
     /*
@@ -883,7 +900,7 @@ krb5_stream_server(h)
      * so as not to conflict with the amanda server's handle numbers,
      * we start at 5000 and work down
      */
-    ks->handle = 5000 - newhandle++;
+    ks->handle = (int)(5000 - newhandle++);
     ks->ev_read = NULL;
     k5printf(("krb5: stream_server: created stream %d\n", ks->handle));
     return (ks);
@@ -894,10 +911,13 @@ krb5_stream_server(h)
  * Nothing needed for krb5.
  */
 static int
-krb5_stream_accept(s)
-    void *s;
+krb5_stream_accept(
+    void *     s)
 {
 
+    /* shut up compiler */
+    s = s;
+
     return (0);
 }
 
@@ -906,9 +926,9 @@ krb5_stream_accept(s)
  * with the supplied handle.
  */
 static void *
-krb5_stream_client(h, id)
-    void *h;
-    int id;
+krb5_stream_client(
+    void *     h,
+    int                id)
 {
     struct krb5_handle *kh = h;
     struct krb5_stream *ks;
@@ -921,9 +941,9 @@ krb5_stream_client(h, id)
        return (NULL);
     }
 
-    ks = alloc(sizeof(*ks));
+    ks = alloc(SIZEOF(*ks));
     security_streaminit(&ks->secstr, &krb5_security_driver);
-    ks->handle = id;
+    ks->handle = (int)id;
     ks->ev_read = NULL;
     ks->kc = conn_get(kh->hostname);
 
@@ -936,8 +956,8 @@ krb5_stream_client(h, id)
  * Close and unallocate resources for a stream.
  */
 static void
-krb5_stream_close(s)
-    void *s;
+krb5_stream_close(
+    void *     s)
 {
     struct krb5_stream *ks = s;
 
@@ -956,9 +976,11 @@ krb5_stream_close(s)
  * on startup.
  */
 static int
-krb5_stream_auth(s)
-    void *s;
+krb5_stream_auth(
+    void *     s)
 {
+    /* shut up compiler */
+    s = s;
 
     return (0);
 }
@@ -968,8 +990,8 @@ krb5_stream_auth(s)
  * port.
  */
 static int
-krb5_stream_id(s)
-    void *s;
+krb5_stream_id(
+    void *     s)
 {
     struct krb5_stream *ks = s;
 
@@ -982,10 +1004,10 @@ krb5_stream_id(s)
  * Write a chunk of data to a stream.  Blocks until completion.
  */
 static int
-krb5_stream_write(s, buf, size)
-    void *s;
-    const void *buf;
-    size_t size;
+krb5_stream_write(
+    void *     s,
+    const void *buf,
+    size_t     size)
 {
     struct krb5_stream *ks = s;
     gss_buffer_desc tok;
@@ -1022,9 +1044,10 @@ krb5_stream_write(s, buf, size)
  * function and arg when completed.
  */
 static void
-krb5_stream_read(s, fn, arg)
-    void *s, *arg;
-    void (*fn) P((void *, void *, int));
+krb5_stream_read(
+    void *     s,
+    void       (*fn)(void *, void *, ssize_t),
+    void *     arg)
 {
     struct krb5_stream *ks = s;
 
@@ -1050,13 +1073,70 @@ krb5_stream_read(s, fn, arg)
     }
 }
 
+/*
+ * Submit a request to read some data.  Calls back with the given
+ * function and arg when completed.
+ */
+static ssize_t
+krb5_stream_read_sync(
+    void *     s,
+    void       **buf)
+{
+    struct krb5_stream *ks = s;
+
+    assert(ks != NULL);
+
+    /*
+     * Only one read request can be active per stream.
+     */
+    ks->fn = stream_read_sync_callback2;
+    ks->arg = ks;
+
+    /*
+     * First see if there's any queued frames for this stream.
+     * If so, we're done.
+     */
+    if (conn_run_frameq(ks->kc, ks) > 0)
+       return ks->len;
+
+    if (ks->ev_read != NULL)
+       event_release(ks->ev_read);
+
+    ks->ev_read = event_register((event_id_t)ks->kc, EV_WAIT,
+       stream_read_callback, ks);
+    conn_read(ks->kc);
+    event_wait(ks->ev_read);
+    buf = (void **)&ks->buf;
+    return ks->len;
+}
+
+
+/*
+ * Callback for krb5_stream_read_sync
+ */
+static void
+stream_read_sync_callback2(
+    void *     arg,
+    void *     buf,
+    ssize_t    size)
+{
+    struct krb5_stream *ks = arg;
+
+    assert(ks != NULL);
+
+    k5printf(("krb5: stream_read_sync_callback2: handle %d\n", ks->handle));
+
+    memcpy(ks->buf, buf, (size_t)size);
+    ks->len = size;
+}
+
 /*
  * Cancel a previous stream read request.  It's ok if we didn't have a read
  * scheduled.
  */
 static void
-krb5_stream_read_cancel(s)
-    void *s;
+krb5_stream_read_cancel(
+    void *     s)
 {
     struct krb5_stream *ks = s;
 
@@ -1073,8 +1153,8 @@ krb5_stream_read_cancel(s)
  * Callback for krb5_stream_read
  */
 static void
-stream_read_callback(arg)
-    void *arg;
+stream_read_callback(
+    void *     arg)
 {
     struct krb5_stream *ks = arg;
 
@@ -1093,9 +1173,9 @@ stream_read_callback(arg)
  * Returns 1 if a frame was found and processed.
  */
 static int
-conn_run_frameq(kc, ks)
-    struct krb5_conn *kc;
-    struct krb5_stream *ks;
+conn_run_frameq(
+    /*@keep@*/ struct krb5_conn *      kc,
+    /*@keep@*/ struct krb5_stream *    ks)
 {
     struct krb5_frame *kf, *nextkf;
     gss_buffer_desc *enctok, *dectok;
@@ -1154,7 +1234,7 @@ conn_run_frameq(kc, ks)
        {
            k5printf(("krb5: stream_read_callback: read %d bytes from %s:%d\n",
                dectok->length, ks->kc->hostname, ks->handle));
-           (*ks->fn)(ks->arg, dectok->value, dectok->length);
+           (*ks->fn)(ks->arg, dectok->value, (ssize_t)dectok->length);
 #ifdef AMANDA_KRB5_ENCRYPT
            gss_release_buffer(&min_stat, dectok);
 #endif
@@ -1172,8 +1252,8 @@ conn_run_frameq(kc, ks)
  * and does the real callback if so.
  */
 static void
-conn_read_callback(cookie)
-    void *cookie;
+conn_read_callback(
+    void *     cookie)
 {
     struct krb5_conn *kc = cookie;
     struct krb5_handle *kh;
@@ -1190,7 +1270,7 @@ conn_read_callback(cookie)
 
     k5printf(("krb5: conn_read_callback\n"));
 
-    kf = alloc(sizeof(*kf));
+    kf = alloc(SIZEOF(*kf));
     TAILQ_INSERT_TAIL(&kc->frameq, kf, tq);
 
     /* Read the data off the wire.  If we get errors, shut down. */
@@ -1221,7 +1301,7 @@ conn_read_callback(cookie)
        return;
     }
 
-    kh = alloc(sizeof(*kh));
+    kh = alloc(SIZEOF(*kh));
     security_handleinit(&kh->sech, &krb5_security_driver);
     kh->hostname = stralloc(kc->hostname);
     kh->ks = krb5_stream_client(kh, kf->handle);
@@ -1274,8 +1354,8 @@ conn_read_callback(cookie)
  * Negotiate a krb5 gss context from the client end.
  */
 static int
-gss_client(kh)
-    struct krb5_handle *kh;
+gss_client(
+    struct krb5_handle *kh)
 {
     struct krb5_stream *ks = kh->ks;
     struct krb5_conn *kc = ks->kc;
@@ -1291,7 +1371,7 @@ gss_client(kh)
     send_tok.length = strlen(send_tok.value) + 1;
     maj_stat = gss_import_name(&min_stat, &send_tok, GSS_C_NULL_OID,
        &gss_name);
-    if (maj_stat != GSS_S_COMPLETE) {
+    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
        security_seterror(&kh->sech, "can't import name %s: %s",
            (char *)send_tok.value, gss_error(maj_stat, min_stat));
        amfree(send_tok.value);
@@ -1314,6 +1394,7 @@ gss_client(kh)
      * and only if the server has another token to send us.
      */
 
+    recv_tok.value = NULL;
     for (recv_tok.length = 0;;) {
        min_stat = 0;
        maj_stat = gss_init_sec_context(&min_stat,
@@ -1321,7 +1402,7 @@ gss_client(kh)
            &kc->gss_context,
            gss_name,
            GSS_C_NULL_OID,
-           GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG,
+           (OM_uint32)GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG,
            0, NULL,    /* no channel bindings */
            (recv_tok.length == 0 ? GSS_C_NO_BUFFER : &recv_tok),
            NULL,       /* ignore mech type */
@@ -1334,7 +1415,7 @@ gss_client(kh)
            recv_tok.length = 0;
        }
 
-       if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
+       if (maj_stat != (OM_uint32)GSS_S_COMPLETE && maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) {
            security_seterror(&kh->sech,
                "error getting gss context: %s",
                gss_error(maj_stat, min_stat));
@@ -1354,7 +1435,7 @@ gss_client(kh)
        /*
         * If we need to continue, then register for more packets
         */
-       if (maj_stat != GSS_S_CONTINUE_NEEDED)
+       if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED)
            break;
 
        if ((rc = recv_token(kc, NULL, &recv_tok, GSS_TIMEOUT)) <= 0) {
@@ -1377,8 +1458,8 @@ done:
  * Negotiate a krb5 gss context from the server end.
  */
 static int
-gss_server(kc)
-    struct krb5_conn *kc;
+gss_server(
+    struct krb5_conn * kc)
 {
     OM_uint32 maj_stat, min_stat, ret_flags;
     gss_buffer_desc send_tok, recv_tok;
@@ -1401,13 +1482,13 @@ gss_server(kc)
      */
     euid = geteuid();
     if (getuid() != 0) {
-       snprintf(errbuf, sizeof(errbuf),
+       snprintf(errbuf, SIZEOF(errbuf),
            "real uid is %ld, needs to be 0 to read krb5 host key",
            (long)getuid());
        goto out;
     }
     if (seteuid(0) < 0) {
-       snprintf(errbuf, sizeof(errbuf),
+       snprintf(errbuf, SIZEOF(errbuf),
            "can't seteuid to uid 0: %s", strerror(errno));
        goto out;
     }
@@ -1420,9 +1501,9 @@ gss_server(kc)
     }
     maj_stat = gss_import_name(&min_stat, &send_tok, GSS_C_NULL_OID,
        &gss_name);
-    if (maj_stat != GSS_S_COMPLETE) {
+    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
        seteuid(euid);
-       snprintf(errbuf, sizeof(errbuf),
+       snprintf(errbuf, SIZEOF(errbuf),
            "can't import name %s: %s", (char *)send_tok.value,
            gss_error(maj_stat, min_stat));
        amfree(send_tok.value);
@@ -1432,8 +1513,8 @@ gss_server(kc)
 
     maj_stat = gss_acquire_cred(&min_stat, gss_name, 0,
        GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &gss_creds, NULL, NULL);
-    if (maj_stat != GSS_S_COMPLETE) {
-       snprintf(errbuf, sizeof(errbuf),
+    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
+       snprintf(errbuf, SIZEOF(errbuf),
            "can't acquire creds for host key host/%s: %s", hostname,
            gss_error(maj_stat, min_stat));
        gss_release_name(&min_stat, &gss_name);
@@ -1445,11 +1526,11 @@ gss_server(kc)
     for (recv_tok.length = 0;;) {
        if ((rc = recv_token(kc, NULL, &recv_tok, GSS_TIMEOUT)) <= 0) {
            if (rc < 0) {
-               snprintf(errbuf, sizeof(errbuf),
+               snprintf(errbuf, SIZEOF(errbuf),
                    "recv error in gss loop: %s", kc->errmsg);
                amfree(kc->errmsg);
            } else
-               snprintf(errbuf, sizeof(errbuf), "EOF in gss loop");
+               snprintf(errbuf, SIZEOF(errbuf), "EOF in gss loop");
            goto out;
        }
 
@@ -1457,9 +1538,9 @@ gss_server(kc)
            gss_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS,
            &gss_name, &doid, &send_tok, &ret_flags, NULL, NULL);
 
-       if (maj_stat != GSS_S_COMPLETE &&
-           maj_stat != GSS_S_CONTINUE_NEEDED) {
-           snprintf(errbuf, sizeof(errbuf),
+       if (maj_stat != (OM_uint32)GSS_S_COMPLETE &&
+           maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) {
+           snprintf(errbuf, SIZEOF(errbuf),
                "error accepting context: %s", gss_error(maj_stat, min_stat));
            amfree(recv_tok.value);
            goto out;
@@ -1467,8 +1548,8 @@ gss_server(kc)
        amfree(recv_tok.value);
 
        if (send_tok.length > 0 && send_token(kc, 0, &send_tok) < 0) {
-           strncpy(errbuf, kc->errmsg, sizeof(errbuf) - 1);
-           errbuf[sizeof(errbuf) - 1] = '\0';
+           strncpy(errbuf, kc->errmsg, SIZEOF(errbuf) - 1);
+           errbuf[SIZEOF(errbuf) - 1] = '\0';
            amfree(kc->errmsg);
            gss_release_buffer(&min_stat, &send_tok);
            goto out;
@@ -1480,13 +1561,13 @@ gss_server(kc)
         * If we need to get more from the client, then register for
         * more packets.
         */
-       if (maj_stat != GSS_S_CONTINUE_NEEDED)
+       if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED)
            break;
     }
 
     maj_stat = gss_display_name(&min_stat, gss_name, &send_tok, &doid);
-    if (maj_stat != GSS_S_COMPLETE) {
-       snprintf(errbuf, sizeof(errbuf),
+    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
+       snprintf(errbuf, SIZEOF(errbuf),
            "can't display gss name: %s", gss_error(maj_stat, min_stat));
        gss_release_name(&min_stat, &gss_name);
        goto out;
@@ -1495,7 +1576,7 @@ gss_server(kc)
 
     /* get rid of the realm */
     if ((p = strchr(send_tok.value, '@')) == NULL) {
-       snprintf(errbuf, sizeof(errbuf),
+       snprintf(errbuf, SIZEOF(errbuf),
            "malformed gss name: %s", (char *)send_tok.value);
        amfree(send_tok.value);
        goto out;
@@ -1507,7 +1588,7 @@ gss_server(kc)
      * If the principal doesn't match, complain
      */
     if ((msg = krb5_checkuser(kc->hostname, send_tok.value, realm)) != NULL) {
-       snprintf(errbuf, sizeof(errbuf),
+       snprintf(errbuf, SIZEOF(errbuf),
            "access not allowed from %s: %s", (char *)send_tok.value, msg);
        amfree(send_tok.value);
        goto out;
@@ -1527,19 +1608,18 @@ out:
  * Setup some things about krb5.  This should only be called once.
  */
 static void
-init()
+init(void)
 {
     static int beenhere = 0;
     struct hostent *he;
     char *p;
-    int krb5_setenv P((const char *, const char *, int));
 
     if (beenhere)
        return;
     beenhere = 1;
 
 #ifndef BROKEN_MEMORY_CCACHE
-    krb5_setenv(KRB5_ENV_CCNAME, "MEMORY:amanda_ccache", 1);
+    setenv(KRB5_ENV_CCNAME, "MEMORY:amanda_ccache", 1);
 #else
     /*
      * MEMORY ccaches seem buggy and cause a lot of internal heap
@@ -1552,19 +1632,19 @@ init()
     atexit(cleanup);
     {
        char ccache[64];
-       snprintf(ccache, sizeof(ccache), "FILE:/tmp/amanda_ccache.%ld.%ld",
+       snprintf(ccache, SIZEOF(ccache), "FILE:/tmp/amanda_ccache.%ld.%ld",
            (long)geteuid(), (long)getpid());
-       krb5_setenv(KRB5_ENV_CCNAME, ccache, 1);
+       setenv(KRB5_ENV_CCNAME, ccache, 1);
     }
 #endif
 
-    gethostname(hostname, sizeof(hostname) - 1);
-    hostname[sizeof(hostname) - 1] = '\0';
+    gethostname(hostname, SIZEOF(hostname) - 1);
+    hostname[SIZEOF(hostname) - 1] = '\0';
     /*
      * In case it isn't fully qualified, do a DNS lookup.
      */
     if ((he = gethostbyname(hostname)) != NULL)
-       strncpy(hostname, he->h_name, sizeof(hostname) - 1);
+       strncpy(hostname, he->h_name, SIZEOF(hostname) - 1);
 
     /*
      * Lowercase the results.  We assume all host/ principals will be
@@ -1578,11 +1658,11 @@ init()
 
 #ifdef BROKEN_MEMORY_CCACHE
 static void
-cleanup()
+cleanup(void)
 {
 #ifdef KDESTROY_VIA_UNLINK
     char ccache[64];
-    snprintf(ccache, sizeof(ccache), "/tmp/amanda_ccache.%ld.%ld",
+    snprintf(ccache, SIZEOF(ccache), "/tmp/amanda_ccache.%ld.%ld",
         (long)geteuid(), (long)getpid());
     unlink(ccache);
 #else
@@ -1595,8 +1675,9 @@ cleanup()
  * Get a ticket granting ticket and stuff it in the cache
  */
 static const char *
-get_tgt(keytab_name, principal_name)
-       char *keytab_name, *principal_name;
+get_tgt(
+    char *     keytab_name,
+    char *     principal_name)
 {
     krb5_context context;
     krb5_error_code ret;
@@ -1619,7 +1700,7 @@ get_tgt(keytab_name, principal_name)
        return (error);
     }
 
-    krb5_init_ets(context);
+    /*krb5_init_ets(context);*/
 
     if(!keytab_name) {
         error = vstralloc("error  -- no krb5 keytab defined", NULL);
@@ -1671,7 +1752,7 @@ get_tgt(keytab_name, principal_name)
        return (error);
     }
 
-    memset(&creds, 0, sizeof(creds));
+    memset(&creds, 0, SIZEOF(creds));
     creds.times.starttime = 0;
     creds.times.endtime = now + AMANDA_TKT_LIFETIME;
 
@@ -1720,7 +1801,8 @@ cleanup2:
 /*
  * get rid of tickets
  */
-kdestroy()
+static void
+kdestroy(void)
 {
     krb5_context context;
     krb5_ccache ccache;
@@ -1740,39 +1822,13 @@ cleanup:
      return;
 }
 
-static void
-parse_pkt(pkt, buf, bufsize)
-    pkt_t *pkt;
-    const void *buf;
-    size_t bufsize;
-{
-    const unsigned char *bufp = buf;
-
-    k5printf(("krb5: parse_pkt: parsing buffer of %d bytes\n", bufsize));
-
-    pkt->type = (pktype_t)*bufp++;
-    bufsize--;
-
-    if (bufsize == 0) {
-       pkt->body[0] = '\0';
-    } else {
-       if (bufsize > sizeof(pkt->body) - 1)
-           bufsize = sizeof(pkt->body) - 1;
-       memcpy(pkt->body, bufp, bufsize);
-       pkt->body[sizeof(pkt->body) - 1] = '\0';
-    }
-
-    k5printf(("krb5: parse_pkt: %s (%d): \"%s\"\n", pkt_type2str(pkt->type),
-       pkt->type, pkt->body));
-}
-
-
 /*
  * Formats an error from the gss api
  */
 static const char *
-gss_error(major, minor)
-    OM_uint32 major, minor;
+gss_error(
+    OM_uint32  major,
+    OM_uint32  minor)
 {
     static gss_buffer_desc msg;
     OM_uint32 min_stat, msg_ctx;
@@ -1796,10 +1852,10 @@ gss_error(major, minor)
  * Encryption must be done by the caller.
  */
 static int
-send_token(kc, handle, tok)
-    struct krb5_conn *kc;
-    int handle;
-    const gss_buffer_desc *tok;
+send_token(
+    struct krb5_conn *         kc,
+    int                                handle,
+    const gss_buffer_desc *    tok)
 {
     OM_uint32 netlength, nethandle;
     struct iovec iov[3];
@@ -1819,13 +1875,13 @@ send_token(kc, handle, tok)
      *   32 bit handle (network byte order)
      *   data
      */
-    netlength = htonl(tok->length);
+    netlength = (OM_uint32)htonl(tok->length);
     iov[0].iov_base = (void *)&netlength;
-    iov[0].iov_len = sizeof(netlength);
+    iov[0].iov_len = SIZEOF(netlength);
 
-    nethandle = htonl(handle);
+    nethandle = (OM_uint32)htonl((uint32_t)handle);
     iov[1].iov_base = (void *)&nethandle;
-    iov[1].iov_len = sizeof(nethandle);
+    iov[1].iov_len = SIZEOF(nethandle);
 
     iov[2].iov_base = (void *)tok->value;
     iov[2].iov_len = tok->length;
@@ -1838,21 +1894,21 @@ send_token(kc, handle, tok)
     return (0);
 }
 
-static int
-recv_token(kc, handle, gtok, timeout)
-    struct krb5_conn *kc;
-    int *handle;
-    gss_buffer_desc *gtok;
-    int timeout;
+static ssize_t
+recv_token(
+    struct krb5_conn * kc,
+    int *              handle,
+    gss_buffer_desc *  gtok,
+    int                        timeout)
 {
-    OM_uint32 netint;
+    OM_uint32 netint[2];
 
     assert(kc->fd >= 0);
     assert(gtok != NULL);
 
     k5printf(("krb5: recv_token: reading from %s\n", kc->hostname));
 
-    switch (net_read(kc, &netint, sizeof(netint), timeout)) {
+    switch (net_read(kc->fd, &netint, SIZEOF(netint), timeout)) {
     case -1:
        kc->errmsg = newvstralloc(kc->errmsg, "recv error: ", strerror(errno),
            NULL);
@@ -1864,7 +1920,7 @@ recv_token(kc, handle, gtok, timeout)
     default:
        break;
     }
-    gtok->length = ntohl(netint);
+    gtok->length = ntohl(netint[0]);
 
     if (gtok->length > AMANDA_MAX_TOK_SIZE) {
        kc->errmsg = newstralloc(kc->errmsg, "recv error: buffer too large");
@@ -1872,23 +1928,11 @@ recv_token(kc, handle, gtok, timeout)
        return (-1);
     }
 
-    switch (net_read(kc, &netint, sizeof(netint), timeout)) {
-    case -1:
-       kc->errmsg = newvstralloc(kc->errmsg, "recv error: ", strerror(errno),
-           NULL);
-       k5printf(("krb5 recv_token error return: %s\n", kc->errmsg));
-       return (-1);
-    case 0:
-       gtok->length = 0;
-       return (0);
-    default:
-       break;
-    }
     if (handle != NULL)
-       *handle = ntohl(netint);
+       *handle = ntohl(netint[1]);
 
     gtok->value = alloc(gtok->length);
-    switch (net_read(kc, gtok->value, gtok->length, timeout)) {
+    switch (net_read(kc->fd, gtok->value, gtok->length, timeout)) {
     case -1:
        kc->errmsg = newvstralloc(kc->errmsg, "recv error: ", strerror(errno),
            NULL);
@@ -1905,14 +1949,15 @@ recv_token(kc, handle, gtok, timeout)
 
     k5printf(("krb5: recv_token: read %d bytes from %s\n", gtok->length,
        kc->hostname));
-    return (gtok->length);
+    return ((ssize_t)gtok->length);
 }
 
 #ifdef AMANDA_KRB5_ENCRYPT
 static int
-kencrypt(ks, tok, enctok)
-    struct krb5_stream *ks;
-    gss_buffer_desc *tok, *enctok;
+kencrypt(
+    struct krb5_stream *ks,
+    gss_buffer_desc *  tok,
+    gss_buffer_desc *  enctok)
 {
     int conf_state;
     OM_uint32 maj_stat, min_stat;
@@ -1920,7 +1965,7 @@ kencrypt(ks, tok, enctok)
     assert(ks->kc->gss_context != GSS_C_NO_CONTEXT);
     maj_stat = gss_seal(&min_stat, ks->kc->gss_context, 1,
        GSS_C_QOP_DEFAULT, tok, &conf_state, enctok);
-    if (maj_stat != GSS_S_COMPLETE || conf_state == 0) {
+    if (maj_stat != (OM_uint32)GSS_S_COMPLETE || conf_state == 0) {
        security_stream_seterror(&ks->secstr,
            "krb5 encryption failed to %s: %s",
            ks->kc->hostname, gss_error(maj_stat, min_stat));
@@ -1930,9 +1975,10 @@ kencrypt(ks, tok, enctok)
 }
 
 static int
-kdecrypt(ks, enctok, tok)
-    struct krb5_stream *ks;
-    gss_buffer_desc *enctok, *tok;
+kdecrypt(
+    struct krb5_stream *ks,
+    gss_buffer_desc *  enctok,
+    gss_buffer_desc *  tok)
 {
     OM_uint32 maj_stat, min_stat;
     int conf_state, qop_state;
@@ -1942,7 +1988,7 @@ kdecrypt(ks, enctok, tok)
     assert(ks->kc->gss_context != GSS_C_NO_CONTEXT);
     maj_stat = gss_unseal(&min_stat, ks->kc->gss_context, enctok, tok,
        &conf_state, &qop_state);
-    if (maj_stat != GSS_S_COMPLETE) {
+    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
        security_stream_seterror(&ks->secstr, "krb5 decrypt error from %s: %s",
            ks->kc->hostname, gss_error(maj_stat, min_stat));
        return (-1);
@@ -1951,121 +1997,6 @@ kdecrypt(ks, enctok, tok)
 }
 #endif
 
-/*
- * Writes out the entire iovec
- */
-static int
-net_writev(fd, iov, iovcnt)
-    int fd, iovcnt;
-    struct iovec *iov;
-{
-    int delta, n, total;
-
-    assert(iov != NULL);
-
-    total = 0;
-    while (iovcnt > 0) {
-       /*
-        * Write the iovec
-        */
-       total += n = writev(fd, iov, iovcnt);
-       if (n < 0)
-           return (-1);
-       if (n == 0) {
-           errno = EIO;
-           return (-1);
-       }
-       /*
-        * Iterate through each iov.  Figure out what we still need
-        * to write out.
-        */
-       for (; n > 0; iovcnt--, iov++) {
-           /* 'delta' is the bytes written from this iovec */
-           delta = n < iov->iov_len ? n : iov->iov_len;
-           /* subtract from the total num bytes written */
-           n -= delta;
-           assert(n >= 0);
-           /* subtract from this iovec */
-           iov->iov_len -= delta;
-           (char *)iov->iov_base += delta;
-           /* if this iovec isn't empty, run the writev again */
-           if (iov->iov_len > 0)
-               break;
-       }
-    }
-    return (total);
-}
-
-/*
- * Like read(), but waits until the entire buffer has been filled.
- */
-static ssize_t
-net_read(kc, vbuf, origsize, timeout)
-    struct krb5_conn *kc;
-    void *vbuf;
-    size_t origsize;
-    int timeout;
-{
-    char *buf = vbuf, *off;    /* ptr arith */
-    int nread;
-    size_t size = origsize;
-
-    while (size > 0) {
-       if (kc->readbuf.left == 0) {
-           if (net_read_fillbuf(kc, timeout) < 0)
-               return (-1);
-           if (kc->readbuf.size == 0)
-               return (0);
-       }
-       nread = min(kc->readbuf.left, size);
-       off = kc->readbuf.buf + kc->readbuf.size - kc->readbuf.left;
-       memcpy(buf, off, nread);
-
-       buf += nread;
-       size -= nread;
-       kc->readbuf.left -= nread;
-    }
-    return ((ssize_t)origsize);
-}
-
-/*
- * net_read likes to do a lot of little reads.  Buffer it.
- */
-static int
-net_read_fillbuf(kc, timeout)
-    struct krb5_conn *kc;
-    int timeout;
-{
-    fd_set readfds;
-    struct timeval tv;
-
-    FD_ZERO(&readfds);
-    FD_SET(kc->fd, &readfds);
-    tv.tv_sec = timeout;
-    tv.tv_usec = 0;
-    switch (select(kc->fd + 1, &readfds, NULL, NULL, &tv)) {
-    case 0:
-       errno = ETIMEDOUT;
-       /* FALLTHROUGH */
-    case -1:
-       return (-1);
-    case 1:
-       assert(FD_ISSET(kc->fd, &readfds));
-       break;
-    default:
-       assert(0);
-       break;
-    }
-    kc->readbuf.left = 0;
-    kc->readbuf.size = read(kc->fd, kc->readbuf.buf,
-       sizeof(kc->readbuf.buf));
-k5printf(("net_read_fillbuf: read %d characters w/ errno %d\n", kc->readbuf.size, errno));
-    if (kc->readbuf.size < 0)
-       return (-1);
-    kc->readbuf.left = kc->readbuf.size;
-    return (0);
-}
-
 /*
  * hackish, but you can #undef AMANDA_PRINCIPAL here, and you can both
  * hardcode a principal in your build and use the .k5amandahosts.  This is
@@ -2080,8 +2011,9 @@ k5printf(("net_read_fillbuf: read %d characters w/ errno %d\n", kc->readbuf.size
  * hardcoded, then we don't check the realm
  */
 static char *
-krb5_checkuser(host, name, realm)
-       char *host, *name, *realm;
+krb5_checkuser( char * host,
+    char *     name,
+    char *     realm)
 {
 #ifdef AMANDA_PRINCIPAL
     if(strcmp(name, AMANDA_PRINCIPAL) == 0) {
@@ -2131,7 +2063,7 @@ krb5_checkuser(host, name, realm)
         if(strcmp(name, CLIENT_LOGIN) != 0) {
                result = vstralloc(name, " does not match ",
                        CLIENT_LOGIN, NULL);
-               goto common_exit;
+               return result;
        }
        result = NULL;
        goto common_exit;
@@ -2140,19 +2072,18 @@ krb5_checkuser(host, name, realm)
     k5printf(("opening ptmp: %s\n", (ptmp)?ptmp: "NULL!"));
     if((fp = fopen(ptmp, "r")) == NULL) {
        result = vstralloc("can not open ", ptmp, NULL);
-       goto common_exit;
+       return result;
     }
     k5printf(("opened ptmp\n"));
 
     if (fstat(fileno(fp), &sbuf) != 0) {
        result = vstralloc("cannot fstat ", ptmp, ": ", strerror(errno), NULL);
        goto common_exit;
-
     }
 
     if (sbuf.st_uid != localuid) {
-       snprintf(n1, sizeof(n1), "%ld", (long) sbuf.st_uid);
-       snprintf(n2, sizeof(n2), "%ld", (long) localuid);
+       snprintf(n1, SIZEOF(n1), "%ld", (long) sbuf.st_uid);
+       snprintf(n2, SIZEOF(n2), "%ld", (long) localuid);
        result = vstralloc(ptmp, ": ",
            "owned by id ", n1,
            ", should be ", n2,
@@ -2165,7 +2096,12 @@ krb5_checkuser(host, name, realm)
        goto common_exit;
     }       
 
-    while((line = agets(fp)) != NULL) {
+    while ((line = agets(fp)) != NULL) {
+       if (line[0] == '\0') {
+           amfree(line);
+           continue;
+       }
+
 #if defined(SHOW_SECURITY_DETAIL)                               /* { */
        k5printf(("%s: processing line: <%s>\n", debug_prefix(NULL), line));
 #endif                                                          /* } */
@@ -2211,23 +2147,26 @@ krb5_checkuser(host, name, realm)
                        continue;
                }
                result = NULL;
+               amfree(line);
                goto common_exit;
        }
-
        amfree(line);
     }
-
     result = vstralloc("no match in ", ptmp, NULL);
 
 common_exit:
-    if(fp)
-       afclose(fp);
-    if(line)
-       amfree(line);
+    afclose(fp);
     return(result);
 #endif /* AMANDA_PRINCIPAL */
 }
 
 #else
-void krb5_security_dummy (void) {}
+
+void krb5_security_dummy(void);
+
+void
+krb5_security_dummy(void)
+{
+}
+
 #endif /* KRB5_SECURITY */
index fbe0c22007211943a79996c1f6e5d5633b7be971..5ddc1da290f6f886d5e744a4c9d589870e89d013 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: match.c,v 1.21 2005/10/11 01:17:00 vectro Exp $
+ * $Id: match.c,v 1.23 2006/05/25 01:47:12 johnfranks Exp $
  *
  * functions for checking and matching regular expressions
  */
 #include "amanda.h"
 #include "regex.h"
 
-char *validate_regexp(regex)
-char *regex;
+static int match_word(const char *glob, const char *word, const char separator);
+
+char *
+validate_regexp(
+    const char *       regex)
 {
     regex_t regc;
     int result;
@@ -41,7 +44,7 @@ char *regex;
 
     if ((result = regcomp(&regc, regex,
                          REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
-      regerror(result, &regc, errmsg, sizeof(errmsg));
+      regerror(result, &regc, errmsg, SIZEOF(errmsg));
       return errmsg;
     }
 
@@ -50,8 +53,9 @@ char *regex;
     return NULL;
 }
 
-char *clean_regex(regex)
-char *regex;
+char *
+clean_regex(
+    const char *       regex)
 {
     char *result;
     int j;
@@ -63,12 +67,14 @@ char *regex;
            result[j++]='\\';
        result[j++]=regex[i];
     }
-    result[j++] = '\0';
+    result[j] = '\0';
     return result;
 }
 
-int match(regex, str)
-char *regex, *str;
+int
+match(
+    const char *       regex,
+    const char *       str)
 {
     regex_t regc;
     int result;
@@ -76,14 +82,16 @@ char *regex, *str;
 
     if((result = regcomp(&regc, regex,
                         REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
-        regerror(result, &regc, errmsg, sizeof(errmsg));
+        regerror(result, &regc, errmsg, SIZEOF(errmsg));
        error("regex \"%s\": %s", regex, errmsg);
+       /*NOTREACHED*/
     }
 
     if((result = regexec(&regc, str, 0, 0, 0)) != 0
        && result != REG_NOMATCH) {
-        regerror(result, &regc, errmsg, sizeof(errmsg));
+        regerror(result, &regc, errmsg, SIZEOF(errmsg));
        error("regex \"%s\": %s", regex, errmsg);
+       /*NOTREACHED*/
     }
 
     regfree(&regc);
@@ -91,10 +99,11 @@ char *regex, *str;
     return result == 0;
 }
 
-char *validate_glob(glob)
-char *glob;
+char *
+validate_glob(
+    const char *       glob)
 {
-    char *regex = NULL;
+    char *regex;
     regex_t regc;
     int result;
     static char errmsg[STR_SIZE];
@@ -102,7 +111,7 @@ char *glob;
     regex = glob_to_regex(glob);
     if ((result = regcomp(&regc, regex,
                          REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
-      regerror(result, &regc, errmsg, sizeof(errmsg));
+      regerror(result, &regc, errmsg, SIZEOF(errmsg));
       amfree(regex);
       return errmsg;
     }
@@ -113,10 +122,12 @@ char *glob;
     return NULL;
 }
 
-int match_glob(glob, str)
-char *glob, *str;
+int
+match_glob(
+    const char *       glob,
+    const char *       str)
 {
-    char *regex = NULL;
+    char *regex;
     regex_t regc;
     int result;
     char errmsg[STR_SIZE];
@@ -124,14 +135,16 @@ char *glob, *str;
     regex = glob_to_regex(glob);
     if((result = regcomp(&regc, regex,
                         REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
-        regerror(result, &regc, errmsg, sizeof(errmsg));
+        regerror(result, &regc, errmsg, SIZEOF(errmsg));
        error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+       /*NOTREACHED*/
     }
 
     if((result = regexec(&regc, str, 0, 0, 0)) != 0
        && result != REG_NOMATCH) {
-        regerror(result, &regc, errmsg, sizeof(errmsg));
+        regerror(result, &regc, errmsg, SIZEOF(errmsg));
        error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+       /*NOTREACHED*/
     }
 
     regfree(&regc);
@@ -140,8 +153,9 @@ char *glob, *str;
     return result == 0;
 }
 
-char *glob_to_regex(glob)
-char *glob;
+char *
+glob_to_regex(
+    const char *       glob)
 {
     char *regex;
     char *r;
@@ -178,12 +192,12 @@ char *glob;
     last_ch = '\0';
     for (ch = *glob++; ch != '\0'; last_ch = ch, ch = *glob++) {
        if (last_ch == '\\') {
-           *r++ = ch;
+           *r++ = (char)ch;
            ch = '\0';                  /* so last_ch != '\\' next time */
        } else if (last_ch == '[' && ch == '!') {
            *r++ = '^';
        } else if (ch == '\\') {
-           *r++ = ch;
+           *r++ = (char)ch;
        } else if (ch == '*' || ch == '?') {
            *r++ = '[';
            *r++ = '^';
@@ -202,9 +216,9 @@ char *glob;
                   || ch == '$'
                   || ch == '|') {
            *r++ = '\\';
-           *r++ = ch;
+           *r++ = (char)ch;
        } else {
-           *r++ = ch;
+           *r++ = (char)ch;
        }
     }
     if (last_ch != '\\') {
@@ -216,10 +230,12 @@ char *glob;
 }
 
 
-int match_tar(glob, str)
-char *glob, *str;
+int
+match_tar(
+    const char *       glob,
+    const char *       str)
 {
-    char *regex = NULL;
+    char *regex;
     regex_t regc;
     int result;
     char errmsg[STR_SIZE];
@@ -227,14 +243,16 @@ char *glob, *str;
     regex = tar_to_regex(glob);
     if((result = regcomp(&regc, regex,
                         REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
-        regerror(result, &regc, errmsg, sizeof(errmsg));
+        regerror(result, &regc, errmsg, SIZEOF(errmsg));
        error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+       /*NOTREACHED*/
     }
 
     if((result = regexec(&regc, str, 0, 0, 0)) != 0
        && result != REG_NOMATCH) {
-        regerror(result, &regc, errmsg, sizeof(errmsg));
+        regerror(result, &regc, errmsg, SIZEOF(errmsg));
        error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+       /*NOTREACHED*/
     }
 
     regfree(&regc);
@@ -243,8 +261,9 @@ char *glob, *str;
     return result == 0;
 }
 
-char *tar_to_regex(glob)
-char *glob;
+char *
+tar_to_regex(
+    const char *       glob)
 {
     char *regex;
     char *r;
@@ -281,12 +300,12 @@ char *glob;
     last_ch = '\0';
     for (ch = *glob++; ch != '\0'; last_ch = ch, ch = *glob++) {
        if (last_ch == '\\') {
-           *r++ = ch;
+           *r++ = (char)ch;
            ch = '\0';                  /* so last_ch != '\\' next time */
        } else if (last_ch == '[' && ch == '!') {
            *r++ = '^';
        } else if (ch == '\\') {
-           *r++ = ch;
+           *r++ = (char)ch;
        } else if (ch == '*') {
            *r++ = '.';
            *r++ = '*';
@@ -305,9 +324,9 @@ char *glob;
                   || ch == '$'
                   || ch == '|') {
            *r++ = '\\';
-           *r++ = ch;
+           *r++ = (char)ch;
        } else {
-           *r++ = ch;
+           *r++ = (char)ch;
        }
     }
     if (last_ch != '\\') {
@@ -319,9 +338,11 @@ char *glob;
 }
 
 
-int match_word(glob, word, separator)
-char *glob, *word;
-char separator;
+static int
+match_word(
+    const char *       glob,
+    const char *       word,
+    const char         separator)
 {
     char *regex;
     char *r;
@@ -332,7 +353,8 @@ char separator;
     size_t  lenword;
     char *nword;
     char *nglob;
-    char *g, *w;
+    char *g; 
+    const char *w;
     int  i;
 
     lenword = strlen(word);
@@ -410,12 +432,12 @@ char separator;
        for (ch = *g++; ch != '\0'; last_ch = ch, ch = *g++) {
            next_ch = *g;
            if (last_ch == '\\') {
-               *r++ = ch;
+               *r++ = (char)ch;
                ch = '\0';              /* so last_ch != '\\' next time */
            } else if (last_ch == '[' && ch == '!') {
                *r++ = '^';
            } else if (ch == '\\') {
-               *r++ = ch;
+               *r++ = (char)ch;
            } else if (ch == '*' || ch == '?') {
                if(ch == '*' && next_ch == '*') {
                    *r++ = '.';
@@ -436,7 +458,7 @@ char separator;
                    *r++ = '\\';
                    *r++ = separator;
                }
-               *r++ = ch;
+               *r++ = (char)ch;
            } else if (   ch == '('
                       || ch == ')'
                       || ch == '{'
@@ -447,9 +469,9 @@ char separator;
                       || ch == '$'
                       || ch == '|') {
                *r++ = '\\';
-               *r++ = ch;
+               *r++ = (char)ch;
            } else {
-               *r++ = ch;
+               *r++ = (char)ch;
            }
        }
        if(last_ch != '\\') {
@@ -470,51 +492,59 @@ char separator;
 }
 
 
-int match_host(glob, host)
-char *glob, *host;
+int
+match_host(
+    const char *       glob,
+    const char *       host)
 {
     char *lglob, *lhost;
-    char *c, *d;
+    char *c;
+    const char *d;
     int i;
 
     
     lglob = (char *)alloc(strlen(glob)+1);
     c = lglob, d=glob;
     while( *d != '\0')
-       *c++ = tolower(*d++);
+       *c++ = (char)tolower(*d++);
     *c = *d;
 
     lhost = (char *)alloc(strlen(host)+1);
     c = lhost, d=host;
     while( *d != '\0')
-       *c++ = tolower(*d++);
+       *c++ = (char)tolower(*d++);
     *c = *d;
 
-    i = match_word(lglob, lhost, '.');
+    i = match_word(lglob, lhost, (int)'.');
     amfree(lglob);
     amfree(lhost);
     return i;
 }
 
 
-int match_disk(glob, disk)
-char *glob, *disk;
+int
+match_disk(
+    const char *       glob,
+    const char *       disk)
 {
     return match_word(glob, disk, '/');
 }
 
-int match_datestamp(dateexp, datestamp)
-char *dateexp, *datestamp;
+int
+match_datestamp(
+    const char *       dateexp,
+    const char *       datestamp)
 {
     char *dash;
     size_t len, len_suffix;
-    int len_prefix;
+    size_t len_prefix;
     char firstdate[100], lastdate[100];
     char mydateexp[100];
     int match_exact;
 
     if(strlen(dateexp) >= 100 || strlen(dateexp) < 1) {
        error("Illegal datestamp expression %s",dateexp);
+       /*NOTREACHED*/
     }
    
     if(dateexp[0] == '^') {
@@ -536,15 +566,12 @@ char *dateexp, *datestamp;
     if((dash = strchr(mydateexp,'-'))) {
        if(match_exact == 1) {
            error("Illegal datestamp expression %s",dateexp);
+           /*NOTREACHED*/
        }
-       len = dash - mydateexp;
+       len = (size_t)(dash - mydateexp);
        len_suffix = strlen(dash) - 1;
        len_prefix = len - len_suffix;
 
-       if(len_prefix < 0) {
-           error("Illegal datestamp expression %s",dateexp);
-       }
-
        dash++;
        strncpy(firstdate, mydateexp, len);
        firstdate[len] = '\0';
@@ -565,18 +592,21 @@ char *dateexp, *datestamp;
 }
 
 
-int match_level(levelexp, level)
-char *levelexp, *level;
+int
+match_level(
+    const char *       levelexp,
+    const char *       level)
 {
     char *dash;
     size_t len, len_suffix;
-    int len_prefix;
+    size_t len_prefix;
     char lowend[100], highend[100];
     char mylevelexp[100];
     int match_exact;
 
     if(strlen(levelexp) >= 100 || strlen(levelexp) < 1) {
        error("Illegal level expression %s",levelexp);
+       /*NOTREACHED*/
     }
    
     if(levelexp[0] == '^') {
@@ -598,15 +628,12 @@ char *levelexp, *level;
     if((dash = strchr(mylevelexp,'-'))) {
        if(match_exact == 1) {
            error("Illegal level expression %s",levelexp);
+           /*NOTREACHED*/
        }
-       len = dash - mylevelexp;
+       len = (size_t)(dash - mylevelexp);
        len_suffix = strlen(dash) - 1;
        len_prefix = len - len_suffix;
 
-       if(len_prefix < 0) {
-           error("Illegal level expression %s",levelexp);
-       }
-
        dash++;
        strncpy(lowend, mylevelexp, len);
        lowend[len] = '\0';
index 8aebb02acb1e2aa53ff09f24d7c9deb4e2b75444..5d4373d48df32df84575873a5b4470558901fd9b 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.  */
 
 /*static char *sccsid = "from: @(#)ctime.c     5.26 (Berkeley) 2/23/91";*/
-/*static char *rcsid = "$Id: mktime.c,v 1.4 1998/03/18 10:00:49 amcore Exp $";*/
+/*static char *rcsid = "$Id: mktime.c,v 1.5 2006/05/25 01:47:12 johnfranks Exp $";*/
 
 /*
  * This implementation of mktime is lifted straight from the NetBSD (BSD 4.4)
@@ -60,6 +60,8 @@
  * by hand.  Sorry about that.
  */
 
+#include "amanda.h"
+
 #ifndef DSTMINUTES
 #define DSTMINUTES 60
 #endif
 #define TM_YEAR_BASE    1900
 #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
 
-#include <sys/types.h>
-#include <time.h>
-
-extern time_t  time();
-
 static int     mon_lengths[2][MONSPERYEAR] = {
        { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
        { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
index 32a2d31501e90ae129cdb33ed77f3cb3605607a7..7ebda6173d69cf7bc4c2013b5a289cfc2d712a5a 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: packet.c,v 1.6 2004/02/13 14:00:35 martinea Exp $
+ * $Id: packet.c,v 1.8 2006/05/25 01:47:12 johnfranks Exp $
  *
  * Routines for modifying the amanda protocol packet type
  */
@@ -45,7 +45,7 @@ static const struct {
     { "ACK", P_ACK },
     { "NAK", P_NAK }
 };
-#define        NPKTYPES        (sizeof(pktypes) / sizeof(pktypes[0]))
+#define        NPKTYPES        (int)(SIZEOF(pktypes) / SIZEOF(pktypes[0]))
 
 /*
  * Initialize a packet
@@ -53,17 +53,24 @@ static const struct {
 printf_arglist_function2(void pkt_init, pkt_t *, pkt, pktype_t, type,
     const char *, fmt)
 {
-    va_list argp;
+    va_list    argp;
 
     assert(pkt != NULL);
     assert(strcmp(pkt_type2str(type), "BOGUS") != 0);
     assert(fmt != NULL);
 
     pkt->type = type;
-
+    pkt->packet_size = 1000;
+    pkt->body = alloc(pkt->packet_size);
     arglist_start(argp, fmt);
-    vsnprintf(pkt->body, sizeof(pkt->body), fmt, argp);
+    while (vsnprintf(pkt->body, pkt->packet_size, fmt, argp) >=
+               (int)(pkt->packet_size - 1)) {
+       pkt->packet_size *= 2;
+       amfree(pkt->body);
+       pkt->body = alloc(pkt->packet_size);
+    }
     arglist_end(argp);
+    pkt->size = strlen(pkt->body);
 }
 
 /*
@@ -71,36 +78,43 @@ printf_arglist_function2(void pkt_init, pkt_t *, pkt, pktype_t, type,
  */
 printf_arglist_function1(void pkt_cat, pkt_t *, pkt, const char *, fmt)
 {
-    size_t len, bufsize;
-    va_list argp;
+    size_t     len;
+    va_list    argp;
+    char *     pktbody;
 
     assert(pkt != NULL);
     assert(fmt != NULL);
 
     len = strlen(pkt->body);
-    assert(len < sizeof(pkt->body));
-
-    bufsize = sizeof(pkt->body) - len;
-    if (bufsize <= 0)
-       return;
 
     arglist_start(argp, fmt);
-    vsnprintf(pkt->body + len, bufsize, fmt, argp);
+    while (vsnprintf(pkt->body + len, pkt->packet_size - len, fmt,argp) >=
+               (int)(pkt->packet_size - len - 1)) {
+       pkt->packet_size *= 2;
+       pktbody = alloc(pkt->packet_size);
+       strncpy(pktbody, pkt->body, len);
+       pktbody[len] = '\0';
+       amfree(pkt->body);
+       pkt->body = pktbody;
+       arglist_end(argp);
+       arglist_start(argp, fmt);
+    }
     arglist_end(argp);
+    pkt->size = strlen(pkt->body);
 }
 
 /*
  * Converts a string into a packet type
  */
 pktype_t
-pkt_str2type(typestr)
-    const char *typestr;
+pkt_str2type(
+    const char *typestr)
 {
     int i;
 
     assert(typestr != NULL);
 
-    for (i = 0; i < NPKTYPES; i++)
+    for (i = 0; i < (int)NPKTYPES; i++)
        if (strcmp(typestr, pktypes[i].name) == 0)
            return (pktypes[i].type);
     return ((pktype_t)-1);
@@ -110,12 +124,12 @@ pkt_str2type(typestr)
  * Converts a packet type into a string
  */
 const char *
-pkt_type2str(type)
-    pktype_t type;
+pkt_type2str(
+    pktype_t   type)
 {
     int i;
 
-    for (i = 0; i < NPKTYPES; i++)
+    for (i = 0; i < (int)NPKTYPES; i++)
        if (pktypes[i].type == type)
            return (pktypes[i].name);
     return ("BOGUS");
index fb126261037e4319845a9b67c23977ad6ef12663..f508b3fd6324cc14c37b42229356db9451c37a77 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: packet.h,v 1.6 2004/02/13 14:00:35 martinea Exp $
+ * $Id: packet.h,v 1.8 2006/05/25 01:47:12 johnfranks Exp $
  *
  * interfaces for modifying amanda protocol packet type
  */
 #ifndef PACKET_H
 #define PACKET_H
 
-/*
- * We limit our body length to 50k.
- */
-#define        MAX_PACKET      (50*1024)
-
 typedef enum { P_REQ = 0, P_REP = 1, P_PREP = 2, P_ACK = 3, P_NAK = 4 } pktype_t;
 typedef struct {
-    pktype_t type;                             /* type of packet */
-    char body[MAX_PACKET];                     /* body of packet */
+    pktype_t   type;                   /* type of packet */
+    char *     body;                   /* body of packet */
+    size_t     size;
+    size_t     packet_size;
 } pkt_t;
 
 /*
  * Initialize a packet
  */
-void pkt_init P((pkt_t *, pktype_t, const char *, ...))
+void pkt_init(pkt_t *, pktype_t, const char *, ...)
     __attribute__ ((format (printf, 3, 4)));
 
 /*
  * Append data to a packet
  */
-void pkt_cat P((pkt_t *, const char *, ...))
+void pkt_cat(pkt_t *, const char *, ...)
     __attribute__ ((format (printf, 2, 3)));
 
 /*
  * Convert the packet type to and from a string
  */
-const char *pkt_type2str P((pktype_t));
-pktype_t pkt_str2type P((const char *));
+const char *pkt_type2str(pktype_t);
+pktype_t pkt_str2type(const char *);
 
 #endif /* PACKET_H */
index d960c97803a089b4bbceea7d4cb4f3f3ed5ff7f6..a56a1d48d92c605a5b25c45de03e7d24e76043d5 100644 (file)
@@ -2,26 +2,31 @@
 #include "pipespawn.h"
 #include "arglist.h"
 #include "clock.h"
+#include "util.h"
 
 char skip_argument[1];
 
+pid_t pipespawnv_passwd(char *prog, int pipedef,
+                  int *stdinfd, int *stdoutfd, int *stderrfd,
+                  char **my_argv);
+
+
 /*
  * this used to be a function in it's own write but became a wrapper around
  * pipespawnv to eliminate redundancy...
  */
-#ifdef STDC_HEADERS
-int pipespawn(char *prog, int pipedef, int *stdinfd, int *stdoutfd,
-             int *stderrfd, ...)
-#else
-int pipespawn(prog, pipedef, stdinfd, stdoutfd, stderrfd, va_alist)
-char *prog;
-int pipedef;
-int *stdinfd, *stdoutfd, *stderrfd;
-va_dcl
-#endif
+pid_t
+pipespawn(
+    char *     prog,
+    int                pipedef,
+    int *      stdinfd,
+    int *      stdoutfd,
+    int *      stderrfd,
+    ...)
 {
     va_list ap;
-    int argc = 0, pid, i;
+    int argc = 0, i;
+    pid_t pid;
     char **argv;
 
     /* count args */
@@ -35,7 +40,7 @@ va_dcl
      * Create the argument vector.
      */
     arglist_start(ap, stderrfd);
-    argv = (char **)alloc((argc + 1) * sizeof(*argv));
+    argv = (char **)alloc((argc + 1) * SIZEOF(*argv));
     i = 0;
     while((argv[i] = arglist_val(ap, char *)) != NULL) {
         if (argv[i] != skip_argument) {
@@ -44,37 +49,43 @@ va_dcl
     }
     arglist_end(ap);
 
-    pid = pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, NULL, NULL, argv);
+    pid = pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, argv);
     amfree(argv);
     return pid;
 }
 
-int pipespawnv(prog, pipedef, stdinfd, stdoutfd, stderrfd, my_argv)
-char *prog;
-int pipedef;
-int *stdinfd, *stdoutfd, *stderrfd;
-char **my_argv;
+pid_t
+pipespawnv(
+    char *     prog,
+    int                pipedef,
+    int *      stdinfd,
+    int *      stdoutfd,
+    int *      stderrfd,
+    char **    my_argv)
 {
     return pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd,
-       NULL, NULL, my_argv);
+       my_argv);
 }
 
-int pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, passwdvar, passwdfd, my_argv)
-char *prog;
-int pipedef;
-int *stdinfd, *stdoutfd, *stderrfd;
-char *passwdvar;
-int *passwdfd;
-char **my_argv;
+pid_t
+pipespawnv_passwd(
+    char *     prog,
+    int                pipedef,
+    int *      stdinfd,
+    int *      stdoutfd,
+    int *      stderrfd,
+    char **    my_argv)
 {
     int argc;
-    int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
+    pid_t pid;
+    int i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
     char number[NUM_STR_SIZE];
     char **arg;
     char *e;
-    int ch;
     char **env;
     char **newenv;
+    char *passwdvar = NULL;
+    int  *passwdfd = NULL;
 
     /*
      * Log the command line and count the args.
@@ -83,22 +94,21 @@ char **my_argv;
     dbprintf(("%s: argument list:", debug_prefix(NULL)));
     if ((pipedef & PASSWD_PIPE) != 0) {
        passwdvar = *my_argv++;
-       passwdfd = (int *)*my_argv++;
+       passwdfd  = (int *)*my_argv++;
     }
+    memset(inpipe, -1, SIZEOF(inpipe));
+    memset(outpipe, -1, SIZEOF(outpipe));
+    memset(errpipe, -1, SIZEOF(errpipe));
+    memset(passwdpipe, -1, SIZEOF(passwdpipe));
     argc = 0;
     for(arg = my_argv; *arg != NULL; arg++) {
-       if (*arg == skip_argument) {
-           continue;
-       }
-       argc++;
-       dbprintf((" "));
-       for(i = 0; (ch = (*arg)[i]) != '\0' && isprint(ch) && ch != ' '; i++) {}
-       if(ch != '\0' || i == 0) {
-           dbprintf(("\""));
-       }
-       dbprintf(("%s", *arg));
-       if(ch != '\0' || i == 0) {
-           dbprintf(("\""));
+       char *quoted;
+
+       if (*arg != skip_argument) {
+           argc++;
+           quoted = quote_string(*arg);
+           dbprintf((" %s", quoted));
+           amfree(quoted);
        }
     }
     dbprintf(("\n"));
@@ -109,21 +119,25 @@ char **my_argv;
     if ((pipedef & STDIN_PIPE) != 0) {
        if(pipe(inpipe) == -1) {
            error("error [open pipe to %s: %s]", prog, strerror(errno));
+           /*NOTREACHED*/
        }
     }
     if ((pipedef & STDOUT_PIPE) != 0) {
        if(pipe(outpipe) == -1) {
            error("error [open pipe to %s: %s]", prog, strerror(errno));
+           /*NOTREACHED*/
        }
     }
     if ((pipedef & STDERR_PIPE) != 0) {
        if(pipe(errpipe) == -1) {
            error("error [open pipe to %s: %s]", prog, strerror(errno));
+           /*NOTREACHED*/
        }
     }
     if ((pipedef & PASSWD_PIPE) != 0) {
        if(pipe(passwdpipe) == -1) {
            error("error [open pipe to %s: %s]", prog, strerror(errno));
+           /*NOTREACHED*/
        }
     }
 
@@ -134,6 +148,8 @@ char **my_argv;
     case -1:
        e = strerror(errno);
        error("error [fork %s: %s]", prog, e);
+       /*NOTREACHED*/
+
     default:   /* parent process */
        if ((pipedef & STDIN_PIPE) != 0) {
            aclose(inpipe[0]);          /* close input side of pipe */
@@ -177,12 +193,15 @@ char **my_argv;
         */
        if(dup2(inpipe[0], 0) == -1) {
            error("error [spawn %s: dup2 in: %s]", prog, strerror(errno));
+           /*NOTREACHED*/
        }
        if(dup2(outpipe[1], 1) == -1) {
            error("error [spawn %s: dup2 out: %s]", prog, strerror(errno));
+           /*NOTREACHED*/
        }
        if(dup2(errpipe[1], 2) == -1) {
            error("error [spawn %s: dup2 err: %s]", prog, strerror(errno));
+           /*NOTREACHED*/
        }
 
        /*
@@ -191,11 +210,14 @@ char **my_argv;
         */
        env = safe_env();
        if ((pipedef & PASSWD_PIPE) != 0) {
-           for(i = 0; env[i] != NULL; i++) {}
-           newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv));
-           snprintf(number, sizeof(number), "%d", passwdpipe[0]);
+           for (i = 0; env[i] != NULL; i++)
+               (void)i; /* make lint happy and do nothing */   
+           newenv = (char **)alloc((i + 1 + 1) * SIZEOF(*newenv));
+           snprintf(number, SIZEOF(number), "%d", passwdpipe[0]);
            newenv[0] = vstralloc(passwdvar, "=", number, NULL);
-           for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {}
+           for(i = 0; env[i] != NULL; i++)
+               newenv[i + 1] = env[i];
+           newenv[i + 1] = NULL;
            amfree(env);
            env = newenv;
        }
@@ -203,7 +225,7 @@ char **my_argv;
        execve(prog, my_argv, env);
        e = strerror(errno);
        error("error [exec %s: %s]", prog, e);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
     return pid;
 }
index 4a8a9e954ade9921a387a3a64df3b00f15dca882..8b81f58d9d4755e78d67363c5bebcd8b07a45e8c 100644 (file)
@@ -12,16 +12,11 @@ extern char skip_argument[1];
 #define STDERR_PIPE    (1 << 2)
 #define PASSWD_PIPE    (1 << 3)
 
-int pipespawn P((char *prog, int pipedef,
+pid_t pipespawn(char *prog, int pipedef,
                 int *stdinfd, int *stdoutfd, int *stderrfd,
-                ...));
-int pipespawnv P((char *prog, int pipedef,
+                ...);
+pid_t pipespawnv(char *prog, int pipedef,
                  int *stdinfd, int *stdoutfd, int *stderrfd,
-                 char **my_argv));
-int pipespawnv_passwd P((char *prog, int pipedef,
-                 int *stdinfd, int *stdoutfd, int *stderrfd,
-                 char *passwdvar, int *passwdfd,
-                 char **my_argv));
-
+                 char **my_argv);
 
 #endif /* PIPESPAWN_H */
index 4274e70b3a7a50244bbc1be700b4b014417f1cf9..c997f3c27c79a33269f250b6c98d8b52a8d0dd10 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: protocol.c,v 1.39 2006/02/28 16:36:13 martinea Exp $
+ * $Id: protocol.c,v 1.45 2006/05/25 17:07:31 martinea Exp $
  *
  * implements amanda protocol
  */
  * Valid actions that can be passed to the state machine
  */
 typedef enum {
-    A_START, A_TIMEOUT, A_ERROR, A_RCVDATA, A_CONTPEND, A_PENDING,
-    A_CONTINUE, A_FINISH, A_ABORT
-} action_t;
+       PA_START,
+       PA_TIMEOUT,
+       PA_ERROR,
+       PA_RCVDATA,
+       PA_CONTPEND,
+       PA_PENDING,
+       PA_CONTINUE,
+       PA_FINISH,
+       PA_ABORT
+} p_action_t;
 
 /*
  * The current state type.  States are represented as function
  * vectors.
  */
 struct proto;
-typedef action_t (*pstate_t) P((struct proto *, action_t, pkt_t *));
+typedef p_action_t (*pstate_t)(struct proto *, p_action_t, pkt_t *);
 
 /*
  * This is a request structure that is wrapped around a packet while it
@@ -71,7 +78,7 @@ typedef struct proto {
     pkt_t req;                         /* the actual wire request */
     protocol_sendreq_callback continuation; /* call when req dies/finishes */
     void *datap;                       /* opaque cookie passed to above */
-    char *(*conf_fn) P((char *, void *));/* configuration function */
+    char *(*conf_fn)(char *, void *);  /* configuration function */
 } proto_t;
 
 #define        CONNECT_TRIES   3       /* num retries after connect errors */
@@ -85,7 +92,7 @@ typedef struct proto {
 #define        DROP_DEAD_TIME(t)       (CURTIME - (t) > (60 * 60))
 
 /* get the size of an array */
-#define        ASIZE(arr)      (sizeof(arr) / sizeof((arr)[0]))
+#define        ASIZE(arr)      (int)(sizeof(arr) / sizeof((arr)[0]))
 
 /*
  * Initialization time
@@ -95,19 +102,18 @@ static time_t proto_init_time;
 /* local functions */
 
 #ifdef PROTO_DEBUG
-static const char *action2str P((action_t));
-static const char *pstate2str P((pstate_t));
+static const char *action2str(p_action_t);
+static const char *pstate2str(pstate_t);
 #endif
 
-static void connect_callback P((void *, security_handle_t *,
-    security_status_t));
-static void connect_wait_callback P((void *));
-static void recvpkt_callback P((void *, pkt_t *, security_status_t));
+static void connect_callback(void *, security_handle_t *, security_status_t);
+static void connect_wait_callback(void *);
+static void recvpkt_callback(void *, pkt_t *, security_status_t);
 
-static action_t s_sendreq P((proto_t *, action_t, pkt_t *));
-static action_t s_ackwait P((proto_t *, action_t, pkt_t *));
-static action_t s_repwait P((proto_t *, action_t, pkt_t *));
-static void state_machine P((proto_t *, action_t, pkt_t *));
+static p_action_t s_sendreq(proto_t *, p_action_t, pkt_t *);
+static p_action_t s_ackwait(proto_t *, p_action_t, pkt_t *);
+static p_action_t s_repwait(proto_t *, p_action_t, pkt_t *);
+static void state_machine(proto_t *, p_action_t, pkt_t *);
 
 /*
  * -------------------
@@ -118,7 +124,7 @@ static void state_machine P((proto_t *, action_t, pkt_t *));
  * Initialize globals.
  */
 void
-protocol_init()
+protocol_init(void)
 {
 
     proto_init_time = time(NULL);
@@ -129,18 +135,18 @@ protocol_init()
  * for transmission.
  */
 void
-protocol_sendreq(hostname, security_driver, conf_fn, req, repwait, continuation, datap)
-    const char *hostname;
-    const security_driver_t *security_driver;
-    char *(*conf_fn) P((char *, void *));
-    const char *req;
-    time_t repwait;
-    protocol_sendreq_callback continuation;
-    void *datap;
+protocol_sendreq(
+    const char *               hostname,
+    const security_driver_t *  security_driver,
+    char *                     (*conf_fn)(char *, void *),
+    const char *               req,
+    time_t                     repwait,
+    protocol_sendreq_callback  continuation,
+    void *                     datap)
 {
     proto_t *p;
 
-    p = alloc(sizeof(proto_t));
+    p = alloc(SIZEOF(proto_t));
     p->state = s_sendreq;
     p->hostname = stralloc(hostname);
     p->security_driver = security_driver;
@@ -164,11 +170,12 @@ protocol_sendreq(hostname, security_driver, conf_fn, req, repwait, continuation,
     p->datap = datap;
 
 #ifdef PROTO_DEBUG
-    dbprintf(("%s: security_connect: host %s -> p %X\n", 
-             debug_prefix_time(": protocol"), hostname, (int)p));
+    dbprintf(("%s: security_connect: host %s -> p %p\n", 
+             debug_prefix_time(": protocol"), hostname, p));
 #endif
 
-    security_connect(p->security_driver, p->hostname, conf_fn, connect_callback, p);
+    security_connect(p->security_driver, p->hostname, conf_fn, connect_callback,
+                        p, p->datap);
 }
 
 /*
@@ -180,10 +187,10 @@ protocol_sendreq(hostname, security_driver, conf_fn, req, repwait, continuation,
  * be had via security_geterror on the handle.
  */
 static void
-connect_callback(cookie, security_handle, status)
-    void *cookie;
-    security_handle_t *security_handle;
-    security_status_t status;
+connect_callback(
+    void *             cookie,
+    security_handle_t *        security_handle,
+    security_status_t  status)
 {
     proto_t *p = cookie;
 
@@ -191,13 +198,13 @@ connect_callback(cookie, security_handle, status)
     p->security_handle = security_handle;
 
 #ifdef PROTO_DEBUG
-    dbprintf(("%s: connect_callback: p %X\n",
-             debug_prefix_time(": protocol"), (int)p));
+    dbprintf(("%s: connect_callback: p %p\n",
+             debug_prefix_time(": protocol"), p));
 #endif
 
     switch (status) {
     case S_OK:
-       state_machine(p, A_START, NULL);
+       state_machine(p, PA_START, NULL);
        break;
 
     case S_TIMEOUT:
@@ -211,11 +218,11 @@ connect_callback(cookie, security_handle, status)
         * an error back to the caller.
         */
        if (--p->connecttries == 0) {
-           state_machine(p, A_ABORT, NULL);
+           state_machine(p, PA_ABORT, NULL);
        } else {
 #ifdef PROTO_DEBUG
-    dbprintf(("%s: connect_callback: p %X: retrying %s\n",
-             debug_prefix_time(": protocol"), (int)p, p->hostname));
+    dbprintf(("%s: connect_callback: p %p: retrying %s\n",
+             debug_prefix_time(": protocol"), p, p->hostname));
 #endif
            security_close(p->security_handle);
            /* XXX overload p->security handle to hold the event handle */
@@ -236,14 +243,14 @@ connect_callback(cookie, security_handle, status)
  * initial connection attempts failed.
  */
 static void
-connect_wait_callback(cookie)
-    void *cookie;
+connect_wait_callback(
+    void *     cookie)
 {
     proto_t *p = cookie;
 
     event_release((event_handle_t *)p->security_handle);
     security_connect(p->security_driver, p->hostname, p->conf_fn,
-       connect_callback, p);
+       connect_callback, p, p->datap);
 }
 
 
@@ -256,7 +263,7 @@ connect_wait_callback(cookie)
  * requests if they plan on doing a lot of work.
  */
 void
-protocol_check()
+protocol_check(void)
 {
 
     /* arg == 1 means don't block */
@@ -272,7 +279,7 @@ protocol_check()
  * and are just waiting for all of the answers to come back.
  */
 void
-protocol_run()
+protocol_run(void)
 {
 
     /* arg == 0 means block forever until no more events are left */
@@ -291,29 +298,29 @@ protocol_run()
  * with timeouts and successfull replies.
  */
 static void
-state_machine(p, action, pkt)
-    proto_t *p;
-    action_t action;
-    pkt_t *pkt;
+state_machine(
+    proto_t *  p,
+    p_action_t action,
+    pkt_t *    pkt)
 {
     pstate_t curstate;
-    action_t retaction;
+    p_action_t retaction;
 
 #ifdef PROTO_DEBUG
-       dbprintf(("%s: state_machine: initial: p %X action %s pkt %X\n",
+       dbprintf(("%s: state_machine: initial: p %p action %s pkt %p\n",
                debug_prefix_time(": protocol"),
-               (int)p, action2str(action), NULL));
+               p, action2str(action), NULL));
 #endif
 
     assert(p != NULL);
-    assert(action == A_RCVDATA || pkt == NULL);
+    assert(action == PA_RCVDATA || pkt == NULL);
     assert(p->state != NULL);
 
     for (;;) {
 #ifdef PROTO_DEBUG
-       dbprintf(("%s: state_machine: p %X state %s action %s\n",
+       dbprintf(("%s: state_machine: p %p state %s action %s\n",
                  debug_prefix_time(": protocol"),
-                 (int)p, pstate2str(p->state), action2str(action)));
+                 p, pstate2str(p->state), action2str(action)));
        if (pkt != NULL) {
            dbprintf(("%s: pkt: %s (t %d) orig REQ (t %d cur %d)\n",
                      debug_prefix(": protocol"),
@@ -329,17 +336,17 @@ state_machine(p, action, pkt)
         * is in.
         *
         * We keep track of the last state we were in so we can make
-        * sure states which return A_CONTINUE really have transitioned
+        * sure states which return PA_CONTINUE really have transitioned
         * the request to a new state.
         */
        curstate = p->state;
 
-       if (action == A_ABORT)
+       if (action == PA_ABORT)
            /*
             * If the passed action indicates a terminal error, then we
             * need to move to abort right away.
             */
-           retaction = A_ABORT;
+           retaction = PA_ABORT;
        else
            /*
             * Else we run the state and perform the action it
@@ -348,14 +355,14 @@ state_machine(p, action, pkt)
            retaction = (*curstate)(p, action, pkt);
 
 #ifdef PROTO_DEBUG
-       dbprintf(("%s: state_machine: p %X state %s returned %s\n",
+       dbprintf(("%s: state_machine: p %p state %s returned %s\n",
                  debug_prefix_time(": protocol"),
-                 (int)p, pstate2str(p->state), action2str(retaction)));
+                 p, pstate2str(p->state), action2str(retaction)));
 #endif
 
        /*
         * The state function is expected to return one of the following
-        * action_t's.
+        * p_action_t's.
         */
        switch (retaction) {
 
@@ -364,15 +371,15 @@ state_machine(p, action, pkt)
         * Setup to receive another pkt, and wait for the recv event
         * to occur.
         */
-       case A_CONTPEND:
+       case PA_CONTPEND:
            (*p->continuation)(p->datap, pkt, p->security_handle);
            /* FALLTHROUGH */
 
-       case A_PENDING:
+       case PA_PENDING:
 #ifdef PROTO_DEBUG
-           dbprintf(("%s: state_machine: p %X state %s: timeout %d\n",
+           dbprintf(("%s: state_machine: p %p state %s: timeout %d\n",
                      debug_prefix_time(": protocol"),
-                     (int)p, pstate2str(p->state), (int)p->timeout));
+                     p, pstate2str(p->state), (int)p->timeout));
 #endif
            /*
             * Get the security layer to register a receive event for this
@@ -380,19 +387,19 @@ state_machine(p, action, pkt)
             * seconds.
             */
            security_recvpkt(p->security_handle, recvpkt_callback, p,
-               p->timeout);
+               (int)p->timeout);
 
            return;
 
        /*
         * Request has moved to another state.  Loop and run it again.
         */
-       case A_CONTINUE:
+       case PA_CONTINUE:
            assert(p->state != curstate);
 #ifdef PROTO_DEBUG
-           dbprintf(("%s: state_machine: p %X: moved from %s to %s\n",
+           dbprintf(("%s: state_machine: p %p: moved from %s to %s\n",
                      debug_prefix_time(": protocol"),
-                     (unsigned int)p, pstate2str(curstate),
+                     p, pstate2str(curstate),
                      pstate2str(p->state)));
 #endif
            continue;
@@ -403,10 +410,10 @@ state_machine(p, action, pkt)
         * pkt to NULL to indicate failure to the callback, and then
         * fall through to the common finish code.
         *
-        * Note that remote failures finish via A_FINISH, because they did
+        * Note that remote failures finish via PA_FINISH, because they did
         * complete successfully locally.
         */
-       case A_ABORT:
+       case PA_ABORT:
            pkt = NULL;
            /* FALLTHROUGH */
 
@@ -415,10 +422,11 @@ state_machine(p, action, pkt)
         * Free up resources the request has used, call the continuation
         * function specified by the caller and quit.
         */
-       case A_FINISH:
+       case PA_FINISH:
            (*p->continuation)(p->datap, pkt, p->security_handle);
            security_close(p->security_handle);
            amfree(p->hostname);
+           amfree(p->req.body);
            amfree(p);
            return;
 
@@ -426,9 +434,9 @@ state_machine(p, action, pkt)
            assert(0);
            break;      /* in case asserts are turned off */
        }
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
-    /* NOTREACHED */
+    /*NOTREACHED*/
 }
 
 /*
@@ -437,20 +445,22 @@ state_machine(p, action, pkt)
  * moves to the acknowledgement wait state.  We return from the state
  * machine at this point, and let the request be received from the network.
  */
-static action_t
-s_sendreq(p, action, pkt)
-    proto_t *p;
-    action_t action;
-    pkt_t *pkt;
+static p_action_t
+s_sendreq(
+    proto_t *  p,
+    p_action_t action,
+    pkt_t *    pkt)
 {
 
     assert(p != NULL);
+    (void)action;      /* Quiet unused parameter warning */
+    (void)pkt;         /* Quiet unused parameter warning */
 
     if (security_sendpkt(p->security_handle, &p->req) < 0) {
        /* XXX should retry */
        security_seterror(p->security_handle, "error sending REQ: %s",
            security_geterror(p->security_handle));
-       return (A_ABORT);
+       return (PA_ABORT);
     }
 
     /*
@@ -463,27 +473,27 @@ s_sendreq(p, action, pkt)
      */
     p->state = s_ackwait;
     p->timeout = ACK_WAIT;
-    return (A_PENDING);
+    return (PA_PENDING);
 }
 
 /*
  * The acknowledge wait state.  We can enter here two ways:
  *
  *  - the caller has received a packet, located the request for
- *    that packet, and called us with an action of A_RCVDATA.
+ *    that packet, and called us with an action of PA_RCVDATA.
  *    
  *  - the caller has determined that a request has timed out,
- *    and has called us with A_TIMEOUT.
+ *    and has called us with PA_TIMEOUT.
  *
  * Here we process the acknowledgment, which usually means that
  * the client has agreed to our request and is working on it.
  * It will later send a reply when finished.
  */
-static action_t
-s_ackwait(p, action, pkt)
-    proto_t *p;
-    action_t action;
-    pkt_t *pkt;
+static p_action_t
+s_ackwait(
+    proto_t *  p,
+    p_action_t action,
+    pkt_t *    pkt)
 {
 
     assert(p != NULL);
@@ -493,19 +503,19 @@ s_ackwait(p, action, pkt)
      * fail this request.  Otherwise, move to the send state
      * to retry the request.
      */
-    if (action == A_TIMEOUT) {
+    if (action == PA_TIMEOUT) {
        assert(pkt == NULL);
 
        if (--p->acktries == 0) {
            security_seterror(p->security_handle, "timeout waiting for ACK");
-           return (A_ABORT);
+           return (PA_ABORT);
        }
 
        p->state = s_sendreq;
-       return (A_CONTINUE);
+       return (PA_CONTINUE);
     }
 
-    assert(action == A_RCVDATA);
+    assert(action == PA_RCVDATA);
     assert(pkt != NULL);
 
     /*
@@ -522,16 +532,16 @@ s_ackwait(p, action, pkt)
     case P_ACK:
        p->state = s_repwait;
        p->timeout = p->repwait;
-       return (A_PENDING);
+       return (PA_PENDING);
 
     /*
      * Received a NAK.  The request failed, so free up the
      * resources associated with it and return.
      *
-     * This should NOT return A_ABORT because it is not a local failure.
+     * This should NOT return PA_ABORT because it is not a local failure.
      */
     case P_NAK:
-       return (A_FINISH);
+       return (PA_FINISH);
 
     /*
      * The client skipped the ACK, and replied right away.
@@ -540,32 +550,32 @@ s_ackwait(p, action, pkt)
     case P_REP:
     case P_PREP:
        p->state = s_repwait;
-       return (A_CONTINUE);
+       return (PA_CONTINUE);
 
     /*
      * Unexpected packet.  Requeue this request and hope
      * we get what we want later.
      */
     default:
-       return (A_PENDING);
+       return (PA_PENDING);
     }
 }
 
 /*
  * The reply wait state.  We enter here much like we do with s_ackwait.
  */
-static action_t
-s_repwait(p, action, pkt)
-    proto_t *p;
-    action_t action;
-    pkt_t *pkt;
+static p_action_t
+s_repwait(
+    proto_t *  p,
+    p_action_t action,
+    pkt_t *    pkt)
 {
     pkt_t ack;
 
     /*
      * Timeout waiting for a reply.
      */
-    if (action == A_TIMEOUT) {
+    if (action == PA_TIMEOUT) {
        assert(pkt == NULL);
 
        /*
@@ -574,7 +584,7 @@ s_repwait(p, action, pkt)
         */
        if (p->reqtries == 0 || DROP_DEAD_TIME(p->origtime)) {
            security_seterror(p->security_handle, "timeout waiting for REP");
-           return (A_ABORT);
+           return (PA_ABORT);
        }
 
        /*
@@ -583,10 +593,10 @@ s_repwait(p, action, pkt)
        p->reqtries--;
        p->state = s_sendreq;
        p->acktries = ACK_TRIES;
-       return (A_CONTINUE);
+       return (PA_CONTINUE);
     }
 
-    assert(action == A_RCVDATA);
+    assert(action == PA_RCVDATA);
 
     /*
      * We've received some data.  If we didn't get a reply,
@@ -594,35 +604,37 @@ s_repwait(p, action, pkt)
      * the reply, cleanup this packet, and return.
      */
     if (pkt->type != P_REP && pkt->type != P_PREP)
-       return (A_PENDING);
+       return (PA_PENDING);
 
     if(pkt->type == P_REP) {
        pkt_init(&ack, P_ACK, "");
        if (security_sendpkt(p->security_handle, &ack) < 0) {
            /* XXX should retry */
+           amfree(ack.body);
            security_seterror(p->security_handle, "error sending ACK: %s",
                security_geterror(p->security_handle));
-           return (A_ABORT);
+           return (PA_ABORT);
        }
-       return (A_FINISH);
+       amfree(ack.body);
+       return (PA_FINISH);
     }
     else if(pkt->type == P_PREP) {
        p->timeout = p->repwait - CURTIME + p->curtime + 1;
-       return (A_CONTPEND);
+       return (PA_CONTPEND);
     }
 
     /* should never go here, shut up compiler warning */
-    return (A_FINISH);
+    return (PA_FINISH);
 }
 
 /*
  * event callback that receives a packet
  */
 static void
-recvpkt_callback(cookie, pkt, status)
-    void *cookie;
-    pkt_t *pkt;
-    security_status_t status;
+recvpkt_callback(
+    void *             cookie,
+    pkt_t *            pkt,
+    security_status_t  status)
 {
     proto_t *p = cookie;
 
@@ -630,13 +642,13 @@ recvpkt_callback(cookie, pkt, status)
 
     switch (status) {
     case S_OK:
-       state_machine(p, A_RCVDATA, pkt);
+       state_machine(p, PA_RCVDATA, pkt);
        break;
     case S_TIMEOUT:
-       state_machine(p, A_TIMEOUT, NULL);
+       state_machine(p, PA_TIMEOUT, NULL);
        break;
     case S_ERROR:
-       state_machine(p, A_ABORT, NULL);
+       state_machine(p, PA_ABORT, NULL);
        break;
     default:
        assert(0);
@@ -654,8 +666,8 @@ recvpkt_callback(cookie, pkt, status)
  * Convert a pstate_t into a printable form.
  */
 static const char *
-pstate2str(pstate)
-    pstate_t pstate;
+pstate2str(
+    pstate_t   pstate)
 {
     static const struct {
        pstate_t type;
@@ -676,26 +688,26 @@ pstate2str(pstate)
 }
 
 /*
- * Convert an action_t into a printable form
+ * Convert an p_action_t into a printable form
  */
 static const char *
-action2str(action)
-    action_t action;
+action2str(
+    p_action_t action)
 {
     static const struct {
-       action_t type;
+       p_action_t type;
        const char name[12];
     } actions[] = {
 #define        X(s)    { s, stringize(s) }
-       X(A_START),
-       X(A_TIMEOUT),
-       X(A_ERROR),
-       X(A_RCVDATA),
-       X(A_CONTPEND),
-       X(A_PENDING),
-       X(A_CONTINUE),
-       X(A_FINISH),
-       X(A_ABORT),
+       X(PA_START),
+       X(PA_TIMEOUT),
+       X(PA_ERROR),
+       X(PA_RCVDATA),
+       X(PA_CONTPEND),
+       X(PA_PENDING),
+       X(PA_CONTINUE),
+       X(PA_FINISH),
+       X(PA_ABORT),
 #undef X
     };
     int i;
index d4116a9ce2e9aa3c16d00c98f1badaa437465e06..215d35b10ad261f386822d6dfe5591a1bb408d23 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: protocol.h,v 1.10 2003/04/26 02:02:18 kovert Exp $
+ * $Id: protocol.h,v 1.11 2006/05/25 01:47:12 johnfranks Exp $
  *
  * server-side interfaces for amanda protocol state machine
  */
 
 #include "security.h"
 
-void protocol_init P((void));
-typedef        void (*protocol_sendreq_callback) P((void *, pkt_t *,
-    security_handle_t *));
-void protocol_sendreq P((const char *, const security_driver_t *, 
-       char *(*) P((char *, void *)), 
-       const char *,
-    time_t, protocol_sendreq_callback, void *));
-void protocol_check P((void));
-void protocol_run P((void));
+void protocol_init(void);
+typedef        void (*protocol_sendreq_callback)(void *, pkt_t *,
+    security_handle_t *);
+void protocol_sendreq(const char *, const security_driver_t *,
+       char *(*)(char *, void *), const char *, time_t,
+       protocol_sendreq_callback, void *);
+void protocol_check(void);
+void protocol_run(void);
 
 #endif /* PROTOCOL_H */
index fbdc7b1704d16ca6961bb783bf155cf686f1ba34..01a86da626be09450bb11e1cabb209f6d0dd08bb 100644 (file)
  * Authors: the Amanda Development Team.  Its members are listed in a
  * file named AUTHORS, in the root directory of this distribution.
  */
-/* $Id: regcomp.c,v 1.3 1998/07/04 00:18:51 oliva Exp $
+/* $Id: regcomp.c,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
  *
  * wrapper file for Henry Spencer's regcomp.c
  */
 
+#include "amanda.h"
 #include "amregex.h"
 #include "../regex-src/regcomp.c"
index c24e3290489a4adf35b58150db3e5d6e0548d8da..9761f81b4bbaa6fa6c6d3f985fb40ae801a55109 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*
- * $Id: rsh-security.c,v 1.18.2.1 2006/04/11 11:11:16 martinea Exp $
+ * $Id: rsh-security.c,v 1.31 2006/08/21 20:17:10 martinea Exp $
  *
  * rsh-security.c - security and transport over rsh or a rsh-like command.
  *
  */
 
 #include "amanda.h"
+#include "util.h"
 #include "event.h"
 #include "packet.h"
 #include "queue.h"
 #include "security.h"
+#include "security-util.h"
 #include "stream.h"
 #include "version.h"
 
@@ -59,7 +61,7 @@
 /*
  * Arguments to rsh.  This should also be configurable
  */
-#define        RSH_ARGS        "-l", CLIENT_LOGIN
+/*#define      RSH_ARGS        */
 
 /*
  * Number of seconds rsh has to start up
 #define        H_TAKEN -1              /* rsh_conn->tok was already read */
 #define        H_EOF   -2              /* this connection has been shut down */
 
-/*
- * This is a rsh connection to a host.  We should only have
- * one connection per host.
- */
-struct rsh_conn {
-    int read, write;                           /* pipes to rsh */
-    pid_t pid;                                 /* pid of rsh process */
-    char pkt[NETWORK_BLOCK_BYTES];             /* last pkt read */
-    unsigned long pktlen;                      /* len of above */
-    struct {                                   /* buffer read() calls */
-       char buf[STREAM_BUFSIZE];               /* buffer */
-       size_t left;                    /* unread data */
-       ssize_t size;                   /* size of last read */
-    } readbuf;
-    event_handle_t *ev_read;                   /* read (EV_READFD) handle */
-    int ev_read_refcnt;                                /* number of readers */
-    char hostname[MAX_HOSTNAME_LENGTH+1];      /* host we're talking to */
-    char *errmsg;                              /* error passed up */
-    int refcnt;                                        /* number of handles using */
-    int handle;                                        /* last proto handle read */
-    TAILQ_ENTRY(rsh_conn) tq;                  /* queue handle */
-};
-
-
-struct rsh_stream;
-
-/*
- * This is the private handle data.
- */
-struct rsh_handle {
-    security_handle_t sech;            /* MUST be first */
-    char *hostname;                    /* ptr to rc->hostname */
-    struct rsh_stream *rs;             /* virtual stream we xmit over */
-
-    union {
-       void (*recvpkt) P((void *, pkt_t *, security_status_t));
-                                       /* func to call when packet recvd */
-       void (*connect) P((void *, security_handle_t *, security_status_t));
-                                       /* func to call when connected */
-    } fn;
-    void *arg;                         /* argument to pass function */
-    event_handle_t *ev_timeout;                /* timeout handle for recv */
-};
-
-/*
- * This is the internal security_stream data for rsh.
- */
-struct rsh_stream {
-    security_stream_t secstr;          /* MUST be first */
-    struct rsh_conn *rc;               /* physical connection */
-    int handle;                                /* protocol handle */
-    event_handle_t *ev_read;           /* read (EV_WAIT) event handle */
-    void (*fn) P((void *, void *, ssize_t));   /* read event fn */
-    void *arg;                         /* arg for previous */
-};
-
 /*
  * Interface functions
  */
-static int rsh_sendpkt P((void *, pkt_t *));
-static int rsh_stream_accept P((void *));
-static int rsh_stream_auth P((void *));
-static int rsh_stream_id P((void *));
-static int rsh_stream_write P((void *, const void *, size_t));
-static void *rsh_stream_client P((void *, int));
-static void *rsh_stream_server P((void *));
-static void rsh_accept P((int, int,
-    void (*)(security_handle_t *, pkt_t *)));
-static void rsh_close P((void *));
-static void rsh_connect P((const char *,
-    char *(*)(char *, void *), 
-    void (*)(void *, security_handle_t *, security_status_t), void *));
-static void rsh_recvpkt P((void *,
-    void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void rsh_recvpkt_cancel P((void *));
-static void rsh_stream_close P((void *));
-static void rsh_stream_read P((void *, void (*)(void *, void *, ssize_t),
-    void *));
-static void rsh_stream_read_cancel P((void *));
+static void rsh_connect(const char *, char *(*)(char *, void *),
+                       void (*)(void *, security_handle_t *, security_status_t),
+                       void *, void *);
 
 /*
  * This is our interface to the outside world.
@@ -158,73 +87,30 @@ static void rsh_stream_read_cancel P((void *));
 const security_driver_t rsh_security_driver = {
     "RSH",
     rsh_connect,
-    rsh_accept,
-    rsh_close,
-    rsh_sendpkt,
-    rsh_recvpkt,
-    rsh_recvpkt_cancel,
-    rsh_stream_server,
-    rsh_stream_accept,
-    rsh_stream_client,
-    rsh_stream_close,
-    rsh_stream_auth,
-    rsh_stream_id,
-    rsh_stream_write,
-    rsh_stream_read,
-    rsh_stream_read_cancel,
-};
-
-/*
- * This is a queue of open connections
- */
-static struct {
-    TAILQ_HEAD(, rsh_conn) tailq;
-    int qlength;
-} connq = {
-    TAILQ_HEAD_INITIALIZER(connq.tailq), 0
+    sec_accept,
+    sec_close,
+    stream_sendpkt,
+    stream_recvpkt,
+    stream_recvpkt_cancel,
+    tcpma_stream_server,
+    tcpma_stream_accept,
+    tcpma_stream_client,
+    tcpma_stream_close,
+    sec_stream_auth,
+    sec_stream_id,
+    tcpm_stream_write,
+    tcpm_stream_read,
+    tcpm_stream_read_sync,
+    tcpm_stream_read_cancel,
+    tcpm_close_connection,
 };
-#define        connq_first()           TAILQ_FIRST(&connq.tailq)
-#define        connq_next(rc)          TAILQ_NEXT(rc, tq)
-#define        connq_append(rc)        do {                                    \
-    TAILQ_INSERT_TAIL(&connq.tailq, rc, tq);                           \
-    connq.qlength++;                                                   \
-} while (0)
-#define        connq_remove(rc)        do {                                    \
-    assert(connq.qlength > 0);                                         \
-    TAILQ_REMOVE(&connq.tailq, rc, tq);                                        \
-    connq.qlength--;                                                   \
-} while (0)
 
 static int newhandle = 1;
 
-/*
- * This is a function that should be called if a new security_handle_t is
- * created.  If NULL, no new handles are created.
- * It is passed the new handle and the received pkt
- */
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
-
 /*
  * Local functions
  */
-static void connect_callback P((void *));
-static void connect_timeout P((void *));
-static int send_token P((struct rsh_conn *, int, const void *, size_t));
-static int recv_token P((struct rsh_conn *, int));
-static void recvpkt_callback P((void *, void *, ssize_t));
-static void recvpkt_timeout P((void *));
-static void stream_read_callback P((void *));
-
-static int runrsh P((struct rsh_conn *));
-static struct rsh_conn *conn_get P((const char *));
-static void conn_put P((struct rsh_conn *));
-static void conn_read P((struct rsh_conn *));
-static void conn_read_cancel P((struct rsh_conn *));
-static void conn_read_callback P((void *));
-static int net_writev P((int, struct iovec *, int));
-static ssize_t net_read P((struct rsh_conn *, void *, size_t, int));
-static int net_read_fillbuf P((struct rsh_conn *, int, int));
-static void parse_pkt P((pkt_t *, const void *, size_t));
+static int runrsh(struct tcp_conn *, const char *, const char *);
 
 
 /*
@@ -232,21 +118,24 @@ static void parse_pkt P((pkt_t *, const void *, size_t));
  * up a network "connection".
  */
 static void
-rsh_connect(hostname, conf_fn, fn, arg)
-    const char *hostname;
-    char *(*conf_fn) P((char *, void *));
-    void (*fn) P((void *, security_handle_t *, security_status_t));
-    void *arg;
-{
-    struct rsh_handle *rh;
+rsh_connect(
+    const char *       hostname,
+    char *             (*conf_fn)(char *, void *),
+    void               (*fn)(void *, security_handle_t *, security_status_t),
+    void *             arg,
+    void *             datap)
+{
+    struct sec_handle *rh;
     struct hostent *he;
+    char *amandad_path=NULL, *client_username=NULL;
 
     assert(fn != NULL);
     assert(hostname != NULL);
 
-    rshprintf(("rsh_connect: %s\n", hostname));
+    rshprintf(("%s: rsh: rsh_connect: %s\n", debug_prefix_time(NULL),
+              hostname));
 
-    rh = alloc(sizeof(*rh));
+    rh = alloc(SIZEOF(*rh));
     security_handleinit(&rh->sech, &rsh_security_driver);
     rh->hostname = NULL;
     rh->rs = NULL;
@@ -258,26 +147,33 @@ rsh_connect(hostname, conf_fn, fn, arg)
        (*fn)(arg, &rh->sech, S_ERROR);
        return;
     }
-    rh->hostname = he->h_name; /* will be replaced */
-    rh->rs = rsh_stream_client(rh, newhandle++);
+    rh->hostname = stralloc(he->h_name);       /* will be replaced */
+    rh->rs = tcpma_stream_client(rh, newhandle++);
 
     if (rh->rs == NULL)
        goto error;
 
-    rh->hostname = rh->rs->rc->hostname;
+    amfree(rh->hostname);
+    rh->hostname = stralloc(rh->rs->rc->hostname);
 
-    if (rh->rs->rc->pid < 0) {
-       /*
-        * We need to open a new connection.
-        *
-        * XXX need to eventually limit number of outgoing connections here.
-        */
-       if (runrsh(rh->rs->rc) < 0) {
-           security_seterror(&rh->sech,
-               "can't connect to %s: %s", hostname, rh->rs->rc->errmsg);
+    /*
+     * We need to open a new connection.
+     *
+     * XXX need to eventually limit number of outgoing connections here.
+     */
+    if(conf_fn) {
+       amandad_path    = conf_fn("amandad_path", datap);
+       client_username = conf_fn("client_username", datap);
+    }
+    if(rh->rc->read == -1) {
+       if (runrsh(rh->rs->rc, amandad_path, client_username) < 0) {
+           security_seterror(&rh->sech, "can't connect to %s: %s",
+                             hostname, rh->rs->rc->errmsg);
            goto error;
        }
+       rh->rc->refcnt++;
     }
+
     /*
      * The socket will be opened async so hosts that are down won't
      * block everything.  We need to register a write event
@@ -288,10 +184,10 @@ rsh_connect(hostname, conf_fn, fn, arg)
      */
     rh->fn.connect = fn;
     rh->arg = arg;
-    rh->rs->ev_read = event_register(rh->rs->rc->write, EV_WRITEFD,
-       connect_callback, rh);
-    rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
-       connect_timeout, rh);
+    rh->rs->ev_read = event_register((event_id_t)rh->rs->rc->write, EV_WRITEFD,
+       sec_connect_callback, rh);
+    rh->ev_timeout = event_register((event_id_t)CONNECT_TIMEOUT, EV_TIME,
+       sec_connect_timeout, rh);
 
     return;
 
@@ -299,213 +195,30 @@ error:
     (*fn)(arg, &rh->sech, S_ERROR);
 }
 
-/*
- * Called when a rsh connection is finished connecting and is ready
- * to be authenticated.
- */
-static void
-connect_callback(cookie)
-    void *cookie;
-{
-    struct rsh_handle *rh = cookie;
-
-    event_release(rh->rs->ev_read);
-    rh->rs->ev_read = NULL;
-    event_release(rh->ev_timeout);
-    rh->ev_timeout = NULL;
-
-    (*rh->fn.connect)(rh->arg, &rh->sech, S_OK);
-}
-
-/*
- * Called if a connection times out before completion.
- */
-static void
-connect_timeout(cookie)
-    void *cookie;
-{
-    struct rsh_handle *rh = cookie;
-
-    event_release(rh->rs->ev_read);
-    rh->rs->ev_read = NULL;
-    event_release(rh->ev_timeout);
-    rh->ev_timeout = NULL;
-
-    (*rh->fn.connect)(rh->arg, &rh->sech, S_TIMEOUT);
-}
-
-/*
- * Setup to handle new incoming connections
- */
-static void
-rsh_accept(in, out, fn)
-    int in, out;
-    void (*fn) P((security_handle_t *, pkt_t *));
-{
-    struct rsh_conn *rc;
-
-    rc = conn_get("unknown");
-    rc->read = in;
-    rc->write = out;
-    accept_fn = fn;
-    conn_read(rc);
-}
-
-/*
- * Locate an existing connection to the given host, or create a new,
- * unconnected entry if none exists.  The caller is expected to check
- * for the lack of a connection (rc->read == -1) and set one up.
- */
-static struct rsh_conn *
-conn_get(hostname)
-    const char *hostname;
-{
-    struct rsh_conn *rc;
-
-    rshprintf(("rsh: conn_get: %s\n", hostname));
-
-    for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
-       if (strcasecmp(hostname, rc->hostname) == 0)
-           break;
-    }
-
-    if (rc != NULL) {
-       rc->refcnt++;
-       rshprintf(("rsh: conn_get: exists, refcnt to %s is now %d\n",
-           rc->hostname, rc->refcnt));
-       return (rc);
-    }
-
-    rshprintf(("rsh: conn_get: creating new handle\n"));
-    /*
-     * We can't be creating a new handle if we are the client
-     */
-    assert(accept_fn == NULL);
-    rc = alloc(sizeof(*rc));
-    rc->read = rc->write = -1;
-    rc->pid = -1;
-    rc->readbuf.left = 0;
-    rc->readbuf.size = 0;
-    rc->ev_read = NULL;
-    strncpy(rc->hostname, hostname, sizeof(rc->hostname) - 1);
-    rc->hostname[sizeof(rc->hostname) - 1] = '\0';
-    rc->errmsg = NULL;
-    rc->refcnt = 1;
-    rc->handle = -1;
-    connq_append(rc);
-    return (rc);
-}
-
-/*
- * Delete a reference to a connection, and close it if it is the last
- * reference.
- */
-static void
-conn_put(rc)
-    struct rsh_conn *rc;
-{
-    amwait_t status;
-
-    assert(rc->refcnt > 0);
-    if (--rc->refcnt > 0) {
-       rshprintf(("rsh: conn_put: decrementing refcnt for %s to %d\n",
-           rc->hostname, rc->refcnt));
-       return;
-    }
-    rshprintf(("rsh: conn_put: closing connection to %s\n", rc->hostname));
-    if (rc->read != -1)
-       aclose(rc->read);
-    if (rc->write != -1)
-       aclose(rc->write);
-    if (rc->pid != -1) {
-       waitpid(rc->pid, &status, WNOHANG);
-    }
-    if (rc->ev_read != NULL)
-       event_release(rc->ev_read);
-    if (rc->errmsg != NULL)
-       amfree(rc->errmsg);
-    connq_remove(rc);
-    amfree(rc);
-}
-
-/*
- * Turn on read events for a conn.  Or, increase a refcnt if we are
- * already receiving read events.
- */
-static void
-conn_read(rc)
-    struct rsh_conn *rc;
-{
-
-    if (rc->ev_read != NULL) {
-       rc->ev_read_refcnt++;
-       rshprintf(("rsh: conn_read: incremented refcnt to %d for %s\n",
-           rc->ev_read_refcnt, rc->hostname));
-       return;
-    }
-    rshprintf(("rsh: conn_read registering event handler for %s\n",
-       rc->hostname));
-    rc->ev_read = event_register(rc->read, EV_READFD, conn_read_callback, rc);
-    rc->ev_read_refcnt = 1;
-}
-
-static void
-conn_read_cancel(rc)
-    struct rsh_conn *rc;
-{
-
-    if (--rc->ev_read_refcnt > 0) {
-       rshprintf(("rsh: conn_read_cancel: decremented refcnt to %d for %s\n",
-           rc->ev_read_refcnt, rc->hostname));
-       return;
-    }
-    rshprintf(("rsh: conn_read_cancel: releasing event handler for %s\n",
-       rc->hostname));
-    event_release(rc->ev_read);
-    rc->ev_read = NULL;
-}
-
-/*
- * frees a handle allocated by the above
- */
-static void
-rsh_close(inst)
-    void *inst;
-{
-    struct rsh_handle *rh = inst;
-
-    assert(rh != NULL);
-
-    rshprintf(("rsh: closing handle to %s\n", rh->hostname));
-
-    if (rh->rs != NULL) {
-       /* This may be null if we get here on an error */
-       rsh_recvpkt_cancel(rh);
-       security_stream_close(&rh->rs->secstr);
-    }
-    /* keep us from getting here again */
-    rh->sech.driver = NULL;
-    amfree(rh);
-}
-
 /*
  * Forks a rsh to the host listed in rc->hostname
  * Returns negative on error, with an errmsg in rc->errmsg.
  */
 static int
-runrsh(rc)
-    struct rsh_conn *rc;
+runrsh(
+    struct tcp_conn *  rc,
+    const char *       amandad_path,
+    const char *       client_username)
 {
     int rpipe[2], wpipe[2];
-    char *amandad_path;
+    char *xamandad_path = (char *)amandad_path;
+    char *xclient_username = (char *)client_username;
 
+    memset(rpipe, -1, SIZEOF(rpipe));
+    memset(wpipe, -1, SIZEOF(wpipe));
     if (pipe(rpipe) < 0 || pipe(wpipe) < 0) {
-       rc->errmsg = newvstralloc("pipe: ", strerror(errno), NULL);
+       rc->errmsg = newvstralloc(rc->errmsg, "pipe: ", strerror(errno), NULL);
        return (-1);
     }
+
     switch (rc->pid = fork()) {
     case -1:
-       rc->errmsg = newvstralloc("fork: ", strerror(errno), NULL);
+       rc->errmsg = newvstralloc(rc->errmsg, "fork: ", strerror(errno), NULL);
        aclose(rpipe[0]);
        aclose(rpipe[1]);
        aclose(wpipe[0]);
@@ -514,7 +227,6 @@ runrsh(rc)
     case 0:
        dup2(wpipe[0], 0);
        dup2(rpipe[1], 1);
-       dup2(rpipe[1], 2);
        break;
     default:
        rc->read = rpipe[0];
@@ -526,693 +238,19 @@ runrsh(rc)
 
     safe_fd(-1, 0);
 
-    amandad_path = vstralloc(libexecdir, "/", "amandad", versionsuffix(),
-       NULL);
-    execlp(RSH_PATH, RSH_PATH, RSH_ARGS, rc->hostname, amandad_path,
-       "-auth=rsh", NULL);
+    if(!xamandad_path || strlen(xamandad_path) <= 1) 
+       xamandad_path = vstralloc(libexecdir, "/", "amandad",
+                                versionsuffix(), NULL);
+    if(!xclient_username || strlen(xclient_username) <= 1)
+       xclient_username = CLIENT_LOGIN;
+
+    execlp(RSH_PATH, RSH_PATH, "-l", xclient_username,
+          rc->hostname, xamandad_path, "-auth=rsh", "amdump", "amindexd",
+          "amidxtaped", (char *)NULL);
     error("error: couldn't exec %s: %s", RSH_PATH, strerror(errno));
 
-    /* should nerver go here, shut up compiler warning */
+    /* should never go here, shut up compiler warning */
     return(-1);
 }
 
-/*
- * Transmit a packet.
- */
-static int
-rsh_sendpkt(cookie, pkt)
-    void *cookie;
-    pkt_t *pkt;
-{
-    char buf[sizeof(pkt_t)];
-    struct rsh_handle *rh = cookie;
-    size_t len;
-
-    assert(rh != NULL);
-    assert(pkt != NULL);
-
-    rshprintf(("rsh: sendpkt: enter\n"));
-
-    len = strlen(pkt->body) + 2;
-    buf[0] = (char)pkt->type;
-    strcpy(&buf[1], pkt->body);
-
-    rshprintf(("rsh: sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
-       pkt_type2str(pkt->type), pkt->type, strlen(pkt->body), pkt->body));
-
-    if (rsh_stream_write(rh->rs, buf, len) < 0) {
-       security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
-       return (-1);
-    }
-    return (0);
-}
-
-/*
- * Set up to receive a packet asyncronously, and call back when
- * it has been read.
- */
-static void
-rsh_recvpkt(cookie, fn, arg, timeout)
-    void *cookie, *arg;
-    void (*fn) P((void *, pkt_t *, security_status_t));
-    int timeout;
-{
-    struct rsh_handle *rh = cookie;
-
-    assert(rh != NULL);
-
-    rshprintf(("rsh: recvpkt registered for %s\n", rh->hostname));
-
-    /*
-     * Reset any pending timeout on this handle
-     */
-    if (rh->ev_timeout != NULL)
-       event_release(rh->ev_timeout);
-
-    /*
-     * Negative timeouts mean no timeout
-     */
-    if (timeout < 0)
-       rh->ev_timeout = NULL;
-    else
-       rh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, rh);
-
-    rh->fn.recvpkt = fn;
-    rh->arg = arg;
-    rsh_stream_read(rh->rs, recvpkt_callback, rh);
-}
-
-/*
- * Remove a async receive request from the queue
- */
-static void
-rsh_recvpkt_cancel(cookie)
-    void *cookie;
-{
-    struct rsh_handle *rh = cookie;
-
-    rshprintf(("rsh: cancelling recvpkt for %s\n", rh->hostname));
-
-    assert(rh != NULL);
-
-    rsh_stream_read_cancel(rh->rs);
-    if (rh->ev_timeout != NULL) {
-       event_release(rh->ev_timeout);
-       rh->ev_timeout = NULL;
-    }
-}
-
-/*
- * This is called when a handle is woken up because data read off of the
- * net is for it.
- */
-static void
-recvpkt_callback(cookie, buf, bufsize)
-    void *cookie, *buf;
-    ssize_t bufsize;
-{
-    pkt_t pkt;
-    struct rsh_handle *rh = cookie;
-
-    assert(rh != NULL);
-
-    /*
-     * We need to cancel the recvpkt request before calling
-     * the callback because the callback may reschedule us.
-     */
-    rsh_recvpkt_cancel(rh);
-
-    switch (bufsize) {
-    case 0:
-       security_seterror(&rh->sech,
-           "EOF on read from %s", rh->hostname);
-       (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
-       return;
-    case -1:
-       security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
-       (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
-       return;
-    default:
-       break;
-    }
-
-    parse_pkt(&pkt, buf, bufsize);
-    rshprintf(("rsh: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n",
-       pkt_type2str(pkt.type), pkt.type, rh->hostname, pkt.body));
-    (*rh->fn.recvpkt)(rh->arg, &pkt, S_OK);
-}
-
-/*
- * This is called when a handle times out before receiving a packet.
- */
-static void
-recvpkt_timeout(cookie)
-    void *cookie;
-{
-    struct rsh_handle *rh = cookie;
-
-    assert(rh != NULL);
-
-    rshprintf(("rsh: recvpkt timeout for %s\n", rh->hostname));
-
-    rsh_recvpkt_cancel(rh);
-    (*rh->fn.recvpkt)(rh->arg, NULL, S_TIMEOUT);
-}
-
-/*
- * Create the server end of a stream.  For rsh, this means setup a stream
- * object and allocate a new handle for it.
- */
-static void *
-rsh_stream_server(h)
-    void *h;
-{
-    struct rsh_handle *rh = h;
-    struct rsh_stream *rs;
-
-    assert(rh != NULL);
-
-    rs = alloc(sizeof(*rs));
-    security_streaminit(&rs->secstr, &rsh_security_driver);
-    rs->rc = conn_get(rh->hostname);
-    /*
-     * Stream should already be setup!
-     */
-    if (rs->rc->read < 0) {
-       conn_put(rs->rc);
-       amfree(rs);
-       security_seterror(&rh->sech, "lost connection to %s", rh->hostname);
-       return (NULL);
-    }
-    rh->hostname = rs->rc->hostname;
-    /*
-     * so as not to conflict with the amanda server's handle numbers,
-     * we start at 5000 and work down
-     */
-    rs->handle = 5000 - newhandle++;
-    rs->ev_read = NULL;
-    rshprintf(("rsh: stream_server: created stream %d\n", rs->handle));
-    return (rs);
-}
-
-/*
- * Accept an incoming connection on a stream_server socket
- * Nothing needed for rsh.
- */
-static int
-rsh_stream_accept(s)
-    void *s;
-{
-
-    return (0);
-}
-
-/*
- * Return a connected stream.  For rsh, this means setup a stream
- * with the supplied handle.
- */
-static void *
-rsh_stream_client(h, id)
-    void *h;
-    int id;
-{
-    struct rsh_handle *rh = h;
-    struct rsh_stream *rs;
-
-    assert(rh != NULL);
-
-    if (id <= 0) {
-       security_seterror(&rh->sech,
-           "%d: invalid security stream id", id);
-       return (NULL);
-    }
-
-    rs = alloc(sizeof(*rs));
-    security_streaminit(&rs->secstr, &rsh_security_driver);
-    rs->handle = id;
-    rs->ev_read = NULL;
-    rs->rc = conn_get(rh->hostname);
-
-    rshprintf(("rsh: stream_client: connected to stream %d\n", id));
-
-    return (rs);
-}
-
-/*
- * Close and unallocate resources for a stream.
- */
-static void
-rsh_stream_close(s)
-    void *s;
-{
-    struct rsh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    rshprintf(("rsh: stream_close: closing stream %d\n", rs->handle));
-
-    rsh_stream_read_cancel(rs);
-    conn_put(rs->rc);
-    amfree(rs);
-}
-
-/*
- * Authenticate a stream
- * Nothing needed for rsh.  The connection is authenticated by rshd
- * on startup.
- */
-static int
-rsh_stream_auth(s)
-    void *s;
-{
-
-    return (0);
-}
-
-/*
- * Returns the stream id for this stream.  This is just the local
- * port.
- */
-static int
-rsh_stream_id(s)
-    void *s;
-{
-    struct rsh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    return (rs->handle);
-}
-
-/*
- * Write a chunk of data to a stream.  Blocks until completion.
- */
-static int
-rsh_stream_write(s, buf, size)
-    void *s;
-    const void *buf;
-    size_t size;
-{
-    struct rsh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    rshprintf(("rsh: stream_write: writing %d bytes to %s:%d\n", size,
-       rs->rc->hostname, rs->handle));
-
-    if (send_token(rs->rc, rs->handle, buf, size) < 0) {
-       security_stream_seterror(&rs->secstr, rs->rc->errmsg);
-       return (-1);
-    }
-    return (0);
-}
-
-/*
- * Submit a request to read some data.  Calls back with the given
- * function and arg when completed.
- */
-static void
-rsh_stream_read(s, fn, arg)
-    void *s, *arg;
-    void (*fn) P((void *, void *, ssize_t));
-{
-    struct rsh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    /*
-     * Only one read request can be active per stream.
-     */
-    if (rs->ev_read == NULL) {
-       rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
-           stream_read_callback, rs);
-       conn_read(rs->rc);
-    }
-    rs->fn = fn;
-    rs->arg = arg;
-}
-
-/*
- * Cancel a previous stream read request.  It's ok if we didn't have a read
- * scheduled.
- */
-static void
-rsh_stream_read_cancel(s)
-    void *s;
-{
-    struct rsh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    if (rs->ev_read != NULL) {
-       event_release(rs->ev_read);
-       rs->ev_read = NULL;
-       conn_read_cancel(rs->rc);
-    }
-}
-
-/*
- * Callback for rsh_stream_read
- */
-static void
-stream_read_callback(arg)
-    void *arg;
-{
-    struct rsh_stream *rs = arg;
-    assert(rs != NULL);
-
-    rshprintf(("rsh: stream_read_callback: handle %d\n", rs->handle));
-
-    /*
-     * Make sure this was for us.  If it was, then blow away the handle
-     * so it doesn't get claimed twice.  Otherwise, leave it alone.
-     *
-     * If the handle is EOF, pass that up to our callback.
-     */
-    if (rs->rc->handle == rs->handle) {
-       rshprintf(("rsh: stream_read_callback: it was for us\n"));
-       rs->rc->handle = H_TAKEN;
-    } else if (rs->rc->handle != H_EOF) {
-       rshprintf(("rsh: stream_read_callback: not for us\n"));
-       return;
-    }
-
-    /*
-     * Remove the event first, and then call the callback.
-     * We remove it first because we don't want to get in their
-     * way if they reschedule it.
-     */
-    rsh_stream_read_cancel(rs);
-
-    if (rs->rc->pktlen == 0) {
-       rshprintf(("rsh: stream_read_callback: EOF\n"));
-       (*rs->fn)(rs->arg, NULL, 0);
-       return;
-    }
-    rshprintf(("rsh: stream_read_callback: read %ld bytes from %s:%d\n",
-       rs->rc->pktlen, rs->rc->hostname, rs->handle));
-    (*rs->fn)(rs->arg, rs->rc->pkt, rs->rc->pktlen);
-}
-
-/*
- * The callback for the netfd for the event handler
- * Determines if this packet is for this security handle,
- * and does the real callback if so.
- */
-static void
-conn_read_callback(cookie)
-    void *cookie;
-{
-    struct rsh_conn *rc = cookie;
-    struct rsh_handle *rh;
-    pkt_t pkt;
-    int rval;
-
-    assert(cookie != NULL);
-
-    rshprintf(("rsh: conn_read_callback\n"));
-
-    /* Read the data off the wire.  If we get errors, shut down. */
-    rval = recv_token(rc, 60);
-    rshprintf(("rsh: conn_read_callback: recv_token returned %d\n", rval));
-    if (rval <= 0) {
-       rc->pktlen = 0;
-       rc->handle = H_EOF;
-       rval = event_wakeup((event_id_t)rc);
-       rshprintf(("rsh: conn_read_callback: event_wakeup return %d\n", rval));
-       /* delete our 'accept' reference */
-       if (accept_fn != NULL)
-           conn_put(rc);
-       accept_fn = NULL;
-       return;
-    }
-
-    /* If there are events waiting on this handle, we're done */
-    rval = event_wakeup((event_id_t)rc);
-    rshprintf(("rsh: conn_read_callback: event_wakeup return %d\n", rval));
-    if (rval > 0)
-       return;
-
-    /* If there is no accept fn registered, then drop the packet */
-    if (accept_fn == NULL)
-       return;
-
-    rh = alloc(sizeof(*rh));
-    security_handleinit(&rh->sech, &rsh_security_driver);
-    rh->hostname = rc->hostname;
-    rh->rs = rsh_stream_client(rh, rc->handle);
-    rh->ev_timeout = NULL;
-
-    rshprintf(("rsh: new connection\n"));
-    parse_pkt(&pkt, rc->pkt, rc->pktlen);
-    rshprintf(("rsh: calling accept_fn\n"));
-    (*accept_fn)(&rh->sech, &pkt);
-}
-
-static void
-parse_pkt(pkt, buf, bufsize)
-    pkt_t *pkt;
-    const void *buf;
-    size_t bufsize;
-{
-    const unsigned char *bufp = buf;
-
-    rshprintf(("rsh: parse_pkt: parsing buffer of %d bytes\n", bufsize));
-
-    pkt->type = (pktype_t)*bufp++;
-    bufsize--;
-
-    if (bufsize == 0) {
-       pkt->body[0] = '\0';
-    } else {
-       if (bufsize > sizeof(pkt->body) - 1)
-           bufsize = sizeof(pkt->body) - 1;
-       memcpy(pkt->body, bufp, bufsize);
-       pkt->body[sizeof(pkt->body) - 1] = '\0';
-    }
-
-    rshprintf(("rsh: parse_pkt: %s (%d): \"%s\"\n", pkt_type2str(pkt->type),
-       pkt->type, pkt->body));
-}
-
-
-/*
- * Transmits a chunk of data over a rsh_handle, adding
- * the necessary headers to allow the remote end to decode it.
- */
-static int
-send_token(rc, handle, buf, len)
-    struct rsh_conn *rc;
-    int handle;
-    const void *buf;
-    size_t len;
-{
-    unsigned int netlength, nethandle;
-    struct iovec iov[3];
-
-    rshprintf(("rsh: send_token: writing %d bytes to %s\n", len,
-       rc->hostname));
-
-    assert(sizeof(netlength) == 4);
-
-    /*
-     * Format is:
-     *   32 bit length (network byte order)
-     *   32 bit handle (network byte order)
-     *   data
-     */
-    netlength = htonl(len);
-    iov[0].iov_base = (void *)&netlength;
-    iov[0].iov_len = sizeof(netlength);
-
-    nethandle = htonl(handle);
-    iov[1].iov_base = (void *)&nethandle;
-    iov[1].iov_len = sizeof(nethandle);
-
-    iov[2].iov_base = (void *)buf;
-    iov[2].iov_len = len;
-
-    if (net_writev(rc->write, iov, 3) < 0) {
-       rc->errmsg = newvstralloc(rc->errmsg, "rsh write error to ",
-           rc->hostname, ": ", strerror(errno), NULL);
-       return (-1);
-    }
-    return (0);
-}
-
-static int
-recv_token(rc, timeout)
-    struct rsh_conn *rc;
-    int timeout;
-{
-    unsigned int netint;
-
-    assert(sizeof(netint) == 4);
-
-    assert(rc->read >= 0);
-
-    rshprintf(("rsh: recv_token: reading from %s\n", rc->hostname));
-
-    switch (net_read(rc, &netint, sizeof(netint), timeout)) {
-    case -1:
-       rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
-           NULL);
-       return (-1);
-    case 0:
-       rc->pktlen = 0;
-       return (0);
-    default:
-       break;
-    }
-    rc->pktlen = ntohl(netint);
-    if (rc->pktlen > sizeof(rc->pkt)) {
-       rc->errmsg = newstralloc(rc->errmsg, "recv error: huge packet");
-       return (-1);
-    }
-
-    switch (net_read(rc, &netint, sizeof(netint), timeout)) {
-    case -1:
-       rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
-           NULL);
-       return (-1);
-    case 0:
-       rc->pktlen = 0;
-       return (0);
-    default:
-       break;
-    }
-    rc->handle = ntohl(netint);
-
-    switch (net_read(rc, rc->pkt, rc->pktlen, timeout)) {
-    case -1:
-       rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
-           NULL);
-       return (-1);
-    case 0:
-       rc->pktlen = 0;
-       break;
-    default:
-       break;
-    }
-
-    rshprintf(("rsh: recv_token: read %ld bytes from %s\n", rc->pktlen,
-       rc->hostname));
-    return (rc->pktlen);
-}
-
-/*
- * Writes out the entire iovec
- */
-static int
-net_writev(fd, iov, iovcnt)
-    int fd, iovcnt;
-    struct iovec *iov;
-{
-    int delta, n, total;
-
-    assert(iov != NULL);
-
-    total = 0;
-    while (iovcnt > 0) {
-       /*
-        * Write the iovec
-        */
-       total += n = writev(fd, iov, iovcnt);
-       if (n < 0)
-           return (-1);
-       if (n == 0) {
-           errno = EIO;
-           return (-1);
-       }
-       /*
-        * Iterate through each iov.  Figure out what we still need
-        * to write out.
-        */
-       for (; n > 0; iovcnt--, iov++) {
-           /* 'delta' is the bytes written from this iovec */
-           delta = n < iov->iov_len ? n : iov->iov_len;
-           /* subtract from the total num bytes written */
-           n -= delta;
-           assert(n >= 0);
-           /* subtract from this iovec */
-           iov->iov_len -= delta;
-           iov->iov_base = (char *)iov->iov_base + delta;
-           /* if this iovec isn't empty, run the writev again */
-           if (iov->iov_len > 0)
-               break;
-       }
-    }
-    return (total);
-}
-
-/*
- * Like read(), but waits until the entire buffer has been filled.
- */
-static ssize_t
-net_read(rc, vbuf, origsize, timeout)
-    struct rsh_conn *rc;
-    void *vbuf;
-    size_t origsize;
-    int timeout;
-{
-    char *buf = vbuf, *off;    /* ptr arith */
-    int nread;
-    size_t size = origsize;
-
-    while (size > 0) {
-       if (rc->readbuf.left == 0) {
-           if (net_read_fillbuf(rc, timeout, size) < 0)
-               return (-1);
-           if (rc->readbuf.size == 0)
-               return (0);
-       }
-       nread = min(rc->readbuf.left, size);
-       off = rc->readbuf.buf + rc->readbuf.size - rc->readbuf.left;
-       memcpy(buf, off, nread);
-
-       buf += nread;
-       size -= nread;
-       rc->readbuf.left -= nread;
-    }
-    return ((ssize_t)origsize);
-}
-
-/*
- * net_read likes to do a lot of little reads.  Buffer it.
- */
-static int
-net_read_fillbuf(rc, timeout, size)
-    struct rsh_conn *rc;
-    int timeout;
-    int size;
-{
-    fd_set readfds;
-    struct timeval tv;
-    if(size > sizeof(rc->readbuf.buf)) size = sizeof(rc->readbuf.buf);
-
-    FD_ZERO(&readfds);
-    FD_SET(rc->read, &readfds);
-    tv.tv_sec = timeout;
-    tv.tv_usec = 0;
-    switch (select(rc->read + 1, &readfds, NULL, NULL, &tv)) {
-    case 0:
-       errno = ETIMEDOUT;
-       /* FALLTHROUGH */
-    case -1:
-       return (-1);
-    case 1:
-       assert(FD_ISSET(rc->read, &readfds));
-       break;
-    default:
-       assert(0);
-       break;
-    }
-    rc->readbuf.left = 0;
-    rc->readbuf.size = read(rc->read, rc->readbuf.buf, size);
-    if (rc->readbuf.size < 0)
-       return (-1);
-    rc->readbuf.left = rc->readbuf.size;
-    return (0);
-}
-
 #endif /* RSH_SECURITY */
diff --git a/common-src/security-util.c b/common-src/security-util.c
new file mode 100644 (file)
index 0000000..531ec86
--- /dev/null
@@ -0,0 +1,2630 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1999 University of Maryland
+ * 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+
+/*
+ * $Id: security-util.c,v 1.25 2006/07/22 12:04:47 martinea Exp $
+ *
+ * sec-security.c - security and transport over sec or a sec-like command.
+ *
+ * XXX still need to check for initial keyword on connect so we can skip
+ * over shell garbage and other stuff that sec might want to spew out.
+ */
+
+#include "amanda.h"
+#include "util.h"
+#include "event.h"
+#include "packet.h"
+#include "queue.h"
+#include "security.h"
+#include "security-util.h"
+#include "stream.h"
+#include "version.h"
+
+/* #define     SEC_DEBUG */
+#define        SHOW_SECURITY_DETAIL
+
+#ifdef SEC_DEBUG
+#  define      secprintf(x)    dbprintf(x)
+#else
+#  ifdef __lint
+#    define    secprintf(x)    (void)(x)
+#  else
+#    define    secprintf(x)
+#  endif
+#endif
+
+/*
+ * Magic values for sec_conn->handle
+ */
+#define        H_TAKEN -1              /* sec_conn->tok was already read */
+#define        H_EOF   -2              /* this connection has been shut down */
+
+/*
+ * This is a queue of open connections
+ */
+struct connq_s connq = {
+    TAILQ_HEAD_INITIALIZER(connq.tailq), 0
+};
+static int newhandle = 1;
+static int newevent = 1;
+
+/*
+ * Local functions
+ */
+static void recvpkt_callback(void *, void *, ssize_t);
+static void stream_read_callback(void *);
+static void stream_read_sync_callback(void *);
+
+static void sec_tcp_conn_read_cancel(struct tcp_conn *);
+static void sec_tcp_conn_read_callback(void *);
+
+
+/*
+ * Authenticate a stream
+ * Nothing needed for sec.  The connection is authenticated by secd
+ * on startup.
+ */
+int
+sec_stream_auth(
+    void *     s)
+{
+    (void)s;   /* Quiet unused parameter warning */
+    return (0);
+}
+
+/*
+ * Returns the stream id for this stream.  This is just the local
+ * port.
+ */
+int
+sec_stream_id(
+    void *     s)
+{
+    struct sec_stream *rs = s;
+
+    assert(rs != NULL);
+
+    return (rs->handle);
+}
+
+/*
+ * Setup to handle new incoming connections
+ */
+void
+sec_accept(
+    const security_driver_t *driver,
+    int                in,
+    int                out,
+    void       (*fn)(security_handle_t *, pkt_t *))
+{
+    struct tcp_conn *rc;
+
+    rc = sec_tcp_conn_get("unknown",0);
+    rc->read = in;
+    rc->write = out;
+    rc->accept_fn = fn;
+    rc->driver = driver;
+    sec_tcp_conn_read(rc);
+}
+
+/*
+ * frees a handle allocated by the above
+ */
+void
+sec_close(
+    void *     inst)
+{
+    struct sec_handle *rh = inst;
+
+    assert(rh != NULL);
+
+    secprintf(("%s: sec: closing handle to %s\n", debug_prefix_time(NULL),
+              rh->hostname));
+
+    if (rh->rs != NULL) {
+       /* This may be null if we get here on an error */
+       stream_recvpkt_cancel(rh);
+       security_stream_close(&rh->rs->secstr);
+    }
+    /* keep us from getting here again */
+    rh->sech.driver = NULL;
+    amfree(rh->hostname);
+    amfree(rh);
+}
+
+/*
+ * Called when a sec connection is finished connecting and is ready
+ * to be authenticated.
+ */
+void
+sec_connect_callback(
+    void *     cookie)
+{
+    struct sec_handle *rh = cookie;
+
+    event_release(rh->rs->ev_read);
+    rh->rs->ev_read = NULL;
+    event_release(rh->ev_timeout);
+    rh->ev_timeout = NULL;
+
+    (*rh->fn.connect)(rh->arg, &rh->sech, S_OK);
+}
+
+/*
+ * Called if a connection times out before completion.
+ */
+void
+sec_connect_timeout(
+    void *     cookie)
+{
+    struct sec_handle *rh = cookie;
+
+    event_release(rh->rs->ev_read);
+    rh->rs->ev_read = NULL;
+    event_release(rh->ev_timeout);
+    rh->ev_timeout = NULL;
+
+    (*rh->fn.connect)(rh->arg, &rh->sech, S_TIMEOUT);
+}
+
+void
+sec_close_connection_none(
+    void *h,
+    char *hostname)
+{
+    h = h;
+    hostname = hostname;
+
+    return;
+}
+
+
+
+/*
+ * Transmit a packet.
+ */
+ssize_t
+stream_sendpkt(
+    void *     cookie,
+    pkt_t *    pkt)
+{
+    char *buf;
+    struct sec_handle *rh = cookie;
+    size_t len;
+    char *s;
+
+    assert(rh != NULL);
+    assert(pkt != NULL);
+
+    secprintf(("%s: sec: stream_sendpkt: enter\n", debug_prefix_time(NULL)));
+
+    if (rh->rc->prefix_packet)
+       s = rh->rc->prefix_packet(rh, pkt);
+    else
+       s = "";
+    len = strlen(pkt->body) + strlen(s) + 2;
+    buf = alloc(len);
+    buf[0] = (char)pkt->type;
+    strncpy(&buf[1], s, len - 1);
+    strncpy(&buf[1 + strlen(s)], pkt->body, (len - strlen(s) - 1));
+    if (strlen(s) > 0)
+       amfree(s);
+
+    secprintf((
+           "%s: sec: stream_sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
+           debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->type,
+           strlen(pkt->body), pkt->body));
+
+    if (security_stream_write(&rh->rs->secstr, buf, len) < 0) {
+       security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
+       return (-1);
+    }
+    amfree(buf);
+    return (0);
+}
+
+/*
+ * Set up to receive a packet asyncronously, and call back when
+ * it has been read.
+ */
+void
+stream_recvpkt(
+    void *     cookie,
+    void       (*fn)(void *, pkt_t *, security_status_t),
+    void *     arg,
+    int                timeout)
+{
+    struct sec_handle *rh = cookie;
+
+    assert(rh != NULL);
+
+    secprintf(("%s: sec: recvpkt registered for %s\n",
+              debug_prefix_time(NULL), rh->hostname));
+
+    /*
+     * Reset any pending timeout on this handle
+     */
+    if (rh->ev_timeout != NULL)
+       event_release(rh->ev_timeout);
+
+    /*
+     * Negative timeouts mean no timeout
+     */
+    if (timeout < 0) {
+       rh->ev_timeout = NULL;
+    } else {
+       rh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
+               stream_recvpkt_timeout, rh);
+    }
+    rh->fn.recvpkt = fn;
+    rh->arg = arg;
+    security_stream_read(&rh->rs->secstr, recvpkt_callback, rh);
+}
+
+/*
+ * This is called when a handle times out before receiving a packet.
+ */
+void
+stream_recvpkt_timeout(
+    void *     cookie)
+{
+    struct sec_handle *rh = cookie;
+
+    assert(rh != NULL);
+
+    secprintf(("%s: sec: recvpkt timeout for %s\n",
+              debug_prefix_time(NULL), rh->hostname));
+
+    stream_recvpkt_cancel(rh);
+    (*rh->fn.recvpkt)(rh->arg, NULL, S_TIMEOUT);
+}
+
+/*
+ * Remove a async receive request from the queue
+ */
+void
+stream_recvpkt_cancel(
+    void *     cookie)
+{
+    struct sec_handle *rh = cookie;
+
+    secprintf(("%s: sec: cancelling recvpkt for %s\n",
+              debug_prefix_time(NULL), rh->hostname));
+
+    assert(rh != NULL);
+
+    security_stream_read_cancel(&rh->rs->secstr);
+    if (rh->ev_timeout != NULL) {
+       event_release(rh->ev_timeout);
+       rh->ev_timeout = NULL;
+    }
+}
+
+/*
+ * Write a chunk of data to a stream.  Blocks until completion.
+ */
+int
+tcpm_stream_write(
+    void *     s,
+    const void *buf,
+    size_t     size)
+{
+    struct sec_stream *rs = s;
+
+    assert(rs != NULL);
+    assert(rs->rc != NULL);
+
+    secprintf(("%s: sec: stream_write: writing %d bytes to %s:%d %d\n",
+              debug_prefix_time(NULL), size, rs->rc->hostname, rs->handle,
+              rs->rc->write));
+
+    if (tcpm_send_token(rs->rc->write, rs->handle, &rs->rc->errmsg,
+                            buf, size)) {
+       security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+       return (-1);
+    }
+    return (0);
+}
+
+/*
+ * Submit a request to read some data.  Calls back with the given
+ * function and arg when completed.
+ */
+void
+tcpm_stream_read(
+    void *     s,
+    void       (*fn)(void *, void *, ssize_t),
+    void *     arg)
+{
+    struct sec_stream *rs = s;
+
+    assert(rs != NULL);
+
+    /*
+     * Only one read request can be active per stream.
+     */
+    if (rs->ev_read == NULL) {
+       rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
+           stream_read_callback, rs);
+       sec_tcp_conn_read(rs->rc);
+    }
+    rs->fn = fn;
+    rs->arg = arg;
+}
+
+/*
+ * Write a chunk of data to a stream.  Blocks until completion.
+ */
+ssize_t
+tcpm_stream_read_sync(
+    void *     s,
+    void **    buf)
+{
+    struct sec_stream *rs = s;
+
+    assert(rs != NULL);
+
+    /*
+     * Only one read request can be active per stream.
+     */
+    if (rs->ev_read != NULL) {
+       return -1;
+    }
+    rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
+        stream_read_sync_callback, rs);
+    sec_tcp_conn_read(rs->rc);
+    event_wait(rs->ev_read);
+    *buf = rs->rc->pkt;
+    return (rs->rc->pktlen);
+}
+
+/*
+ * Cancel a previous stream read request.  It's ok if we didn't have a read
+ * scheduled.
+ */
+void
+tcpm_stream_read_cancel(
+    void *     s)
+{
+    struct sec_stream *rs = s;
+
+    assert(rs != NULL);
+
+    if (rs->ev_read != NULL) {
+       event_release(rs->ev_read);
+       rs->ev_read = NULL;
+       sec_tcp_conn_read_cancel(rs->rc);
+    }
+}
+
+/*
+ * Transmits a chunk of data over a rsh_handle, adding
+ * the necessary headers to allow the remote end to decode it.
+ */
+ssize_t
+tcpm_send_token(
+    int                fd,
+    int                handle,
+    char **    errmsg,
+    const void *buf,
+    size_t     len)
+{
+    uint32_t           nethandle;
+    uint32_t           netlength;
+    struct iovec       iov[3];
+    int                        nb_iov = 3;
+
+    assert(SIZEOF(netlength) == 4);
+
+    /*
+     * Format is:
+     *   32 bit length (network byte order)
+     *   32 bit handle (network byte order)
+     *   data
+     */
+    netlength = htonl(len);
+    iov[0].iov_base = (void *)&netlength;
+    iov[0].iov_len = SIZEOF(netlength);
+
+    nethandle = htonl((uint32_t)handle);
+    iov[1].iov_base = (void *)&nethandle;
+    iov[1].iov_len = SIZEOF(nethandle);
+
+    if(len == 0) {
+       nb_iov = 2;
+    }
+    else {
+       iov[2].iov_base = (void *)buf;
+       iov[2].iov_len = len;
+        nb_iov = 3;
+    }
+
+    if (net_writev(fd, iov, nb_iov) < 0) {
+       if (errmsg)
+            *errmsg = newvstralloc(*errmsg, "write error to ",
+                                  ": ", strerror(errno), NULL);
+        return (-1);
+    }
+    return (0);
+}
+
+/*
+ *  return -1 on error
+ *  return  0 on EOF:   *handle = H_EOF  && *size = 0    if socket closed
+ *  return  0 on EOF:   *handle = handle && *size = 0    if stream closed
+ *  return size     :   *handle = handle && *size = size for data read
+ */
+
+ssize_t
+tcpm_recv_token(
+    int                fd,
+    int *      handle,
+    char **    errmsg,
+    char **    buf,
+    ssize_t *  size,
+    int                timeout)
+{
+    unsigned int netint[2];
+
+    assert(SIZEOF(netint) == 8);
+
+    switch (net_read(fd, &netint, SIZEOF(netint), timeout)) {
+    case -1:
+       if (errmsg)
+           *errmsg = newvstralloc(*errmsg, "recv error: ", strerror(errno),
+                                  NULL);
+       secprintf(("%s: tcpm_recv_token: A return(-1)\n",
+                  debug_prefix_time(NULL)));
+       return (-1);
+    case 0:
+       *size = 0;
+       *handle = H_EOF;
+       *errmsg = newvstralloc(*errmsg, "SOCKET_EOF", NULL);
+       secprintf(("%s: tcpm_recv_token: A return(0)\n",
+                  debug_prefix_time(NULL)));
+       return (0);
+    default:
+       break;
+    }
+
+    *size = (ssize_t)ntohl(netint[0]);
+    if (*size > NETWORK_BLOCK_BYTES) {
+       *errmsg = newvstralloc(*errmsg, "tcpm_recv_token: invalid size",
+                                  NULL);
+       dbprintf(("%s: tcpm_recv_token: invalid size %d\n",
+                  debug_prefix_time(NULL), *size));
+       *size = -1;
+       return -1;
+    }
+    amfree(*buf);
+    *buf = alloc((size_t)*size);
+    *handle = (int)ntohl(netint[1]);
+
+    if(*size == 0) {
+       secprintf(("%s: tcpm_recv_token: read EOF from %d\n",
+                  debug_prefix_time(NULL), *handle));
+       *errmsg = newvstralloc(*errmsg, "EOF",
+                                  NULL);
+       return 0;
+    }
+    switch (net_read(fd, *buf, (size_t)*size, timeout)) {
+    case -1:
+       if (errmsg)
+           *errmsg = newvstralloc(*errmsg, "recv error: ", strerror(errno),
+                                  NULL);
+       secprintf(("%s: tcpm_recv_token: B return(-1)\n",
+                  debug_prefix_time(NULL)));
+       return (-1);
+    case 0:
+       *size = 0;
+       *errmsg = newvstralloc(*errmsg, "SOCKET_EOF", NULL);
+       secprintf(("%s: tcpm_recv_token: B return(0)\n",
+                  debug_prefix_time(NULL)));
+       return (0);
+    default:
+       break;
+    }
+
+    secprintf(("%s: tcpm_recv_token: read %ld bytes from %d\n",
+              debug_prefix_time(NULL), *size, *handle));
+    return((*size));
+}
+
+void
+tcpm_close_connection(
+    void *h,
+    char *hostname)
+{
+    struct sec_handle *rh = h;
+
+    hostname = hostname;
+
+    if(rh->rc->toclose == 0) {
+       rh->rc->toclose = 1;
+       sec_tcp_conn_put(rh->rc);
+    }
+}
+
+
+
+/*
+ * Accept an incoming connection on a stream_server socket
+ * Nothing needed for tcpma.
+ */
+int
+tcpma_stream_accept(
+    void *     s)
+{
+    (void)s;   /* Quiet unused parameter warning */
+
+    return (0);
+}
+
+/*
+ * Return a connected stream.  For sec, this means setup a stream
+ * with the supplied handle.
+ */
+void *
+tcpma_stream_client(
+    void *     h,
+    int                id)
+{
+    struct sec_handle *rh = h;
+    struct sec_stream *rs;
+
+    assert(rh != NULL);
+
+    if (id <= 0) {
+       security_seterror(&rh->sech,
+           "%hd: invalid security stream id", id);
+       return (NULL);
+    }
+
+    rs = alloc(SIZEOF(*rs));
+    security_streaminit(&rs->secstr, rh->sech.driver);
+    rs->handle = id;
+    rs->ev_read = NULL;
+    rs->closed_by_me = 0;
+    rs->closed_by_network = 0;
+    if (rh->rc) {
+       rs->rc = rh->rc;
+       rh->rc->refcnt++;
+    }
+    else {
+       rs->rc = sec_tcp_conn_get(rh->hostname, 0);
+       rs->rc->driver = rh->sech.driver;
+       rh->rc = rs->rc;
+    }
+
+    secprintf(("%s: sec: stream_client: connected to stream %hd\n",
+              debug_prefix_time(NULL), id));
+
+    return (rs);
+}
+
+/*
+ * Create the server end of a stream.  For sec, this means setup a stream
+ * object and allocate a new handle for it.
+ */
+void *
+tcpma_stream_server(
+    void *     h)
+{
+    struct sec_handle *rh = h;
+    struct sec_stream *rs;
+
+    assert(rh != NULL);
+
+    rs = alloc(SIZEOF(*rs));
+    security_streaminit(&rs->secstr, rh->sech.driver);
+    rs->closed_by_me = 0;
+    rs->closed_by_network = 0;
+    if (rh->rc) {
+       rs->rc = rh->rc;
+       rs->rc->refcnt++;
+    }
+    else {
+       rs->rc = sec_tcp_conn_get(rh->hostname, 0);
+       rs->rc->driver = rh->sech.driver;
+       rh->rc = rs->rc;
+    }
+    /*
+     * Stream should already be setup!
+     */
+    if (rs->rc->read < 0) {
+       sec_tcp_conn_put(rs->rc);
+       amfree(rs);
+       security_seterror(&rh->sech, "lost connection to %s", rh->hostname);
+       return (NULL);
+    }
+    assert(strcmp(rh->hostname, rs->rc->hostname) == 0);
+    //amfree(rh->hostname);
+    //rh->hostname = stralloc(rs->rc->hostname);
+    /*
+     * so as not to conflict with the amanda server's handle numbers,
+     * we start at 500000 and work down
+     */
+    rs->handle = 500000 - newhandle++;
+    rs->ev_read = NULL;
+    secprintf(("%s: sec: stream_server: created stream %d\n",
+              debug_prefix_time(NULL), rs->handle));
+    return (rs);
+}
+
+/*
+ * Close and unallocate resources for a stream.
+ */
+void
+tcpma_stream_close(
+    void *     s)
+{
+    struct sec_stream *rs = s;
+    char buf = 0;
+
+    assert(rs != NULL);
+
+    secprintf(("%s: sec: tcpma_stream_close: closing stream %d\n",
+              debug_prefix_time(NULL), rs->handle));
+
+    if(rs->closed_by_network == 0 && rs->rc->write != -1)
+       tcpm_stream_write(rs, &buf, 0);
+    security_stream_read_cancel(&rs->secstr);
+    if(rs->closed_by_network == 0)
+       sec_tcp_conn_put(rs->rc);
+    amfree(rs);
+}
+
+/*
+ * Create the server end of a stream.  For bsdudp, this means setup a tcp
+ * socket for receiving a connection.
+ */
+void *
+tcp1_stream_server(
+    void *     h)
+{
+    struct sec_stream *rs = NULL;
+    struct sec_handle *rh = h;
+
+    assert(rh != NULL);
+
+    rs = alloc(SIZEOF(*rs));
+    security_streaminit(&rs->secstr, rh->sech.driver);
+    rs->closed_by_me = 0;
+    rs->closed_by_network = 0;
+    if (rh->rc) {
+       rs->rc = rh->rc;
+       rs->handle = 500000 - newhandle++;
+       rs->rc->refcnt++;
+       rs->socket = 0;         /* the socket is already opened */
+    }
+    else {
+       rh->rc = sec_tcp_conn_get(rh->hostname, 1);
+       rh->rc->driver = rh->sech.driver;
+       rs->rc = rh->rc;
+       rs->socket = stream_server(&rs->port, STREAM_BUFSIZE, 
+               STREAM_BUFSIZE, 0);
+       if (rs->socket < 0) {
+           security_seterror(&rh->sech,
+                           "can't create server stream: %s", strerror(errno));
+           amfree(rs);
+           return (NULL);
+       }
+       rh->rc->read = rs->socket;
+       rh->rc->write = rs->socket;
+       rs->handle = (int)rs->port;
+    }
+    rs->fd = -1;
+    rs->ev_read = NULL;
+    return (rs);
+}
+
+/*
+ * Accepts a new connection on unconnected streams.  Assumes it is ok to
+ * block on accept()
+ */
+int
+tcp1_stream_accept(
+    void *     s)
+{
+    struct sec_stream *bs = s;
+
+    assert(bs != NULL);
+    assert(bs->socket != -1);
+    assert(bs->fd < 0);
+
+    if (bs->socket > 0) {
+       bs->fd = stream_accept(bs->socket, 30, STREAM_BUFSIZE, STREAM_BUFSIZE);
+       if (bs->fd < 0) {
+           security_stream_seterror(&bs->secstr,
+                                    "can't accept new stream connection: %s",
+                                    strerror(errno));
+           return (-1);
+       }
+       bs->rc->read = bs->fd;
+       bs->rc->write = bs->fd;
+    }
+    return (0);
+}
+
+/*
+ * Return a connected stream
+ */
+void *
+tcp1_stream_client(
+    void *     h,
+    int                id)
+{
+    struct sec_stream *rs = NULL;
+    struct sec_handle *rh = h;
+
+    assert(rh != NULL);
+
+    rs = alloc(SIZEOF(*rs));
+    security_streaminit(&rs->secstr, rh->sech.driver);
+    rs->handle = id;
+    rs->ev_read = NULL;
+    rs->closed_by_me = 0;
+    rs->closed_by_network = 0;
+    if (rh->rc) {
+       rs->rc = rh->rc;
+       rh->rc->refcnt++;
+    }
+    else {
+       rh->rc = sec_tcp_conn_get(rh->hostname, 1);
+       rs->rc = rh->rc;
+       rh->rc->read = stream_client(rh->hostname, (in_port_t)id,
+                       STREAM_BUFSIZE, STREAM_BUFSIZE, &rs->port, 0);
+       if (rh->rc->read < 0) {
+           security_seterror(&rh->sech,
+                             "can't connect stream to %s port %d: %s",
+                              rh->hostname, id, strerror(errno));
+           amfree(rs);
+           return (NULL);
+        }
+       rh->rc->write = rh->rc->read;
+    }
+    rs->socket = -1;   /* we're a client */
+    rh->rs = rs;
+    return (rs);
+}
+
+int
+tcp_stream_write(
+    void *     s,
+    const void *buf,
+    size_t     size)
+{
+    struct sec_stream *rs = s;
+
+    assert(rs != NULL);
+
+    if (fullwrite(rs->fd, buf, size) < 0) {
+        security_stream_seterror(&rs->secstr,
+            "write error on stream %d: %s", rs->port, strerror(errno));
+        return (-1);
+    }
+    return (0);
+}
+
+char *
+bsd_prefix_packet(
+    void *     h,
+    pkt_t *    pkt)
+{
+    struct sec_handle *rh = h;
+    struct passwd *pwd;
+    char *buf;
+
+    if (pkt->type != P_REQ)
+       return "";
+
+    if ((pwd = getpwuid(getuid())) == NULL) {
+       security_seterror(&rh->sech,
+                         "can't get login name for my uid %ld",
+                         (long)getuid());
+       return(NULL);
+    }
+    buf = alloc(16+strlen(pwd->pw_name));
+    strncpy(buf, "SECURITY USER ", (16 + strlen(pwd->pw_name)));
+    strncpy(&buf[14], pwd->pw_name, (16 + strlen(pwd->pw_name) - 14));
+    buf[14 + strlen(pwd->pw_name)] = '\n';
+    buf[15 + strlen(pwd->pw_name)] = '\0';
+
+    return (buf);
+}
+
+
+/*
+ * Check the security of a received packet.  Returns negative on security
+ * violation, or returns 0 if ok.  Removes the security info from the pkt_t.
+ */
+int
+bsd_recv_security_ok(
+    struct sec_handle *        rh,
+    pkt_t *            pkt)
+{
+    char *tok, *security, *body, *result;
+    char *service = NULL, *serviceX, *serviceY;
+    char *security_line;
+    size_t len;
+
+    /*
+     * Now, find the SECURITY line in the body, and parse it out
+     * into an argv.
+     */
+    if (strncmp(pkt->body, "SECURITY ", SIZEOF("SECURITY ") - 1) == 0) {
+       security = pkt->body;
+       len = 0;
+       while(*security != '\n' && len < pkt->size) {
+           security++;
+           len++;
+       }
+       if(*security == '\n') {
+           body = security+1;
+           *security = '\0';
+           security_line = stralloc(pkt->body);
+           security = pkt->body + strlen("SECURITY ");
+       } else {
+           body = pkt->body;
+           security_line = NULL;
+           security = NULL;
+       }
+    } else {
+       body = pkt->body;
+       security_line = NULL;
+       security = NULL;
+    }
+
+    /*
+     * Now, find the SERVICE line in the body, and parse it out
+     * into an argv.
+     */
+    if (strncmp(body, "SERVICE", SIZEOF("SERVICE") - 1) == 0) {
+       serviceX = stralloc(body + strlen("SERVICE "));
+       serviceY = strtok(serviceX, "\n");
+       if (serviceY)
+           service  = stralloc(serviceY);
+       amfree(serviceX);
+    }
+
+    /*
+     * We need to do different things depending on which type of packet
+     * this is.
+     */
+    switch (pkt->type) {
+    case P_REQ:
+       /*
+        * Request packets must come from a reserved port
+        */
+       if (ntohs(rh->peer.sin_port) >= IPPORT_RESERVED) {
+           security_seterror(&rh->sech,
+               "host %s: port %d not secure", rh->hostname,
+               ntohs(rh->peer.sin_port));
+           amfree(service);
+           amfree(security_line);
+           return (-1);
+       }
+
+       if (!service) {
+           security_seterror(&rh->sech,
+                             "packet as no SERVICE line");
+           amfree(security_line);
+           return (-1);
+       }
+
+       /*
+        * Request packets contain a remote username.  We need to check
+        * that we allow it in.
+        *
+        * They will look like:
+        *      SECURITY USER [username]
+        */
+
+       /* there must be some security info */
+       if (security == NULL) {
+           security_seterror(&rh->sech,
+               "no bsd SECURITY for P_REQ");
+           amfree(service);
+           return (-1);
+       }
+
+       /* second word must be USER */
+       if ((tok = strtok(security, " ")) == NULL) {
+           security_seterror(&rh->sech,
+               "SECURITY line: %s", security_line);
+           amfree(service);
+           amfree(security_line);
+           return (-1);        /* default errmsg */
+       }
+       if (strcmp(tok, "USER") != 0) {
+           security_seterror(&rh->sech,
+               "REQ SECURITY line parse error, expecting USER, got %s", tok);
+           amfree(service);
+           amfree(security_line);
+           return (-1);
+       }
+
+       /* the third word is the username */
+       if ((tok = strtok(NULL, "")) == NULL) {
+           security_seterror(&rh->sech,
+               "SECURITY line: %s", security_line);
+           amfree(security_line);
+           return (-1);        /* default errmsg */
+       }
+       if ((result = check_user(rh, tok, service)) != NULL) {
+           security_seterror(&rh->sech, "%s", result);
+           amfree(service);
+           amfree(result);
+           amfree(security_line);
+           return (-1);
+       }
+
+       /* we're good to go */
+       break;
+    default:
+       break;
+    }
+    amfree(service);
+    amfree(security_line);
+
+    /*
+     * If there is security info at the front of the packet, we need to
+     * shift the rest of the data up and nuke it.
+     */
+    if (body != pkt->body)
+       memmove(pkt->body, body, strlen(body) + 1);
+    return (0);
+}
+
+/*
+ * Transmit a packet.  Add security information first.
+ */
+ssize_t
+udpbsd_sendpkt(
+    void *     cookie,
+    pkt_t *    pkt)
+{
+    struct sec_handle *rh = cookie;
+    struct passwd *pwd;
+
+    assert(rh != NULL);
+    assert(pkt != NULL);
+
+    secprintf(("%s: udpbsd_sendpkt: enter\n", get_pname()));
+    /*
+     * Initialize this datagram, and add the header
+     */
+    dgram_zero(&rh->udp->dgram);
+    dgram_cat(&rh->udp->dgram, pkthdr2str(rh, pkt));
+
+    /*
+     * Add the security info.  This depends on which kind of packet we're
+     * sending.
+     */
+    switch (pkt->type) {
+    case P_REQ:
+       /*
+        * Requests get sent with our username in the body
+        */
+       if ((pwd = getpwuid(geteuid())) == NULL) {
+           security_seterror(&rh->sech,
+               "can't get login name for my uid %ld", (long)getuid());
+           return (-1);
+       }
+       dgram_cat(&rh->udp->dgram, "SECURITY USER %s\n", pwd->pw_name);
+       break;
+
+    default:
+       break;
+    }
+
+    /*
+     * Add the body, and send it
+     */
+    dgram_cat(&rh->udp->dgram, pkt->body);
+
+    secprintf((
+           "%s: sec: udpbsd_sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
+           debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->type,
+           strlen(pkt->body), pkt->body));
+
+    if (dgram_send_addr(rh->peer, &rh->udp->dgram) != 0) {
+       security_seterror(&rh->sech,
+           "send %s to %s failed: %s", pkt_type2str(pkt->type),
+           rh->hostname, strerror(errno));
+       return (-1);
+    }
+    return (0);
+}
+
+void
+udp_close(
+    void *     cookie)
+{
+    struct sec_handle *rh = cookie;
+
+    if (rh->proto_handle == NULL) {
+       return;
+    }
+
+    secprintf(("%s: udp: close handle '%s'\n",
+              debug_prefix_time(NULL), rh->proto_handle));
+
+    udp_recvpkt_cancel(rh);
+    if (rh->next) {
+       rh->next->prev = rh->prev;
+    }
+    else {
+       rh->udp->bh_last = rh->prev;
+    }
+    if (rh->prev) {
+       rh->prev->next = rh->next;
+    }
+    else {
+       rh->udp->bh_first = rh->next;
+    }
+
+    amfree(rh->proto_handle);
+    amfree(rh->hostname);
+    amfree(rh);
+}
+
+/*
+ * Set up to receive a packet asynchronously, and call back when it has
+ * been read.
+ */
+void
+udp_recvpkt(
+    void *     cookie,
+    void       (*fn)(void *, pkt_t *, security_status_t),
+    void *     arg,
+    int                timeout)
+{
+    struct sec_handle *rh = cookie;
+
+    secprintf(("%s: udp_recvpkt(cookie=%p, fn=%p, arg=%p, timeout=%u)\n",
+       debug_prefix(NULL), cookie, fn, arg, timeout));
+    assert(rh != NULL);
+    assert(fn != NULL);
+
+
+    /*
+     * Subsequent recvpkt calls override previous ones
+     */
+    if (rh->ev_read == NULL) {
+       udp_addref(rh->udp, &udp_netfd_read_callback);
+       rh->ev_read = event_register(rh->event_id, EV_WAIT,
+           udp_recvpkt_callback, rh);
+    }
+    if (rh->ev_timeout != NULL)
+       event_release(rh->ev_timeout);
+    if (timeout < 0)
+       rh->ev_timeout = NULL;
+    else
+       rh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
+                                       udp_recvpkt_timeout, rh);
+    rh->fn.recvpkt = fn;
+    rh->arg = arg;
+}
+
+/*
+ * Remove a async receive request on this handle from the queue.
+ * If it is the last one to be removed, then remove the event
+ * handler for our network fd
+ */
+void
+udp_recvpkt_cancel(
+    void *     cookie)
+{
+    struct sec_handle *rh = cookie;
+
+    assert(rh != NULL);
+
+    if (rh->ev_read != NULL) {
+       udp_delref(rh->udp);
+       event_release(rh->ev_read);
+       rh->ev_read = NULL;
+    }
+
+    if (rh->ev_timeout != NULL) {
+       event_release(rh->ev_timeout);
+       rh->ev_timeout = NULL;
+    }
+}
+
+/*
+ * This is called when a handle is woken up because data read off of the
+ * net is for it.
+ */
+void
+udp_recvpkt_callback(
+    void *     cookie)
+{
+    struct sec_handle *rh = cookie;
+    void (*fn)(void *, pkt_t *, security_status_t);
+    void *arg;
+
+    secprintf(("%s: udp: receive handle '%s' netfd '%s'\n",
+              debug_prefix_time(NULL), rh->proto_handle, rh->udp->handle));
+    assert(rh != NULL);
+
+    if (strcmp(rh->proto_handle, rh->udp->handle) != 0) assert(1);
+    /* if it didn't come from the same host/port, forget it */
+    if (memcmp(&rh->peer.sin_addr, &rh->udp->peer.sin_addr,
+       SIZEOF(rh->udp->peer.sin_addr)) != 0 ||
+       rh->peer.sin_port != rh->udp->peer.sin_port) {
+       amfree(rh->udp->handle);
+       //rh->udp->handle = NULL;
+       return;
+    }
+
+    /*
+     * We need to cancel the recvpkt request before calling the callback
+     * because the callback may reschedule us.
+     */
+    fn = rh->fn.recvpkt;
+    arg = rh->arg;
+    udp_recvpkt_cancel(rh);
+
+    /*
+     * Check the security of the packet.  If it is bad, then pass NULL
+     * to the packet handling function instead of a packet.
+     */
+    if (rh->udp->recv_security_ok &&
+       rh->udp->recv_security_ok(rh, &rh->udp->pkt) < 0)
+       (*fn)(arg, NULL, S_ERROR);
+    else
+       (*fn)(arg, &rh->udp->pkt, S_OK);
+}
+
+/*
+ * This is called when a handle times out before receiving a packet.
+ */
+void
+udp_recvpkt_timeout(
+    void *     cookie)
+{
+    struct sec_handle *rh = cookie;
+    void (*fn)(void *, pkt_t *, security_status_t);
+    void *arg;
+
+    assert(rh != NULL);
+
+    assert(rh->ev_timeout != NULL);
+    fn = rh->fn.recvpkt;
+    arg = rh->arg;
+    udp_recvpkt_cancel(rh);
+    (*fn)(arg, NULL, S_TIMEOUT);
+}
+
+/*
+ * Given a hostname and a port, setup a udp_handle
+ */
+int
+udp_inithandle(
+    udp_handle_t *     udp,
+    struct sec_handle *        rh,
+    struct hostent *   he,
+    in_port_t          port,
+    char *             handle,
+    int                        sequence)
+{
+    int i;
+
+    /*
+     * Save the hostname and port info
+     */
+    secprintf(("%s: udp_inithandle port %hd handle %s sequence %d\n",
+              debug_prefix_time(NULL), ntohs(port),
+              handle, sequence));
+    assert(he != NULL);
+
+    rh->hostname = stralloc(he->h_name);
+    memcpy(&rh->peer.sin_addr, he->h_addr, SIZEOF(rh->peer.sin_addr));
+    rh->peer.sin_port = port;
+    rh->peer.sin_family = (sa_family_t)AF_INET;
+
+    /*
+     * Do a forward lookup of the hostname.  This is unnecessary if we
+     * are initiating the connection, but is very serious if we are
+     * receiving.  We want to make sure the hostname
+     * resolves back to the remote ip for security reasons.
+     */
+    if ((he = gethostbyname(rh->hostname)) == NULL) {
+    secprintf(("%s: udp: bb\n", debug_prefix_time(NULL)));
+       security_seterror(&rh->sech,
+           "%s: could not resolve hostname", rh->hostname);
+       return (-1);
+    }
+
+    /*
+     * Make sure the hostname matches.  This should always work.
+     */
+    if (strncasecmp(rh->hostname, he->h_name, strlen(rh->hostname)) != 0) {
+    secprintf(("%s: udp: cc\n", debug_prefix_time(NULL)));
+       security_seterror(&rh->sech,
+                         "%s: did not resolve to itself, it resolv to",
+                         rh->hostname, he->h_name);
+       return (-1);
+    }
+
+    /*
+     * Now look for a matching ip address.
+     */
+    for (i = 0; he->h_addr_list[i] != NULL; i++) {
+       if (memcmp(&rh->peer.sin_addr, he->h_addr_list[i],
+           SIZEOF(struct in_addr)) == 0) {
+           break;
+       }
+    }
+
+    /*
+     * If we didn't find it, try the aliases.  This is a workaround for
+     * Solaris if DNS goes over NIS.
+     */
+    if (he->h_addr_list[i] == NULL) {
+       const char *ipstr = inet_ntoa(rh->peer.sin_addr);
+       for (i = 0; he->h_aliases[i] != NULL; i++) {
+           if (strcmp(he->h_aliases[i], ipstr) == 0)
+               break;
+       }
+       /*
+        * No aliases either.  Failure.  Someone is fooling with us or
+        * DNS is messed up.
+        */
+       if (he->h_aliases[i] == NULL) {
+           security_seterror(&rh->sech,
+               "DNS check failed: no matching ip address for %s",
+               rh->hostname);
+           return (-1);
+       }
+    }
+
+    rh->prev = udp->bh_last;
+    if (udp->bh_last) {
+       rh->prev->next = rh;
+    }
+    if (!udp->bh_first) {
+       udp->bh_first = rh;
+    }
+    rh->next = NULL;
+    udp->bh_last = rh;
+
+    rh->sequence = sequence;
+    rh->event_id = (event_id_t)newevent++;
+    amfree(rh->proto_handle);
+    rh->proto_handle = stralloc(handle);
+    rh->fn.connect = NULL;
+    rh->arg = NULL;
+    rh->ev_read = NULL;
+    rh->ev_timeout = NULL;
+
+    secprintf(("%s: udp: adding handle '%s'\n",
+              debug_prefix_time(NULL), rh->proto_handle));
+
+    return(0);
+}
+
+
+/*
+ * Callback for received packets.  This is the function bsd_recvpkt
+ * registers with the event handler.  It is called when the event handler
+ * realizes that data is waiting to be read on the network socket.
+ */
+void
+udp_netfd_read_callback(
+    void *     cookie)
+{
+    struct udp_handle *udp = cookie;
+    struct sec_handle *rh;
+    struct hostent *he;
+    int a;
+
+    secprintf(("%s: udp_netfd_read_callback(cookie=%p)\n",
+               debug_prefix(NULL), cookie));
+    assert(udp != NULL);
+    
+#ifndef TEST                                                   /* { */
+    /*
+     * Receive the packet.
+     */
+    dgram_zero(&udp->dgram);
+    if (dgram_recv(&udp->dgram, 0, &udp->peer) < 0)
+       return;
+#endif /* !TEST */                                             /* } */
+
+    /*
+     * Parse the packet.
+     */
+    if (str2pkthdr(udp) < 0)
+       return;
+
+    /*
+     * If there are events waiting on this handle, we're done
+     */
+    rh = udp->bh_first;
+    while(rh != NULL && (strcmp(rh->proto_handle, udp->handle) != 0 ||
+                        rh->sequence != udp->sequence ||
+                        rh->peer.sin_addr.s_addr != udp->peer.sin_addr.s_addr ||
+                        rh->peer.sin_port != udp->peer.sin_port)) {
+       rh = rh->next;
+    }
+    if (rh && event_wakeup(rh->event_id) > 0)
+       return;
+
+    /*
+     * If we didn't find a handle, then check for a new incoming packet.
+     * If no accept handler was setup, then just return.
+     */
+    if (udp->accept_fn == NULL)
+       return;
+
+    he = gethostbyaddr((void *)&udp->peer.sin_addr,
+       (socklen_t)sizeof(udp->peer.sin_addr), AF_INET);
+    if (he == NULL)
+       return;
+    rh = alloc(SIZEOF(*rh));
+    rh->proto_handle=NULL;
+    rh->udp = udp;
+    rh->rc = NULL;
+    security_handleinit(&rh->sech, udp->driver);
+    a = udp_inithandle(udp, rh,
+                  he,
+                  udp->peer.sin_port,
+                  udp->handle,
+                  udp->sequence);
+    if (a < 0) {
+       secprintf(("%s: bsd: closeX handle '%s'\n",
+                 debug_prefix_time(NULL), rh->proto_handle));
+
+       amfree(rh);
+       return;
+    }
+    /*
+     * Check the security of the packet.  If it is bad, then pass NULL
+     * to the accept function instead of a packet.
+     */
+    if (rh->udp->recv_security_ok(rh, &udp->pkt) < 0)
+       (*udp->accept_fn)(&rh->sech, NULL);
+    else
+       (*udp->accept_fn)(&rh->sech, &udp->pkt);
+}
+
+/*
+ * Locate an existing connection to the given host, or create a new,
+ * unconnected entry if none exists.  The caller is expected to check
+ * for the lack of a connection (rc->read == -1) and set one up.
+ */
+struct tcp_conn *
+sec_tcp_conn_get(
+    const char *hostname,
+    int                want_new)
+{
+    struct tcp_conn *rc;
+
+    secprintf(("%s: sec_tcp_conn_get: %s\n", debug_prefix_time(NULL), hostname));
+
+    if (want_new == 0) {
+    for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
+       if (strcasecmp(hostname, rc->hostname) == 0)
+           break;
+    }
+
+    if (rc != NULL) {
+       rc->refcnt++;
+       secprintf(("%s: sec_tcp_conn_get: exists, refcnt to %s is now %d\n",
+                  debug_prefix_time(NULL),
+                  rc->hostname, rc->refcnt));
+       return (rc);
+    }
+    }
+
+    secprintf(("%s: sec_tcp_conn_get: creating new handle\n",
+              debug_prefix_time(NULL)));
+    /*
+     * We can't be creating a new handle if we are the client
+     */
+    rc = alloc(SIZEOF(*rc));
+    rc->read = rc->write = -1;
+    rc->driver = NULL;
+    rc->pid = -1;
+    rc->ev_read = NULL;
+    rc->toclose = 0;
+    rc->donotclose = 0;
+    strncpy(rc->hostname, hostname, SIZEOF(rc->hostname) - 1);
+    rc->hostname[SIZEOF(rc->hostname) - 1] = '\0';
+    rc->errmsg = NULL;
+    rc->refcnt = 1;
+    rc->handle = -1;
+    rc->pkt = NULL;
+    rc->accept_fn = NULL;
+    rc->recv_security_ok = NULL;
+    rc->prefix_packet = NULL;
+    connq_append(rc);
+    return (rc);
+}
+
+/*
+ * Delete a reference to a connection, and close it if it is the last
+ * reference.
+ */
+void
+sec_tcp_conn_put(
+    struct tcp_conn *  rc)
+{
+    amwait_t status;
+
+    assert(rc->refcnt > 0);
+    --rc->refcnt;
+    secprintf(("%s: sec_tcp_conn_put: decrementing refcnt for %s to %d\n",
+              debug_prefix_time(NULL),
+       rc->hostname, rc->refcnt));
+    if (rc->refcnt > 0) {
+       return;
+    }
+    secprintf(("%s: sec_tcp_conn_put: closing connection to %s\n",
+              debug_prefix_time(NULL), rc->hostname));
+    if (rc->read != -1)
+       aclose(rc->read);
+    if (rc->write != -1)
+       aclose(rc->write);
+    if (rc->pid != -1) {
+       waitpid(rc->pid, &status, WNOHANG);
+    }
+    if (rc->ev_read != NULL)
+       event_release(rc->ev_read);
+    if (rc->errmsg != NULL)
+       amfree(rc->errmsg);
+    connq_remove(rc);
+    amfree(rc->pkt);
+    if(!rc->donotclose)
+       amfree(rc); /* someone might still use it           */
+                   /* eg. in sec_tcp_conn_read_callback if */
+                   /*     event_wakeup call us.            */
+}
+
+/*
+ * Turn on read events for a conn.  Or, increase a ev_read_refcnt if we are
+ * already receiving read events.
+ */
+void
+sec_tcp_conn_read(
+    struct tcp_conn *  rc)
+{
+    assert (rc != NULL);
+
+    if (rc->ev_read != NULL) {
+       rc->ev_read_refcnt++;
+       secprintf((
+              "%s: sec: conn_read: incremented ev_read_refcnt to %d for %s\n",
+              debug_prefix_time(NULL), rc->ev_read_refcnt, rc->hostname));
+       return;
+    }
+    secprintf(("%s: sec: conn_read registering event handler for %s\n",
+              debug_prefix_time(NULL), rc->hostname));
+    rc->ev_read = event_register((event_id_t)rc->read, EV_READFD,
+               sec_tcp_conn_read_callback, rc);
+    rc->ev_read_refcnt = 1;
+}
+
+static void
+sec_tcp_conn_read_cancel(
+    struct tcp_conn *  rc)
+{
+
+    --rc->ev_read_refcnt;
+    secprintf((
+       "%s: sec: conn_read_cancel: decremented ev_read_refcnt to %d for %s\n",
+       debug_prefix_time(NULL),
+       rc->ev_read_refcnt, rc->hostname));
+    if (rc->ev_read_refcnt > 0) {
+       return;
+    }
+    secprintf(("%s: sec: conn_read_cancel: releasing event handler for %s\n",
+              debug_prefix_time(NULL), rc->hostname));
+    event_release(rc->ev_read);
+    rc->ev_read = NULL;
+}
+
+/*
+ * This is called when a handle is woken up because data read off of the
+ * net is for it.
+ */
+static void
+recvpkt_callback(
+    void *     cookie,
+    void *     buf,
+    ssize_t    bufsize)
+{
+    pkt_t pkt;
+    struct sec_handle *rh = cookie;
+
+    assert(rh != NULL);
+
+    secprintf(("%s: sec: recvpkt_callback: %d\n",
+              debug_prefix_time(NULL), bufsize));
+    /*
+     * We need to cancel the recvpkt request before calling
+     * the callback because the callback may reschedule us.
+     */
+    stream_recvpkt_cancel(rh);
+
+    switch (bufsize) {
+    case 0:
+       security_seterror(&rh->sech,
+           "EOF on read from %s", rh->hostname);
+       (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
+       return;
+    case -1:
+       security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
+       (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
+       return;
+    default:
+       break;
+    }
+
+    parse_pkt(&pkt, buf, (size_t)bufsize);
+    secprintf((
+          "%s: sec: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n",
+          debug_prefix_time(NULL), pkt_type2str(pkt.type), pkt.type,
+          rh->hostname, pkt.body));
+    if (rh->rc->recv_security_ok && (rh->rc->recv_security_ok)(rh, &pkt) < 0)
+       (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
+    else
+       (*rh->fn.recvpkt)(rh->arg, &pkt, S_OK);
+    amfree(pkt.body);
+}
+
+/*
+ * Callback for tcpm_stream_read_sync
+ */
+static void
+stream_read_sync_callback(
+    void *     s)
+{
+    struct sec_stream *rs = s;
+    assert(rs != NULL);
+
+    secprintf(("%s: sec: stream_read_callback_sync: handle %d\n",
+              debug_prefix_time(NULL), rs->handle));
+
+    /*
+     * Make sure this was for us.  If it was, then blow away the handle
+     * so it doesn't get claimed twice.  Otherwise, leave it alone.
+     *
+     * If the handle is EOF, pass that up to our callback.
+     */
+    if (rs->rc->handle == rs->handle) {
+        secprintf(("%s: sec: stream_read_callback_sync: it was for us\n",
+                  debug_prefix_time(NULL)));
+        rs->rc->handle = H_TAKEN;
+    } else if (rs->rc->handle != H_EOF) {
+        secprintf(("%s: sec: stream_read_callback_sync: not for us\n",
+                  debug_prefix_time(NULL)));
+        return;
+    }
+
+    /*
+     * Remove the event first, and then call the callback.
+     * We remove it first because we don't want to get in their
+     * way if they reschedule it.
+     */
+    tcpm_stream_read_cancel(rs);
+
+    if (rs->rc->pktlen <= 0) {
+       secprintf(("%s: sec: stream_read_sync_callback: %s\n",
+                  debug_prefix_time(NULL), rs->rc->errmsg));
+       security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+       if(rs->closed_by_me == 0 && rs->closed_by_network == 0)
+           sec_tcp_conn_put(rs->rc);
+       rs->closed_by_network = 1;
+       return;
+    }
+    secprintf((
+            "%s: sec: stream_read_callback_sync: read %ld bytes from %s:%d\n",
+            debug_prefix_time(NULL),
+        rs->rc->pktlen, rs->rc->hostname, rs->handle));
+}
+
+/*
+ * Callback for tcpm_stream_read
+ */
+static void
+stream_read_callback(
+    void *     arg)
+{
+    struct sec_stream *rs = arg;
+    assert(rs != NULL);
+
+    secprintf(("%s: sec: stream_read_callback: handle %d\n",
+              debug_prefix_time(NULL), rs->handle));
+
+    /*
+     * Make sure this was for us.  If it was, then blow away the handle
+     * so it doesn't get claimed twice.  Otherwise, leave it alone.
+     *
+     * If the handle is EOF, pass that up to our callback.
+     */
+    if (rs->rc->handle == rs->handle) {
+       secprintf(("%s: sec: stream_read_callback: it was for us\n",
+                  debug_prefix_time(NULL)));
+       rs->rc->handle = H_TAKEN;
+    } else if (rs->rc->handle != H_EOF) {
+       secprintf(("%s: sec: stream_read_callback: not for us\n",
+                  debug_prefix_time(NULL)));
+       return;
+    }
+
+    /*
+     * Remove the event first, and then call the callback.
+     * We remove it first because we don't want to get in their
+     * way if they reschedule it.
+     */
+    tcpm_stream_read_cancel(rs);
+
+    if (rs->rc->pktlen <= 0) {
+       secprintf(("%s: sec: stream_read_callback: %s\n",
+                  debug_prefix_time(NULL), rs->rc->errmsg));
+       security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+       if(rs->closed_by_me == 0 && rs->closed_by_network == 0)
+           sec_tcp_conn_put(rs->rc);
+       rs->closed_by_network = 1;
+       (*rs->fn)(rs->arg, NULL, rs->rc->pktlen);
+       return;
+    }
+    secprintf(("%s: sec: stream_read_callback: read %ld bytes from %s:%d\n",
+              debug_prefix_time(NULL),
+       rs->rc->pktlen, rs->rc->hostname, rs->handle));
+    (*rs->fn)(rs->arg, rs->rc->pkt, rs->rc->pktlen);
+    secprintf(("%s: sec: after callback stream_read_callback\n",
+              debug_prefix_time(NULL)));
+}
+
+/*
+ * The callback for the netfd for the event handler
+ * Determines if this packet is for this security handle,
+ * and does the real callback if so.
+ */
+static void
+sec_tcp_conn_read_callback(
+    void *     cookie)
+{
+    struct tcp_conn *  rc = cookie;
+    struct sec_handle *        rh;
+    pkt_t              pkt;
+    ssize_t            rval;
+    int                        revent;
+
+    assert(cookie != NULL);
+
+    secprintf(("%s: sec: conn_read_callback\n", debug_prefix_time(NULL)));
+
+    /* Read the data off the wire.  If we get errors, shut down. */
+    rval = tcpm_recv_token(rc->read, &rc->handle, &rc->errmsg, &rc->pkt,
+                               &rc->pktlen, 60);
+    secprintf(("%s: sec: conn_read_callback: tcpm_recv_token returned %d\n",
+              debug_prefix_time(NULL), rval));
+    if (rval < 0 || rc->handle == H_EOF) {
+       rc->pktlen = rval;
+       rc->handle = H_EOF;
+       revent = event_wakeup((event_id_t)rc);
+       secprintf(("%s: sec: conn_read_callback: event_wakeup return %d\n",
+                  debug_prefix_time(NULL), revent));
+       /* delete our 'accept' reference */
+       if (rc->accept_fn != NULL) {
+           if(rc->refcnt != 1) {
+               dbprintf(("STRANGE, rc->refcnt should be 1"));
+               rc->refcnt=1;
+           }
+           rc->accept_fn = NULL;
+           sec_tcp_conn_put(rc);
+       }
+       return;
+    }
+
+    if(rval == 0) {
+       rc->pktlen = 0;
+       revent = event_wakeup((event_id_t)rc);
+       secprintf(("%s: 0 sec: conn_read_callback: event_wakeup return %d\n",
+                  debug_prefix_time(NULL), revent));
+       return;
+    }
+
+    /* If there are events waiting on this handle, we're done */
+    rc->donotclose = 1;
+    revent = event_wakeup((event_id_t)rc);
+    secprintf(("%s: sec: conn_read_callback: event_wakeup return %d\n",
+              debug_prefix_time(NULL), rval));
+    rc->donotclose = 0;
+    if (rc->handle == H_TAKEN || rc->pktlen == 0) {
+       if(rc->refcnt == 0) amfree(rc);
+       return;
+    }
+
+    assert(rc->refcnt > 0);
+
+    /* If there is no accept fn registered, then drop the packet */
+    if (rc->accept_fn == NULL)
+       return;
+
+    rh = alloc(SIZEOF(*rh));
+    security_handleinit(&rh->sech, rc->driver);
+    rh->hostname = stralloc(rc->hostname);
+    rh->ev_timeout = NULL;
+    rh->rc = rc;
+    rh->peer = rc->peer;
+    rh->rs = tcpma_stream_client(rh, rc->handle);
+
+    secprintf(("%s: sec: new connection\n", debug_prefix_time(NULL)));
+    pkt.body = NULL;
+    parse_pkt(&pkt, rc->pkt, (size_t)rc->pktlen);
+    secprintf(("%s: sec: calling accept_fn\n", debug_prefix_time(NULL)));
+    if (rh->rc->recv_security_ok && (rh->rc->recv_security_ok)(rh, &pkt) < 0)
+       (*rc->accept_fn)(&rh->sech, NULL);
+    else
+       (*rc->accept_fn)(&rh->sech, &pkt);
+    amfree(pkt.body);
+}
+
+void
+parse_pkt(
+    pkt_t *    pkt,
+    const void *buf,
+    size_t     bufsize)
+{
+    const unsigned char *bufp = buf;
+
+    secprintf(("%s: sec: parse_pkt: parsing buffer of %d bytes\n",
+              debug_prefix_time(NULL), bufsize));
+
+    pkt->type = (pktype_t)*bufp++;
+    bufsize--;
+
+    pkt->packet_size = bufsize+1;
+    pkt->body = alloc(pkt->packet_size);
+    if (bufsize == 0) {
+       pkt->body[0] = '\0';
+    } else {
+       memcpy(pkt->body, bufp, bufsize);
+       pkt->body[pkt->packet_size - 1] = '\0';
+    }
+    pkt->size = strlen(pkt->body);
+
+    secprintf(("%s: sec: parse_pkt: %s (%d): \"%s\"\n",
+              debug_prefix_time(NULL), pkt_type2str(pkt->type),
+              pkt->type, pkt->body));
+}
+
+/*
+ * Convert a packet header into a string
+ */
+const char *
+pkthdr2str(
+    const struct sec_handle *  rh,
+    const pkt_t *              pkt)
+{
+    static char retbuf[256];
+
+    assert(rh != NULL);
+    assert(pkt != NULL);
+
+    snprintf(retbuf, SIZEOF(retbuf), "Amanda %d.%d %s HANDLE %s SEQ %d\n",
+       VERSION_MAJOR, VERSION_MINOR, pkt_type2str(pkt->type),
+       rh->proto_handle, rh->sequence);
+
+    secprintf(("%s: bsd: pkthdr2str handle '%s'\n",
+              debug_prefix_time(NULL), rh->proto_handle));
+
+    /* check for truncation.  If only we had asprintf()... */
+    assert(retbuf[strlen(retbuf) - 1] == '\n');
+
+    return (retbuf);
+}
+
+/*
+ * Parses out the header line in 'str' into the pkt and handle
+ * Returns negative on parse error.
+ */
+int
+str2pkthdr(
+    udp_handle_t *     udp)
+{
+    char *str;
+    const char *tok;
+    pkt_t *pkt;
+
+    pkt = &udp->pkt;
+
+    assert(udp->dgram.cur != NULL);
+    str = stralloc(udp->dgram.cur);
+
+    /* "Amanda %d.%d <ACK,NAK,...> HANDLE %s SEQ %d\n" */
+
+    /* Read in "Amanda" */
+    if ((tok = strtok(str, " ")) == NULL || strcmp(tok, "Amanda") != 0)
+       goto parse_error;
+
+    /* nothing is done with the major/minor numbers currently */
+    if ((tok = strtok(NULL, " ")) == NULL || strchr(tok, '.') == NULL)
+       goto parse_error;
+
+    /* Read in the packet type */
+    if ((tok = strtok(NULL, " ")) == NULL)
+       goto parse_error;
+    amfree(pkt->body);
+    pkt_init(pkt, pkt_str2type(tok), "");
+    if (pkt->type == (pktype_t)-1)    
+       goto parse_error;
+
+    /* Read in "HANDLE" */
+    if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "HANDLE") != 0)
+       goto parse_error;
+
+    /* parse the handle */
+    if ((tok = strtok(NULL, " ")) == NULL)
+       goto parse_error;
+    amfree(udp->handle);
+    udp->handle = stralloc(tok);
+
+    /* Read in "SEQ" */
+    if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "SEQ") != 0)   
+       goto parse_error;
+
+    /* parse the sequence number */   
+    if ((tok = strtok(NULL, "\n")) == NULL)
+       goto parse_error;
+    udp->sequence = atoi(tok);
+
+    /* Save the body, if any */       
+    if ((tok = strtok(NULL, "")) != NULL)
+       pkt_cat(pkt, "%s", tok);
+
+    amfree(str);
+    return (0);
+
+parse_error:
+#if 0 /* XXX we have no way of passing this back up */
+    security_seterror(&rh->sech,
+       "parse error in packet header : '%s'", origstr);
+#endif
+    amfree(str);
+    return (-1);
+}
+
+char *
+check_user(
+    struct sec_handle *        rh,
+    const char *       remoteuser,
+    const char *       service)
+{
+    struct passwd *pwd;
+    char *r;
+    char *result = NULL;
+    char *localuser = NULL;
+
+    /* lookup our local user name */
+    if ((pwd = getpwnam(CLIENT_LOGIN)) == NULL) {
+       return vstralloc("getpwnam(", CLIENT_LOGIN, ") fails", NULL);
+    }
+
+    /*
+     * Make a copy of the user name in case getpw* is called by
+     * any of the lower level routines.
+     */
+    localuser = stralloc(pwd->pw_name);
+
+#ifndef USE_AMANDAHOSTS
+    r = check_user_ruserok(rh->hostname, pwd, remoteuser);
+#else
+    r = check_user_amandahosts(rh->hostname, rh->peer.sin_addr, pwd, remoteuser, service);
+#endif
+    if (r != NULL) {
+       result = vstralloc("user ", remoteuser, " from ", rh->hostname,
+                          " is not allowed to execute the service ",
+                          service, ": ", r, NULL);
+       amfree(r);
+    }
+    amfree(localuser);
+    return result;
+}
+
+/*
+ * See if a remote user is allowed in.  This version uses ruserok()
+ * and friends.
+ *
+ * Returns 0 on success, or negative on error.
+ */
+char *
+check_user_ruserok(
+    const char *       host,
+    struct passwd *    pwd,
+    const char *       remoteuser)
+{
+    int saved_stderr;
+    int fd[2];
+    FILE *fError;
+    amwait_t exitcode;
+    pid_t ruserok_pid;
+    pid_t pid;
+    char *es;
+    char *result;
+    int ok;
+    char number[NUM_STR_SIZE];
+    uid_t myuid = getuid();
+
+    /*
+     * note that some versions of ruserok (eg SunOS 3.2) look in
+     * "./.rhosts" rather than "~CLIENT_LOGIN/.rhosts", so we have to
+     * chdir ourselves.  Sigh.
+     *
+     * And, believe it or not, some ruserok()'s try an initgroup just
+     * for the hell of it.  Since we probably aren't root at this point
+     * it'll fail, and initgroup "helpfully" will blatt "Setgroups: Not owner"
+     * into our stderr output even though the initgroup failure is not a
+     * problem and is expected.  Thanks a lot.  Not.
+     */
+    if (pipe(fd) != 0) {
+       return stralloc2("pipe() fails: ", strerror(errno));
+    }
+    if ((ruserok_pid = fork()) < 0) {
+       return stralloc2("fork() fails: ", strerror(errno));
+    } else if (ruserok_pid == 0) {
+       int ec;
+
+       close(fd[0]);
+       fError = fdopen(fd[1], "w");
+       if (!fError) {
+           error("Can't fdopen: %s", strerror(errno));
+           /*NOTREACHED*/
+       }
+       /* pamper braindead ruserok's */
+       if (chdir(pwd->pw_dir) != 0) {
+           fprintf(fError, "chdir(%s) failed: %s",
+                   pwd->pw_dir, strerror(errno));
+           fclose(fError);
+           exit(1);
+       }
+
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+       {
+       char *dir = stralloc(pwd->pw_dir);
+
+       secprintf(("%s: bsd: calling ruserok(%s, %d, %s, %s)\n",
+                  debug_prefix_time(NULL),
+                  host, ((myuid == 0) ? 1 : 0), remoteuser, pwd->pw_name));
+       if (myuid == 0) {
+           secprintf(("%s: bsd: because you are running as root, ",
+                      debug_prefix(NULL)));
+           secprintf(("/etc/hosts.equiv will not be used\n"));
+       } else {
+           show_stat_info("/etc/hosts.equiv", NULL);
+       }
+       show_stat_info(dir, "/.rhosts");
+       amfree(dir);
+       }
+#endif                                                         /* } */
+
+       saved_stderr = dup(2);
+       close(2);
+       if (open("/dev/null", O_RDWR) == -1) {
+            secprintf(("%s: Could not open /dev/null: %s\n",
+                     debug_prefix(NULL), strerror(errno)));
+           ec = 1;
+       } else {
+           ok = ruserok(host, myuid == 0, remoteuser, CLIENT_LOGIN);
+           if (ok < 0) {
+               ec = 1;
+           } else {
+               ec = 0;
+           }
+       }
+       (void)dup2(saved_stderr,2);
+       close(saved_stderr);
+       exit(ec);
+    }
+    close(fd[1]);
+    fError = fdopen(fd[0], "r");
+    if (!fError) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+
+    result = NULL;
+    while ((es = agets(fError)) != NULL) {
+       if (*es == 0) {
+           amfree(es);
+           continue;
+       }
+       if (result == NULL) {
+           result = stralloc("");
+       } else {
+           strappend(result, ": ");
+       }
+       strappend(result, es);
+       amfree(es);
+    }
+    close(fd[0]);
+
+    pid = wait(&exitcode);
+    while (pid != ruserok_pid) {
+       if ((pid == (pid_t) -1) && (errno != EINTR)) {
+           amfree(result);
+           return stralloc2("ruserok wait failed: %s", strerror(errno));
+       }
+       pid = wait(&exitcode);
+    }
+    if (WIFSIGNALED(exitcode)) {
+       amfree(result);
+       snprintf(number, SIZEOF(number), "%d", WTERMSIG(exitcode));
+       return stralloc2("ruserok child got signal ", number);
+    }
+    if (WEXITSTATUS(exitcode) == 0) {
+       amfree(result);
+    } else if (result == NULL) {
+       result = stralloc("ruserok failed");
+    }
+
+    return result;
+}
+
+/*
+ * Check to see if a user is allowed in.  This version uses .amandahosts
+ * Returns -1 on failure, or 0 on success.
+ */
+char *
+check_user_amandahosts(
+    const char *       host,
+    struct in_addr      addr,
+    struct passwd *    pwd,
+    const char *       remoteuser,
+    const char *       service)
+{
+    char *line = NULL;
+    char *filehost;
+    const char *fileuser;
+    char *ptmp = NULL;
+    char *result = NULL;
+    FILE *fp = NULL;
+    int found;
+    struct stat sbuf;
+    char n1[NUM_STR_SIZE];
+    char n2[NUM_STR_SIZE];
+    int hostmatch;
+    int usermatch;
+    char *aservice = NULL;
+
+    secprintf(("check_user_amandahosts(host=%s, pwd=%p, "
+               "remoteuser=%s, service=%s)\n",
+               host, pwd, remoteuser, service));
+
+    ptmp = stralloc2(pwd->pw_dir, "/.amandahosts");
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+    show_stat_info(ptmp, "");;
+#endif                                                         /* } */
+    if ((fp = fopen(ptmp, "r")) == NULL) {
+       result = vstralloc("cannot open ", ptmp, ": ", strerror(errno), NULL);
+       amfree(ptmp);
+       return result;
+    }
+
+    /*
+     * Make sure the file is owned by the Amanda user and does not
+     * have any group/other access allowed.
+     */
+    if (fstat(fileno(fp), &sbuf) != 0) {
+       result = vstralloc("cannot fstat ", ptmp, ": ", strerror(errno), NULL);
+       goto common_exit;
+    }
+    if (sbuf.st_uid != pwd->pw_uid) {
+       snprintf(n1, SIZEOF(n1), "%ld", (long)sbuf.st_uid);
+       snprintf(n2, SIZEOF(n2), "%ld", (long)pwd->pw_uid);
+       result = vstralloc(ptmp, ": ",
+                          "owned by id ", n1,
+                          ", should be ", n2,
+                          NULL);
+       goto common_exit;
+    }
+    if ((sbuf.st_mode & 077) != 0) {
+       result = stralloc2(ptmp,
+         ": incorrect permissions; file must be accessible only by its owner");
+       goto common_exit;
+    }
+
+    /*
+     * Now, scan the file for the host/user/service.
+     */
+    found = 0;
+    while ((line = agets(fp)) != NULL) {
+       if (*line == 0) {
+           amfree(line);
+           continue;
+       }
+
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+       secprintf(("%s: bsd: processing line: <%s>\n", debug_prefix(NULL), line));
+#endif                                                         /* } */
+       /* get the host out of the file */
+       if ((filehost = strtok(line, " \t")) == NULL) {
+           amfree(line);
+           continue;
+       }
+
+       /* get the username.  If no user specified, then use the local user */
+       if ((fileuser = strtok(NULL, " \t")) == NULL) {
+           fileuser = pwd->pw_name;
+       }
+
+       hostmatch = (strcasecmp(filehost, host) == 0);
+       /*  ok if addr=127.0.0.1 and
+        *  either localhost or localhost.domain is in .amandahost */
+       if ( !hostmatch ) {
+         if (strcmp(inet_ntoa(addr), "127.0.0.1")== 0  &&
+             (strcasecmp(filehost, "localhost")== 0 ||
+             strcasecmp(filehost, "localhost.localdomain")== 0))
+           {
+             hostmatch = 1;
+           }
+       }
+       usermatch = (strcasecmp(fileuser, remoteuser) == 0);
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+       secprintf(("%s: bsd: comparing \"%s\" with\n", debug_prefix(NULL), filehost));
+       secprintf(("%s: bsd:           \"%s\" (%s)\n", host,
+                 debug_prefix(NULL), hostmatch ? "match" : "no match"));
+       secprintf(("%s: bsd:       and \"%s\" with\n", fileuser, debug_prefix(NULL)));
+       secprintf(("%s: bsd:           \"%s\" (%s)\n", remoteuser,
+                 debug_prefix(NULL), usermatch ? "match" : "no match"));
+#endif                                                         /* } */
+       /* compare */
+       if (!hostmatch || !usermatch) {
+           amfree(line);
+           continue;
+       }
+
+        if (!service) {
+           /* success */
+           amfree(line);
+           found = 1;
+           break;
+       }
+
+       /* get the services.  If no service specified, then use
+        * noop/selfcheck/sendsize/sendbackup
+         */
+       aservice = strtok(NULL, " \t,");
+       if (!aservice) {
+           if (strcmp(service,"noop") == 0 ||
+              strcmp(service,"selfcheck") == 0 ||
+              strcmp(service,"sendsize") == 0 ||
+              strcmp(service,"sendbackup") == 0) {
+               /* success */
+               found = 1;
+               amfree(line);
+               break;
+           }
+           else {
+               amfree(line);
+               break;
+           }
+       }
+
+       do {
+           if (strcmp(aservice,service) == 0) {
+               found = 1;
+               break;
+           }
+           if (strcmp(aservice, "amdump") == 0 && 
+              (strcmp(service, "noop") == 0 ||
+               strcmp(service, "selfcheck") == 0 ||
+               strcmp(service, "sendsize") == 0 ||
+               strcmp(service, "sendbackup") == 0)) {
+               found = 1;
+               break;
+           }
+       } while((aservice = strtok(NULL, " \t,")) != NULL);
+
+       if (aservice && strcmp(aservice, service) == 0) {
+           /* success */
+           found = 1;
+           amfree(line);
+           break;
+       }
+       amfree(line);
+    }
+    if (! found) {
+       if (strcmp(service, "amindexd") == 0 ||
+           strcmp(service, "amidxtaped") == 0) {
+           result = vstralloc("Please add \"amindexd amidxtaped\" to "
+                              "the line in ", ptmp, NULL);
+       } else if (strcmp(service, "amdump") == 0 ||
+                  strcmp(service, "noop") == 0 ||
+                  strcmp(service, "selfcheck") == 0 ||
+                  strcmp(service, "sendsize") == 0 ||
+                  strcmp(service, "sendbackup") == 0) {
+           result = vstralloc("Please add \"amdump\" to the line in ",
+                              ptmp, NULL);
+       } else {
+           result = vstralloc(ptmp, ": ",
+                              "invalid service ", service, NULL);
+       }
+    }
+
+common_exit:
+
+    afclose(fp);
+    amfree(ptmp);
+
+    return result;
+}
+
+/* return 1 on success, 0 on failure */
+int
+check_security(
+    struct sockaddr_in *addr,
+    char *             str,
+    unsigned long      cksum,
+    char **            errstr)
+{
+    char *             remotehost = NULL, *remoteuser = NULL;
+    char *             bad_bsd = NULL;
+    struct hostent *   hp;
+    struct passwd *    pwptr;
+    uid_t              myuid;
+    int                        i;
+    int                        j;
+    char *             s;
+    char *             fp;
+    int                        ch;
+
+    (void)cksum;       /* Quiet unused parameter warning */
+
+    secprintf(("%s: check_security(addr=%p, str='%s', cksum=%ul, errstr=%p\n",
+               debug_prefix(NULL), addr, str, cksum, errstr));
+    dump_sockaddr(addr);
+
+    *errstr = NULL;
+
+    /* what host is making the request? */
+
+    hp = gethostbyaddr((char *)&addr->sin_addr, SIZEOF(addr->sin_addr),
+                      AF_INET);
+    if (hp == NULL) {
+       /* XXX include remote address in message */
+       *errstr = vstralloc("[",
+                           "addr ", inet_ntoa(addr->sin_addr), ": ",
+                           "hostname lookup failed",
+                           "]", NULL);
+       return 0;
+    }
+    remotehost = stralloc(hp->h_name);
+
+    /* Now let's get the hostent for that hostname */
+    hp = gethostbyname( remotehost );
+    if (hp == NULL) {
+       /* XXX include remote hostname in message */
+       *errstr = vstralloc("[",
+                           "host ", remotehost, ": ",
+                           "hostname lookup failed",
+                           "]", NULL);
+       amfree(remotehost);
+       return 0;
+    }
+
+    /* Verify that the hostnames match -- they should theoretically */
+    if (strncasecmp( remotehost, hp->h_name, strlen(remotehost)+1 ) != 0 ) {
+       *errstr = vstralloc("[",
+                           "hostnames do not match: ",
+                           remotehost, " ", hp->h_name,
+                           "]", NULL);
+       amfree(remotehost);
+       return 0;
+    }
+
+    /* Now let's verify that the ip which gave us this hostname
+     * is really an ip for this hostname; or is someone trying to
+     * break in? (THIS IS THE CRUCIAL STEP)
+     */
+    for (i = 0; hp->h_addr_list[i]; i++) {
+       if (memcmp(hp->h_addr_list[i],
+                  (char *) &addr->sin_addr, SIZEOF(addr->sin_addr)) == 0)
+           break;                     /* name is good, keep it */
+    }
+
+    /* If we did not find it, your DNS is messed up or someone is trying
+     * to pull a fast one on you. :(
+     */
+
+   /*   Check even the aliases list. Work around for Solaris if dns goes over NIS */
+
+    if (!hp->h_addr_list[i] ) {
+        for (j = 0; hp->h_aliases[j] !=0 ; j++) {
+            if (strcmp(hp->h_aliases[j],inet_ntoa(addr->sin_addr)) == 0)
+                break;                          /* name is good, keep it */
+        }
+       if (!hp->h_aliases[j] ) {
+           *errstr = vstralloc("[",
+                               "ip address ", inet_ntoa(addr->sin_addr),
+                               " is not in the ip list for ", remotehost,
+                               "]",
+                               NULL);
+           amfree(remotehost);
+           return 0;
+       }
+    }
+
+    /* next, make sure the remote port is a "reserved" one */
+
+    if (ntohs(addr->sin_port) >= IPPORT_RESERVED) {
+       char number[NUM_STR_SIZE];
+
+       snprintf(number, SIZEOF(number), "%hd", (short)ntohs(addr->sin_port));
+       *errstr = vstralloc("[",
+                           "host ", remotehost, ": ",
+                           "port ", number, " not secure",
+                           "]", NULL);
+       amfree(remotehost);
+       return 0;
+    }
+
+    /* extract the remote user name from the message */
+
+    s = str;
+    ch = *s++;
+
+    bad_bsd = vstralloc("[",
+                       "host ", remotehost, ": ",
+                       "bad bsd security line",
+                       "]", NULL);
+
+#define sc "USER "
+    if (strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+       *errstr = bad_bsd;
+       bad_bsd = NULL;
+       amfree(remotehost);
+       return 0;
+    }
+    s += SIZEOF(sc)-1;
+    ch = s[-1];
+#undef sc
+
+    skip_whitespace(s, ch);
+    if (ch == '\0') {
+       *errstr = bad_bsd;
+       bad_bsd = NULL;
+       amfree(remotehost);
+       return 0;
+    }
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    remoteuser = stralloc(fp);
+    s[-1] = (char)ch;
+    amfree(bad_bsd);
+
+    /* lookup our local user name */
+
+    myuid = getuid();
+    if ((pwptr = getpwuid(myuid)) == NULL)
+        error("error [getpwuid(%d) fails]", myuid);
+
+    secprintf(("%s: bsd security: remote host %s user %s local user %s\n",
+             debug_prefix(NULL), remotehost, remoteuser, pwptr->pw_name));
+
+#ifndef USE_AMANDAHOSTS
+    s = check_user_ruserok(remotehost, pwptr, remoteuser);
+#else
+    s = check_user_amandahosts(remotehost, addr->sin_addr, pwptr, remoteuser, NULL);
+#endif
+
+    if (s != NULL) {
+       *errstr = vstralloc("[",
+                           "access as ", pwptr->pw_name, " not allowed",
+                           " from ", remoteuser, "@", remotehost,
+                           ": ", s, "]", NULL);
+    }
+    amfree(s);
+    amfree(remotehost);
+    amfree(remoteuser);
+    return *errstr == NULL;
+}
+
+/*
+ * Writes out the entire iovec
+ */
+ssize_t
+net_writev(
+    int                        fd,
+    struct iovec *     iov,
+    int                        iovcnt)
+{
+    ssize_t delta, n, total;
+
+    assert(iov != NULL);
+
+    total = 0;
+    while (iovcnt > 0) {
+       /*
+        * Write the iovec
+        */
+       n = writev(fd, iov, iovcnt);
+       if (n < 0) {
+           if (errno != EINTR)
+               return (-1);
+           secprintf(("%s: net_writev got EINTR\n",
+                      debug_prefix(NULL)));
+       }
+       else if (n == 0) {
+           errno = EIO;
+           return (-1);
+       } else {
+           total += n;
+           /*
+            * Iterate through each iov.  Figure out what we still need
+            * to write out.
+            */
+           for (; n > 0; iovcnt--, iov++) {
+               /* 'delta' is the bytes written from this iovec */
+               delta = ((size_t)n < iov->iov_len) ? n : (ssize_t)iov->iov_len;
+               /* subtract from the total num bytes written */
+               n -= delta;
+               assert(n >= 0);
+               /* subtract from this iovec */
+               iov->iov_len -= delta;
+               iov->iov_base = (char *)iov->iov_base + delta;
+               /* if this iovec isn't empty, run the writev again */
+               if (iov->iov_len > 0)
+                   break;
+           }
+       }
+    }
+    return (total);
+}
+
+/*
+ * Like read(), but waits until the entire buffer has been filled.
+ */
+ssize_t
+net_read(
+    int                fd,
+    void *     vbuf,
+    size_t     origsize,
+    int                timeout)
+{
+    char *buf = vbuf;  /* ptr arith */
+    ssize_t nread;
+    size_t size = origsize;
+
+    secprintf(("%s: net_read: begin %d\n", debug_prefix_time(NULL), origsize));
+
+    while (size > 0) {
+       secprintf(("%s: net_read: while %d\n",
+                  debug_prefix_time(NULL), size));
+       nread = net_read_fillbuf(fd, timeout, buf, size);
+       if (nread < 0) {
+           secprintf(("%s: db: net_read: end return(-1)\n",
+                      debug_prefix_time(NULL)));
+           return (-1);
+       }
+       if (nread == 0) {
+           secprintf(("%s: net_read: end return(0)\n",
+                      debug_prefix_time(NULL)));
+           return (0);
+       }
+       buf += nread;
+       size -= nread;
+    }
+    secprintf(("%s: net_read: end %d\n",
+              debug_prefix_time(NULL), origsize));
+    return ((ssize_t)origsize);
+}
+
+/*
+ * net_read likes to do a lot of little reads.  Buffer it.
+ */
+ssize_t
+net_read_fillbuf(
+    int                fd,
+    int                timeout,
+    void *     buf,
+    size_t     size)
+{
+    fd_set readfds;
+    struct timeval tv;
+    ssize_t nread;
+
+    secprintf(("%s: net_read_fillbuf: begin\n", debug_prefix_time(NULL)));
+    FD_ZERO(&readfds);
+    FD_SET(fd, &readfds);
+    tv.tv_sec = timeout;
+    tv.tv_usec = 0;
+    switch (select(fd + 1, &readfds, NULL, NULL, &tv)) {
+    case 0:
+       errno = ETIMEDOUT;
+       /* FALLTHROUGH */
+    case -1:
+       secprintf(("%s: net_read_fillbuf: case -1\n",
+                  debug_prefix_time(NULL)));
+       return (-1);
+    case 1:
+       secprintf(("%s: net_read_fillbuf: case 1\n",
+                  debug_prefix_time(NULL)));
+       assert(FD_ISSET(fd, &readfds));
+       break;
+    default:
+       secprintf(("%s: net_read_fillbuf: case default\n",
+                  debug_prefix_time(NULL)));
+       assert(0);
+       break;
+    }
+    nread = read(fd, buf, size);
+    if (nread < 0)
+       return (-1);
+    secprintf(("%s: net_read_fillbuf: end %d\n",
+              debug_prefix_time(NULL), nread));
+    return (nread);
+}
+
+
+/*
+ * Display stat() information about a file.
+ */
+
+void
+show_stat_info(
+    char *     a,
+    char *     b)
+{
+    char *name = vstralloc(a, b, NULL);
+    struct stat sbuf;
+    struct passwd *pwptr;
+    char *owner;
+    struct group *grptr;
+    char *group;
+
+    if (stat(name, &sbuf) != 0) {
+       secprintf(("%s: bsd: cannot stat %s: %s\n",
+                  debug_prefix_time(NULL), name, strerror(errno)));
+       amfree(name);
+       return;
+    }
+    if ((pwptr = getpwuid(sbuf.st_uid)) == NULL) {
+       owner = alloc(NUM_STR_SIZE + 1);
+       snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_uid);
+    } else {
+       owner = stralloc(pwptr->pw_name);
+    }
+    if ((grptr = getgrgid(sbuf.st_gid)) == NULL) {
+       group = alloc(NUM_STR_SIZE + 1);
+       snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_gid);
+    } else {
+       group = stralloc(grptr->gr_name);
+    }
+    secprintf(("%s: bsd: processing file: %s\n", debug_prefix(NULL), name));
+    secprintf(("%s: bsd:                  owner=%s group=%s mode=%03o\n",
+              debug_prefix(NULL), owner, group, (int) (sbuf.st_mode & 0777)));
+    amfree(name);
+    amfree(owner);
+    amfree(group);
+}
diff --git a/common-src/security-util.h b/common-src/security-util.h
new file mode 100644 (file)
index 0000000..b1d8faa
--- /dev/null
@@ -0,0 +1,254 @@
+#ifndef _SECURITY_UTIL_H
+#define _SECURITY_UTIL_H
+
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1999 University of Maryland
+ * 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+
+/*
+ * $Id: security-util.h,v 1.5 2006/07/01 00:10:38 paddy_s Exp $
+ *
+ */
+
+#include "stream.h"
+#include "dgram.h"
+#include "queue.h"
+
+struct sec_handle;
+
+/*
+ * This is a sec connection to a host.  We should only have
+ * one connection per host.
+ */
+struct tcp_conn {
+    const struct security_driver *driver;      /* MUST be first */
+    int                        read, write;            /* pipes to sec */
+    pid_t              pid;                    /* pid of sec process */
+    char *             pkt;                    /* last pkt read */
+    ssize_t            pktlen;                 /* len of above */
+    event_handle_t *   ev_read;                /* read (EV_READFD) handle */
+    int                        ev_read_refcnt;         /* number of readers */
+    char               hostname[MAX_HOSTNAME_LENGTH+1];
+                                               /* host we're talking to */
+    char *             errmsg;                 /* error passed up */
+    int                        refcnt;                 /* number of handles using */
+    int                        handle;                 /* last proto handle read */
+    void               (*accept_fn)(security_handle_t *, pkt_t *);
+    struct sockaddr_in peer;
+    TAILQ_ENTRY(tcp_conn) tq;                  /* queue handle */
+    int                        (*recv_security_ok)(struct sec_handle *, pkt_t *);
+    char *             (*prefix_packet)(void *, pkt_t *);
+    int                        toclose;
+    int                        donotclose;
+};
+
+
+struct sec_stream;
+
+/*
+ * This is the private handle data.
+ */
+struct sec_handle {
+    security_handle_t  sech;           /* MUST be first */
+    char *             hostname;       /* ptr to rc->hostname */
+    struct sec_stream *        rs;             /* virtual stream we xmit over */
+    struct tcp_conn *  rc;             /* */
+    union {
+       void (*recvpkt)(void *, pkt_t *, security_status_t);
+                                       /* func to call when packet recvd */
+       void (*connect)(void *, security_handle_t *, security_status_t);
+                                       /* func to call when connected */
+    } fn;
+    void *             arg;            /* argument to pass function */
+    event_handle_t *   ev_timeout;     /* timeout handle for recv */
+    struct sockaddr_in peer;
+    int                        sequence;
+    event_id_t         event_id;
+    char *             proto_handle;
+    event_handle_t *   ev_read;
+    struct sec_handle *        prev;
+    struct sec_handle *        next;
+    struct udp_handle *        udp;
+    void               (*accept_fn)(security_handle_t *, pkt_t *);
+    int                        (*recv_security_ok)(struct sec_handle *, pkt_t *);
+};
+
+/*
+ * This is the internal security_stream data for sec.
+ */
+struct sec_stream {
+    security_stream_t  secstr;         /* MUST be first */
+    struct tcp_conn *  rc;             /* physical connection */
+    int                        handle;         /* protocol handle */
+    event_handle_t *   ev_read;        /* read (EV_WAIT) event handle */
+    void               (*fn)(void *, void *, ssize_t); /* read event fn */
+    void *             arg;            /* arg for previous */
+    int                        fd;
+    char               databuf[NETWORK_BLOCK_BYTES];
+    ssize_t            len;
+    int                        socket;
+    in_port_t          port;
+    int                        closed_by_me;
+    int                        closed_by_network;
+};
+
+struct connq_s {
+    TAILQ_HEAD(, tcp_conn) tailq;
+    int qlength;
+};
+extern struct connq_s connq;
+
+#define connq_first()           TAILQ_FIRST(&connq.tailq)
+#define connq_next(rc)          TAILQ_NEXT(rc, tq)
+#define connq_append(rc)        do {                                    \
+    TAILQ_INSERT_TAIL(&connq.tailq, rc, tq);                            \
+    connq.qlength++;                                                    \
+} while (0)
+#define connq_remove(rc)        do {                                    \
+    assert(connq.qlength > 0);                                          \
+    TAILQ_REMOVE(&connq.tailq, rc, tq);                                 \
+    connq.qlength--;                                                    \
+} while (0)
+
+/*
+ * This is data local to the datagram socket.  We have one datagram
+ * per process per auth.
+ */
+typedef struct udp_handle {
+    const struct security_driver *driver;      /* MUST be first */
+    dgram_t dgram;             /* datagram to read/write from */
+    struct sockaddr_in peer;   /* who sent it to us */
+    pkt_t pkt;                 /* parsed form of dgram */
+    char *handle;              /* handle from recvd packet */
+    int sequence;              /* seq no of packet */
+    event_handle_t *ev_read;   /* read event handle from dgram */
+    int refcnt;                        /* number of handles blocked for reading */
+    struct sec_handle *bh_first, *bh_last;
+    void (*accept_fn)(security_handle_t *, pkt_t *);
+    int (*recv_security_ok)(struct sec_handle *, pkt_t *);
+    char *(*prefix_packet)(void *, pkt_t *);
+} udp_handle_t;
+
+/*
+ * We register one event handler for our network fd which takes
+ * care of all of our async requests.  When all async requests
+ * have either been satisfied or cancelled, we unregister our
+ * network event handler.
+ */
+#define        udp_addref(udp, netfd_read_callback) do {                       \
+    if ((udp)->refcnt++ == 0) {                                                \
+       assert((udp)->ev_read == NULL);                                 \
+       (udp)->ev_read = event_register((event_id_t)(udp)->dgram.socket,\
+           EV_READFD, netfd_read_callback, (udp));                     \
+    }                                                                  \
+    assert((udp)->refcnt > 0);                                         \
+} while (0)
+
+/*
+ * If this is the last request to be removed, then remove the
+ * reader event from the netfd.
+ */
+#define        udp_delref(udp) do {                                            \
+    assert((udp)->refcnt > 0);                                         \
+    if (--(udp)->refcnt == 0) {                                                \
+       assert((udp)->ev_read != NULL);                                 \
+       event_release((udp)->ev_read);                                  \
+       (udp)->ev_read = NULL;                                          \
+    }                                                                  \
+} while (0)
+
+
+int    sec_stream_auth(void *);
+int    sec_stream_id(void *);
+void   sec_accept(const security_driver_t *, int, int,
+                   void (*)(security_handle_t *, pkt_t *));
+void   sec_close(void *);
+void   sec_connect_callback(void *);
+void   sec_connect_timeout(void *);
+void   sec_close_connection_none(void *, char *);
+
+ssize_t        stream_sendpkt(void *, pkt_t *);
+void   stream_recvpkt(void *,
+                       void (*)(void *, pkt_t *, security_status_t),
+                       void *, int);
+void   stream_recvpkt_timeout(void *);
+void   stream_recvpkt_cancel(void *);
+
+int    tcpm_stream_write(void *, const void *, size_t);
+void   tcpm_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
+ssize_t        tcpm_stream_read_sync(void *, void **);
+void   tcpm_stream_read_cancel(void *);
+ssize_t        tcpm_send_token(int, int, char **, const void *, size_t);
+ssize_t        tcpm_recv_token(int, int *, char **, char **, ssize_t *, int);
+void   tcpm_close_connection(void *, char *);
+
+int    tcpma_stream_accept(void *);
+void * tcpma_stream_client(void *, int);
+void * tcpma_stream_server(void *);
+void   tcpma_stream_close(void *);
+
+void * tcp1_stream_server(void *);
+int    tcp1_stream_accept(void *);
+void * tcp1_stream_client(void *, int);
+
+int    tcp_stream_write(void *, const void *, size_t);
+
+char * bsd_prefix_packet(void *, pkt_t *);
+int    bsd_recv_security_ok(struct sec_handle *, pkt_t *);
+
+ssize_t        udpbsd_sendpkt(void *, pkt_t *);
+void   udp_close(void *);
+void   udp_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
+                    void *, int);
+void   udp_recvpkt_cancel(void *);
+void   udp_recvpkt_callback(void *);
+void   udp_recvpkt_timeout(void *);
+int    udp_inithandle(udp_handle_t *, struct sec_handle *, struct hostent *,
+                       in_port_t, char *, int);
+void   udp_netfd_read_callback(void *);
+
+struct tcp_conn *sec_tcp_conn_get(const char *, int);
+void   sec_tcp_conn_put(struct tcp_conn *);
+void   sec_tcp_conn_read(struct tcp_conn *);
+void   parse_pkt(pkt_t *, const void *, size_t);
+const char *pkthdr2str(const struct sec_handle *, const pkt_t *);
+int    str2pkthdr(udp_handle_t *);
+char * check_user(struct sec_handle *, const char *, const char *);
+
+char * check_user_ruserok    (const char *host,
+                               struct passwd *pwd,
+                               const char *user);
+char * check_user_amandahosts(const char *host,
+                               struct in_addr addr,
+                               struct passwd *pwd,
+                               const char *user,
+                               const char *service);
+
+ssize_t        net_writev(int, struct iovec *, int);
+ssize_t        net_read(int, void *, size_t, int);
+ssize_t net_read_fillbuf(int, int, void *, size_t);
+void   show_stat_info(char *a, char *b);
+
+#endif /* _SECURITY_INFO_H */
index 795d64eda86df73eacd91f34a4f2de0c586a9e33..76cf78ddc345427be060b7b01b483e749c0c0387 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: security.c,v 1.26 2004/03/16 19:09:39 martinea Exp $
+ * $Id: security.c,v 1.28 2006/05/25 01:47:12 johnfranks Exp $
  *
  * Security driver interface for the Amanda backup system.
  */
@@ -49,6 +49,12 @@ extern const security_driver_t rsh_security_driver;
 #ifdef SSH_SECURITY
 extern const security_driver_t ssh_security_driver;
 #endif
+#ifdef BSDTCP_SECURITY
+extern const security_driver_t bsdtcp_security_driver;
+#endif
+#ifdef BSDUDP_SECURITY
+extern const security_driver_t bsdudp_security_driver;
+#endif
 
 static const security_driver_t *drivers[] = {
 #ifdef BSD_SECURITY
@@ -66,23 +72,34 @@ static const security_driver_t *drivers[] = {
 #ifdef SSH_SECURITY
     &ssh_security_driver,
 #endif
+#ifdef BSDTCP_SECURITY
+    &bsdtcp_security_driver,
+#endif
+#ifdef BSDUDP_SECURITY
+    &bsdudp_security_driver,
+#endif
 };
-#define        NDRIVERS        (sizeof(drivers) / sizeof(drivers[0]))
+#define        NDRIVERS        (size_t)(sizeof(drivers) / sizeof(drivers[0]))
 
 /*
  * Given a name of a security type, returns the driver structure
  */
 const security_driver_t *
-security_getdriver(name)
-    const char *name;
+security_getdriver(
+    const char *       name)
 {
-    int i;
+    size_t i;
 
     assert(name != NULL);
 
-    for (i = 0; i < NDRIVERS; i++)
-       if (strcasecmp(name, drivers[i]->name) == 0)
+    for (i = 0; i < NDRIVERS; i++) {
+       if (strcasecmp(name, drivers[i]->name) == 0) {
+           dbprintf(("security_getdriver(name=%s) returns %p\n",
+                       name, drivers[i]));
            return (drivers[i]);
+       }
+    }
+    dbprintf(("security_getdriver(name=%s) returns NULL\n", name));
     return (NULL);
 }
 
@@ -90,11 +107,12 @@ security_getdriver(name)
  * For the drivers: initialize the common part of a security_handle_t
  */
 void
-security_handleinit(handle, driver)
-    security_handle_t *handle;
-    const security_driver_t *driver;
+security_handleinit(
+    security_handle_t *                handle,
+    const security_driver_t *  driver)
 {
-
+    dbprintf(("security_handleinit(handle=%p, driver=%p (%s))\n",
+               handle, driver, driver->name));
     handle->driver = driver;
     handle->error = stralloc("unknown protocol error");
 }
@@ -107,16 +125,19 @@ printf_arglist_function1(void security_seterror, security_handle_t *, handle,
 
     assert(handle->error != NULL);
     arglist_start(argp, fmt);
-    vsnprintf(buf, sizeof(buf), fmt, argp);
+    vsnprintf(buf, SIZEOF(buf), fmt, argp);
     arglist_end(argp);
     handle->error = newstralloc(handle->error, buf);
+    dbprintf(("security_seterror(handle=%p, driver=%p (%s) error=%s)\n",
+               handle, handle->driver, handle->driver->name, handle->error));
 }
 
 void
-security_close(handle)
-    security_handle_t *handle;
+security_close(
+    security_handle_t *        handle)
 {
-
+    dbprintf(("security_close(handle=%p, driver=%p (%s))\n",
+               handle, handle->driver, handle->driver->name));
     amfree(handle->error);
     (*handle->driver->close)(handle);
 }
@@ -125,11 +146,12 @@ security_close(handle)
  * For the drivers: initialize the common part of a security_stream_t
  */
 void
-security_streaminit(stream, driver)
-    security_stream_t *stream;
-    const security_driver_t *driver;
+security_streaminit(
+    security_stream_t *                stream,
+    const security_driver_t *  driver)
 {
-
+    dbprintf(("security_streaminit(stream=%p, driver=%p (%s))\n",
+               stream, driver, driver->name));
     stream->driver = driver;
     stream->error = stralloc("unknown stream error");
 }
@@ -141,18 +163,18 @@ printf_arglist_function1(void security_stream_seterror,
     static char buf[256];
     va_list argp;
 
-    assert(stream->error != NULL);
     arglist_start(argp, fmt);
-    vsnprintf(buf, sizeof(buf), fmt, argp);
+    vsnprintf(buf, SIZEOF(buf), fmt, argp);
     arglist_end(argp);
     stream->error = newstralloc(stream->error, buf);
+    dbprintf(("security_stream_seterr(%p, %s)\n", stream, stream->error));
 }
 
 void
-security_stream_close(stream)
-    security_stream_t *stream;
+security_stream_close(
+    security_stream_t *        stream)
 {
-
+    dbprintf(("security_stream_close(%p)\n", stream));
     amfree(stream->error);
     (*stream->driver->stream_close)(stream);
 }
index 9d8448e5dcf85284ab93c334c6c81779578f6c53..d0971b4ab683cea573e6cad5eb30f684ad3dcda7 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: security.h,v 1.11 2003/04/26 02:02:19 kovert Exp $
+ * $Id: security.h,v 1.17 2006/05/26 14:00:58 martinea Exp $
  *
  * security api
  */
 #ifndef SECURITY_H
 #define        SECURITY_H
 
+#include "packet.h"
+
 struct security_handle;
 
 /*
@@ -55,27 +57,28 @@ typedef struct security_driver {
      * Connects a security handle, for this driver to a remote
      * host.
      */
-    void (*connect) P((const char *,
+    void (*connect)(const char *,
        char *(*)(char *, void *),
        void (*)(void *, struct security_handle *, security_status_t),
-       void *));
+       void *, void *);
 
     /*
      * This form sets up a callback that returns new handles as
      * they are received.  It takes an input and output file descriptor.
      */
-    void (*accept) P((int, int, void (*)(struct security_handle *, pkt_t *)));
+    void (*accept)(const struct security_driver *, int, int,
+                       void (*)(struct security_handle *, pkt_t *));
 
     /*
      * Frees up handles allocated by the previous
      */
-    void (*close) P((void *));
+    void (*close)(void *);
 
     /*
      * This transmits a packet after adding the security information
      * Returns 0 on success, negative on error.
      */
-    int (*sendpkt) P((void *, pkt_t *));
+    ssize_t (*sendpkt)(void *, pkt_t *);
 
     /*
      * This creates an event in the event handler for receiving pkt_t's
@@ -89,60 +92,67 @@ typedef struct security_driver {
      * 
      * Only one recvpkt request can exist per handle.
      */
-    void (*recvpkt) P((void *, void (*)(void *, pkt_t *,
-       security_status_t), void *, int));
+    void (*recvpkt)(void *, void (*)(void *, pkt_t *,
+       security_status_t), void *, int);
 
     /*
      * Cancel an outstanding recvpkt request on a handle.
      */
-    void (*recvpkt_cancel) P((void *));
+    void (*recvpkt_cancel)(void *);
 
     /*
      * Get a stream given a security handle
      */
-    void *(*stream_server) P((void *));
+    void *(*stream_server)(void *);
 
     /*
      * Accept a stream created by stream_server
      */
-    int (*stream_accept) P((void *));
+    int (*stream_accept)(void *);
 
     /*
      * Get a stream and connect it to a remote given a security handle
      * and a stream id.
      */
-    void *(*stream_client) P((void *, int));
+    void *(*stream_client)(void *, int);
 
     /*
      * Close a stream opened with stream_server or stream_client
      */
-    void (*stream_close) P((void *));
+    void (*stream_close)(void *);
 
     /*
      * Authenticate a stream.
      */
-    int (*stream_auth) P((void *));
+    int (*stream_auth)(void *);
 
     /*
      * Return a numeric id for a stream.
      */
-    int (*stream_id) P((void *));
+    int (*stream_id)(void *);
 
     /*
      * Write to a stream.
      */
-    int (*stream_write) P((void *, const void *, size_t));
+    int (*stream_write)(void *, const void *, size_t);
 
     /*
      * Read asyncronously from a stream.  Only one request can exist
      * per stream.
      */
-    void (*stream_read) P((void *, void (*)(void *, void *, ssize_t), void *));
+    void (*stream_read)(void *, void (*)(void *, void *, ssize_t), void *);
+
+    /*
+     * Read syncronously from a stream.
+     */
+    ssize_t (*stream_read_sync)(void *, void **);
 
     /*
      * Cancel a stream read request
      */
-    void (*stream_read_cancel) P((void *));
+    void (*stream_read_cancel)(void *);
+
+    void (*close_connection)(void *, char *);
 
 } security_driver_t;
 
@@ -169,77 +179,83 @@ typedef struct security_stream {
 } security_stream_t;
 
 
-const security_driver_t *security_getdriver P((const char *));
-void security_handleinit P((security_handle_t *, const security_driver_t *));
-void security_streaminit P((security_stream_t *, const security_driver_t *));
+const security_driver_t *security_getdriver(const char *);
+void security_handleinit(security_handle_t *, const security_driver_t *);
+void security_streaminit(security_stream_t *, const security_driver_t *);
 
-/* const char *security_geterror P((security_handle_t *)); */
+/* const char *security_geterror(security_handle_t *); */
 #define        security_geterror(handle)       ((handle)->error)
-void security_seterror P((security_handle_t *, const char *, ...))
+void security_seterror(security_handle_t *, const char *, ...)
     __attribute__ ((format (printf, 2, 3)));
 
 
-/* void security_connect P((const security_driver_t *, const char *,
-    void (*)(void *, security_handle_t *, security_status_t), void *)); */
-#define        security_connect(driver, hostname, conf_fn, fn, arg)    \
-    (*(driver)->connect)(hostname, conf_fn, fn, arg)
-/* void security_accept P((const security_driver_t *, int, int,
-    void (*)(security_handle_t *, pkt_t *))); */
+/* void security_connect(const security_driver_t *, const char *,
+    void (*)(void *, security_handle_t *, security_status_t), void *, void *); */
+#define        security_connect(driver, hostname, conf_fn, fn, arg, datap)     \
+    (*(driver)->connect)(hostname, conf_fn, fn, arg, datap)
+/* void security_accept(const security_driver_t *, int, int,
+    void (*)(security_handle_t *, pkt_t *)); */
 #define        security_accept(driver, in, out, fn)    \
-    (*(driver)->accept)(in, out, fn)
-void security_close P((security_handle_t *));
+    (*(driver)->accept)(driver, in, out, fn)
+void security_close(security_handle_t *);
 
-/* int security_sendpkt P((security_handle_t *, const pkt_t *)); */
+/* int security_sendpkt(security_handle_t *, const pkt_t *); */
 #define        security_sendpkt(handle, pkt)           \
     (*(handle)->driver->sendpkt)(handle, pkt)
 
-/* void security_recvpkt P((security_handle_t *,
+/* void security_recvpkt(security_handle_t *,
     void (*)(void *, pkt_t *, security_status_t), void *, int); */
 #define        security_recvpkt(handle, fn, arg, timeout)      \
     (*(handle)->driver->recvpkt)(handle, fn, arg, timeout)
 
-/* void security_recvpkt_cancel P((security_handle_t *)); */
+/* void security_recvpkt_cancel(security_handle_t *); */
 #define        security_recvpkt_cancel(handle)         \
     (*(handle)->driver->recvpkt_cancel)(handle)
 
-/* const char *security_stream_geterror P((security_stream_t *)); */
+/* const char *security_stream_geterror(security_stream_t *); */
 #define        security_stream_geterror(stream)        ((stream)->error)
-void security_stream_seterror P((security_stream_t *, const char *, ...))
+void security_stream_seterror(security_stream_t *, const char *, ...)
     __attribute__ ((format (printf, 2, 3)));
 
-/* security_stream_t *security_stream_server P((security_handle_t *)); */
+/* security_stream_t *security_stream_server(security_handle_t *); */
 #define        security_stream_server(handle)  \
     (*(handle)->driver->stream_server)(handle)
 
-/* int security_stream_accept P((security_stream_t *)); */
+/* int security_stream_accept(security_stream_t *); */
 #define        security_stream_accept(stream)          \
     (*(stream)->driver->stream_accept)(stream)
 
-/* security_stream_t *security_stream_client P((security_handle_t *, int)); */
+/* security_stream_t *security_stream_client(security_handle_t *, int); */
 #define        security_stream_client(handle, id)      \
     (*(handle)->driver->stream_client)(handle, id)
 
-void security_stream_close P((security_stream_t *));
+void security_stream_close(security_stream_t *);
 
-/* int security_stream_auth P((security_stream_t *)); */
+/* int security_stream_auth(security_stream_t *); */
 #define        security_stream_auth(stream)            \
     (*(stream)->driver->stream_auth)(stream)
 
-/* int security_stream_id P((security_stream_t *)); */
+/* int security_stream_id(security_stream_t *); */
 #define        security_stream_id(stream)              \
     (*(stream)->driver->stream_id)(stream)
 
-/* int security_stream_write P((security_stream_t *, const void *, size_t)); */
+/* int security_stream_write(security_stream_t *, const void *, size_t); */
 #define        security_stream_write(stream, buf, size)        \
     (*(stream)->driver->stream_write)(stream, buf, size)
 
-/* void security_stream_read P((security_stream_t *,
-    void (*)(void *, void *, size_t), void *)); */
+/* void security_stream_read(security_stream_t *,
+    void (*)(void *, void *, size_t), void *); */
 #define        security_stream_read(stream, fn, arg)           \
     (*(stream)->driver->stream_read)(stream, fn, arg)
 
-/* void security_stream_read_cancel P((security_stream_t *)); */
+/* void security_stream_read_sync(security_stream_t *, void *); */
+#define        security_stream_read_sync(stream, buf)          \
+    (*(stream)->driver->stream_read_sync)(stream, buf)
+
+/* void security_stream_read_cancel(security_stream_t *); */
 #define        security_stream_read_cancel(stream)             \
     (*(stream)->driver->stream_read_cancel)(stream)
 
+#define security_close_connection(handle, hostname) \
+    (*(handle)->driver->close_connection)(handle, hostname)
 #endif /* SECURITY_H */
index 44599602c265c6707bc8bb0f6256290215a803a6..f84ebb3883c55b3babe96c036aa50506a6bb26d5 100644 (file)
@@ -25,7 +25,7 @@
  *                         University of Maryland at College Park
  */
 /*
- * $Id: sl.c,v 1.5 2005/09/30 19:01:43 martinea Exp $
+ * $Id: sl.c,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
  *
  * A doubly linked list of string (char *)
  */
@@ -34,8 +34,8 @@
 #include "sl.h"
 
 
-void init_sl(sl)
-sl_t *sl;
+void init_sl(
+    sl_t *sl)
 {
     sl->first = NULL;
     sl->last  = NULL;
@@ -43,24 +43,27 @@ sl_t *sl;
 }
 
 
-sl_t *new_sl() {
+sl_t *
+new_sl(void)
+{
     sl_t *sl;
-    sl = alloc(sizeof(sl_t));
+    sl = alloc(SIZEOF(sl_t));
     init_sl(sl);
     return(sl);
 }
 
 
-sl_t *insert_sl(sl, name)
-sl_t *sl;
-char *name;
+sl_t *
+insert_sl(
+    sl_t *sl,
+    char *name)
 {
     sle_t *a;
 
     if(!sl) {
        sl = new_sl();
     }
-    a = alloc(sizeof(sle_t));
+    a = alloc(SIZEOF(sle_t));
     a->name = stralloc(name);
     a->next = sl->first;
     a->prev = NULL;
@@ -74,16 +77,17 @@ char *name;
 }
 
 
-sl_t *append_sl(sl, name)
-sl_t *sl;
-char *name;
+sl_t *
+append_sl(
+    sl_t *     sl,
+    char *     name)
 {
     sle_t *a;
 
     if(!sl) {
        sl = new_sl();
     }
-    a = alloc(sizeof(sle_t));
+    a = alloc(SIZEOF(sle_t));
     a->name = stralloc(name);
     a->prev = sl->last;
     a->next = NULL;
@@ -97,9 +101,10 @@ char *name;
 }
 
 
-sl_t *insert_sort_sl(sl, name)
-sl_t *sl;
-char *name;
+sl_t *
+insert_sort_sl(
+    sl_t *     sl,
+    char *     name)
 {
     sle_t *a, *b;
 
@@ -116,7 +121,7 @@ char *name;
     if(b == sl->first) return insert_sl(sl, name);
     if(b == NULL)      return append_sl(sl, name);
 
-    a = alloc(sizeof(sle_t));
+    a = alloc(SIZEOF(sle_t));
     a->name = stralloc(name);
 
     /* insert before b */
@@ -129,8 +134,9 @@ char *name;
 }
 
 
-void free_sl(sl)
-sl_t *sl;
+void
+free_sl(
+    sl_t *     sl)
 {
     sle_t *a, *b;
 
@@ -147,9 +153,10 @@ sl_t *sl;
 }
 
 
-void remove_sl(sl, elem)
-sl_t *sl;
-sle_t *elem;
+void
+remove_sl(
+    sl_t *     sl,
+    sle_t *    elem)
 {
     if(elem->prev)
        elem->prev->next = elem->next;
@@ -168,8 +175,9 @@ sle_t *elem;
 }
 
 
-sl_t *duplicate_sl(sl)
-sl_t *sl;
+sl_t *
+duplicate_sl(
+    sl_t *     sl)
 {
     sl_t *new_sl = NULL;
     sle_t *a;
@@ -186,8 +194,9 @@ sl_t *sl;
 /*
  * Return "true" iff sl is empty (i.e. contains no elements).
  */
-int is_empty_sl(sl)
-sl_t *sl;
+int
+is_empty_sl(
+    sl_t *     sl)
 {
     if (sl == NULL)
        return 1;
index a54a78470992ca4b9293ba6fca41a363d673db8d..7671d79c488dcc980eb9e8a09fe8e9e30dc1170b 100644 (file)
@@ -25,7 +25,7 @@
  *                         University of Maryland at College Park
  */
 /*
- * $Id: sl.h,v 1.3 2004/04/23 11:44:46 martinea Exp $
+ * $Id: sl.h,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
  *
  * A doubly linked list of string (char *)
  */
@@ -51,14 +51,14 @@ typedef struct sl_s {
     int nb_element;
 } sl_t;
 
-void init_sl P((sl_t *sl));
-sl_t *new_sl P(());
-sl_t *insert_sl P((sl_t *sl, char *name));
-sl_t *append_sl P((sl_t *sl, char *name));
-sl_t *insert_sort_sl P((sl_t *sl, char *name));
-void free_sl P((sl_t *sl));
-void remove_sl P((sl_t *sl,sle_t *elem));
-sl_t *duplicate_sl P((sl_t *sl));
-int  is_empty_sl P((sl_t *sl));
+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 83a7a2c732eb15314408a5e708d20c117782be69..c0b023c86aa79a4819163fcb89a1a9ae752e52de 100644 (file)
@@ -25,7 +25,7 @@
  */
 
 /*
- * $Id: ssh-security.c,v 1.8.2.1 2006/04/11 11:11:16 martinea Exp $
+ * $Id: ssh-security.c,v 1.23 2006/08/21 20:17:10 martinea Exp $
  *
  * ssh-security.c - security and transport over ssh or a ssh-like command.
  *
  */
 
 #include "amanda.h"
+#include "util.h"
 #include "event.h"
 #include "packet.h"
 #include "queue.h"
 #include "security.h"
+#include "security-util.h"
 #include "stream.h"
 #include "version.h"
 
 /*#define      SSH_DEBUG*/
 
 #ifdef SSH_DEBUG
-#define        sshprintf(x)    dbprintf(x)
+int    ssh_debug = 1; 
 #else
-#define        sshprintf(x)
+int    ssh_debug = 0; 
 #endif
 
+#define        sshprintf(x)                            \
+           do {                                \
+               if (ssh_debug) {                \
+                   dbprintf(x);                \
+               }                               \
+           } while (0)
+
 /*
  * Path to the ssh binary.  This should be configurable.
  */
@@ -59,7 +68,7 @@
 /*
  * Arguments to ssh.  This should also be configurable
  */
-#define        SSH_ARGS        "-x", "-l", CLIENT_LOGIN
+#define        SSH_ARGS        "-x", "-o", "BatchMode=yes", "-o", "PreferredAuthentications=publickey"
 
 /*
  * Number of seconds ssh has to start up
 #define        H_TAKEN -1              /* ssh_conn->tok was already read */
 #define        H_EOF   -2              /* this connection has been shut down */
 
-/*
- * This is a ssh connection to a host.  We should only have
- * one connection per host.
- */
-struct ssh_conn {
-    int read, write;                           /* pipes to ssh */
-    pid_t pid;                                 /* pid of ssh process */
-    char pkt[NETWORK_BLOCK_BYTES];             /* last pkt read */
-    unsigned long pktlen;                      /* len of above */
-    struct {                                   /* buffer read() calls */
-       char buf[STREAM_BUFSIZE];               /* buffer */
-       size_t left;                    /* unread data */
-       ssize_t size;                   /* size of last read */
-    } readbuf;
-    event_handle_t *ev_read;                   /* read (EV_READFD) handle */
-    int ev_read_refcnt;                                /* number of readers */
-    char hostname[MAX_HOSTNAME_LENGTH+1];      /* host we're talking to */
-    char *errmsg;                              /* error passed up */
-    int refcnt;                                        /* number of handles using */
-    int handle;                                        /* last proto handle read */
-    TAILQ_ENTRY(ssh_conn) tq;                  /* queue handle */
-};
-
-
-struct ssh_stream;
-
-/*
- * This is the private handle data.
- */
-struct ssh_handle {
-    security_handle_t sech;            /* MUST be first */
-    char *hostname;                    /* ptr to rc->hostname */
-    struct ssh_stream *rs;             /* virtual stream we xmit over */
-
-    union {
-       void (*recvpkt) P((void *, pkt_t *, security_status_t));
-                                       /* func to call when packet recvd */
-       void (*connect) P((void *, security_handle_t *, security_status_t));
-                                       /* func to call when connected */
-    } fn;
-    void *arg;                         /* argument to pass function */
-    event_handle_t *ev_timeout;                /* timeout handle for recv */
-};
-
-/*
- * This is the internal security_stream data for ssh.
- */
-struct ssh_stream {
-    security_stream_t secstr;          /* MUST be first */
-    struct ssh_conn *rc;               /* physical connection */
-    int handle;                                /* protocol handle */
-    event_handle_t *ev_read;           /* read (EV_WAIT) event handle */
-    void (*fn) P((void *, void *, ssize_t));   /* read event fn */
-    void *arg;                         /* arg for previous */
-};
-
 /*
  * Interface functions
  */
-static int ssh_sendpkt P((void *, pkt_t *));
-static int ssh_stream_accept P((void *));
-static int ssh_stream_auth P((void *));
-static int ssh_stream_id P((void *));
-static int ssh_stream_write P((void *, const void *, size_t));
-static void *ssh_stream_client P((void *, int));
-static void *ssh_stream_server P((void *));
-static void ssh_accept P((int, int,
-    void (*)(security_handle_t *, pkt_t *)));
-static void ssh_close P((void *));
-static void ssh_connect P((const char *,
-    char *(*)(char *, void *), 
-    void (*)(void *, security_handle_t *, security_status_t), void *));
-static void ssh_recvpkt P((void *,
-    void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void ssh_recvpkt_cancel P((void *));
-static void ssh_stream_close P((void *));
-static void ssh_stream_read P((void *, void (*)(void *, void *, ssize_t),
-    void *));
-static void ssh_stream_read_cancel P((void *));
+static void    ssh_connect(const char *, char *(*)(char *, void *),
+                       void (*)(void *, security_handle_t *, security_status_t),
+                       void *, void *);
 
 /*
  * This is our interface to the outside world.
@@ -158,126 +94,96 @@ static void ssh_stream_read_cancel P((void *));
 const security_driver_t ssh_security_driver = {
     "SSH",
     ssh_connect,
-    ssh_accept,
-    ssh_close,
-    ssh_sendpkt,
-    ssh_recvpkt,
-    ssh_recvpkt_cancel,
-    ssh_stream_server,
-    ssh_stream_accept,
-    ssh_stream_client,
-    ssh_stream_close,
-    ssh_stream_auth,
-    ssh_stream_id,
-    ssh_stream_write,
-    ssh_stream_read,
-    ssh_stream_read_cancel,
-};
-
-/*
- * This is a queue of open connections
- */
-static struct {
-    TAILQ_HEAD(, ssh_conn) tailq;
-    int qlength;
-} connq = {
-    TAILQ_HEAD_INITIALIZER(connq.tailq), 0
+    sec_accept,
+    sec_close,
+    stream_sendpkt,
+    stream_recvpkt,
+    stream_recvpkt_cancel,
+    tcpma_stream_server,
+    tcpma_stream_accept,
+    tcpma_stream_client,
+    tcpma_stream_close,
+    sec_stream_auth,
+    sec_stream_id,
+    tcpm_stream_write,
+    tcpm_stream_read,
+    tcpm_stream_read_sync,
+    tcpm_stream_read_cancel,
+    tcpm_close_connection,
 };
-#define        connq_first()           TAILQ_FIRST(&connq.tailq)
-#define        connq_next(rc)          TAILQ_NEXT(rc, tq)
-#define        connq_append(rc)        do {                                    \
-    TAILQ_INSERT_TAIL(&connq.tailq, rc, tq);                           \
-    connq.qlength++;                                                   \
-} while (0)
-#define        connq_remove(rc)        do {                                    \
-    assert(connq.qlength > 0);                                         \
-    TAILQ_REMOVE(&connq.tailq, rc, tq);                                        \
-    connq.qlength--;                                                   \
-} while (0)
 
 static int newhandle = 1;
 
-/*
- * This is a function that should be called if a new security_handle_t is
- * created.  If NULL, no new handles are created.
- * It is passed the new handle and the received pkt
- */
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
-
 /*
  * Local functions
  */
-static void connect_callback P((void *));
-static void connect_timeout P((void *));
-static int send_token P((struct ssh_conn *, int, const void *, size_t));
-static int recv_token P((struct ssh_conn *, int));
-static void recvpkt_callback P((void *, void *, ssize_t));
-static void recvpkt_timeout P((void *));
-static void stream_read_callback P((void *));
-
-static int runssh P((struct ssh_conn *));
-static struct ssh_conn *conn_get P((const char *));
-static void conn_put P((struct ssh_conn *));
-static void conn_read P((struct ssh_conn *));
-static void conn_read_cancel P((struct ssh_conn *));
-static void conn_read_callback P((void *));
-static int net_writev P((int, struct iovec *, int));
-static ssize_t net_read P((struct ssh_conn *, void *, size_t, int));
-static int net_read_fillbuf P((struct ssh_conn *, int, int));
-static void parse_pkt P((pkt_t *, const void *, size_t));
-
+static int runssh(struct tcp_conn *, const char *, const char *, const char *);
 
 /*
  * ssh version of a security handle allocator.  Logically sets
  * up a network "connection".
  */
 static void
-ssh_connect(hostname, conf_fn, fn, arg)
-    const char *hostname;
-    char *(*conf_fn) P((char *, void *));
-    void (*fn) P((void *, security_handle_t *, security_status_t));
-    void *arg;
-{
-    struct ssh_handle *rh;
+ssh_connect(
+    const char *       hostname,
+    char *             (*conf_fn)(char *, void *),
+    void               (*fn)(void *, security_handle_t *, security_status_t),
+    void *             arg,
+    void *             datap)
+{
+    struct sec_handle *rh;
     struct hostent *he;
+    char *amandad_path=NULL, *client_username=NULL, *ssh_keys=NULL;
 
     assert(fn != NULL);
     assert(hostname != NULL);
 
-    sshprintf(("%s: ssh: ssh_connect: %s\n", debug_prefix_time(NULL), hostname));
+    (void)conf_fn;     /* Quiet unused parameter warning */
+
+    sshprintf(("%s: ssh: ssh_connect: %s\n", debug_prefix_time(NULL),
+              hostname));
 
-    rh = alloc(sizeof(*rh));
+    rh = alloc(SIZEOF(*rh));
     security_handleinit(&rh->sech, &ssh_security_driver);
     rh->hostname = NULL;
     rh->rs = NULL;
     rh->ev_timeout = NULL;
+    rh->rc = NULL;
 
     if ((he = gethostbyname(hostname)) == NULL) {
        security_seterror(&rh->sech,
-           "%s: could not resolve hostname", hostname);
+           "%s: ssh could not resolve hostname", hostname);
        (*fn)(arg, &rh->sech, S_ERROR);
        return;
     }
-    rh->hostname = he->h_name; /* will be replaced */
-    rh->rs = ssh_stream_client(rh, newhandle++);
+    rh->hostname = stralloc(he->h_name);       /* will be replaced */
+    rh->rs = tcpma_stream_client(rh, newhandle++);
 
     if (rh->rs == NULL)
        goto error;
 
-    rh->hostname = rh->rs->rc->hostname;
+    amfree(rh->hostname);
+    rh->hostname = stralloc(rh->rs->rc->hostname);
 
-    if (rh->rs->rc->pid < 0) {
-       /*
-        * We need to open a new connection.
-        *
-        * XXX need to eventually limit number of outgoing connections here.
-        */
-       if (runssh(rh->rs->rc) < 0) {
-           security_seterror(&rh->sech,
-               "can't connect to %s: %s", hostname, rh->rs->rc->errmsg);
+    /*
+     * We need to open a new connection.
+     *
+     * XXX need to eventually limit number of outgoing connections here.
+     */
+    if(conf_fn) {
+       amandad_path    = conf_fn("amandad_path", datap);
+       client_username = conf_fn("client_username", datap);
+       ssh_keys        = conf_fn("ssh_keys", datap);
+    }
+    if(rh->rc->read == -1) {
+       if (runssh(rh->rs->rc, amandad_path, client_username, ssh_keys) < 0) {
+           security_seterror(&rh->sech, "can't connect to %s: %s",
+                             hostname, rh->rs->rc->errmsg);
            goto error;
        }
+       rh->rc->refcnt++;
     }
+
     /*
      * The socket will be opened async so hosts that are down won't
      * block everything.  We need to register a write event
@@ -288,10 +194,10 @@ ssh_connect(hostname, conf_fn, fn, arg)
      */
     rh->fn.connect = fn;
     rh->arg = arg;
-    rh->rs->ev_read = event_register(rh->rs->rc->write, EV_WRITEFD,
-       connect_callback, rh);
-    rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
-       connect_timeout, rh);
+    rh->rs->ev_read = event_register((event_id_t)rh->rs->rc->write, EV_WRITEFD,
+       sec_connect_callback, rh);
+    rh->ev_timeout = event_register((event_id_t)CONNECT_TIMEOUT, EV_TIME,
+       sec_connect_timeout, rh);
 
     return;
 
@@ -299,215 +205,32 @@ error:
     (*fn)(arg, &rh->sech, S_ERROR);
 }
 
-/*
- * Called when a ssh connection is finished connecting and is ready
- * to be authenticated.
- */
-static void
-connect_callback(cookie)
-    void *cookie;
-{
-    struct ssh_handle *rh = cookie;
-
-    event_release(rh->rs->ev_read);
-    rh->rs->ev_read = NULL;
-    event_release(rh->ev_timeout);
-    rh->ev_timeout = NULL;
-
-    (*rh->fn.connect)(rh->arg, &rh->sech, S_OK);
-}
-
-/*
- * Called if a connection times out before completion.
- */
-static void
-connect_timeout(cookie)
-    void *cookie;
-{
-    struct ssh_handle *rh = cookie;
-
-    event_release(rh->rs->ev_read);
-    rh->rs->ev_read = NULL;
-    event_release(rh->ev_timeout);
-    rh->ev_timeout = NULL;
-
-    (*rh->fn.connect)(rh->arg, &rh->sech, S_TIMEOUT);
-}
-
-/*
- * Setup to handle new incoming connections
- */
-static void
-ssh_accept(in, out, fn)
-    int in, out;
-    void (*fn) P((security_handle_t *, pkt_t *));
-{
-    struct ssh_conn *rc;
-
-    rc = conn_get("unknown");
-    rc->read = in;
-    rc->write = out;
-    accept_fn = fn;
-    conn_read(rc);
-}
-
-/*
- * Locate an existing connection to the given host, or create a new,
- * unconnected entry if none exists.  The caller is expected to check
- * for the lack of a connection (rc->read == -1) and set one up.
- */
-static struct ssh_conn *
-conn_get(hostname)
-    const char *hostname;
-{
-    struct ssh_conn *rc;
-
-    sshprintf(("%s: ssh: conn_get: %s\n", debug_prefix_time(NULL), hostname));
-
-    for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
-       if (strcasecmp(hostname, rc->hostname) == 0)
-           break;
-    }
-
-    if (rc != NULL) {
-       rc->refcnt++;
-       sshprintf(("%s: ssh: conn_get: exists, refcnt to %s is now %d\n", debug_prefix_time(NULL),
-           rc->hostname, rc->refcnt));
-       return (rc);
-    }
-
-    sshprintf(("%s: ssh: conn_get: creating new handle\n", debug_prefix_time(NULL)));
-    /*
-     * We can't be creating a new handle if we are the client
-     */
-    assert(accept_fn == NULL);
-    rc = alloc(sizeof(*rc));
-    rc->read = rc->write = -1;
-    rc->pid = -1;
-    rc->readbuf.left = 0;
-    rc->readbuf.size = 0;
-    rc->ev_read = NULL;
-    strncpy(rc->hostname, hostname, sizeof(rc->hostname) - 1);
-    rc->hostname[sizeof(rc->hostname) - 1] = '\0';
-    rc->errmsg = NULL;
-    rc->refcnt = 1;
-    rc->handle = -1;
-    connq_append(rc);
-    return (rc);
-}
-
-/*
- * Delete a reference to a connection, and close it if it is the last
- * reference.
- */
-static void
-conn_put(rc)
-    struct ssh_conn *rc;
-{
-    amwait_t status;
-
-    assert(rc->refcnt > 0);
-    --rc->refcnt;
-    sshprintf(("%s: ssh: conn_put: decrementing refcnt for %s to %d\n", debug_prefix_time(NULL),
-       rc->hostname, rc->refcnt));
-    if (rc->refcnt > 0) {
-       return;
-    }
-    sshprintf(("%s: ssh: conn_put: closing connection to %s\n", debug_prefix_time(NULL), rc->hostname));
-    if (rc->read != -1)
-       aclose(rc->read);
-    if (rc->write != -1)
-       aclose(rc->write);
-    if (rc->pid != -1) {
-       waitpid(rc->pid, &status, WNOHANG);
-    }
-    if (rc->ev_read != NULL)
-       event_release(rc->ev_read);
-    if (rc->errmsg != NULL)
-       amfree(rc->errmsg);
-    connq_remove(rc);
-    amfree(rc);
-}
-
-/*
- * Turn on read events for a conn.  Or, increase a ev_read_refcnt if we are
- * already receiving read events.
- */
-static void
-conn_read(rc)
-    struct ssh_conn *rc;
-{
-
-    if (rc->ev_read != NULL) {
-       rc->ev_read_refcnt++;
-       sshprintf(("%s: ssh: conn_read: incremented ev_read_refcnt to %d for %s\n", debug_prefix_time(NULL),
-           rc->ev_read_refcnt, rc->hostname));
-       return;
-    }
-    sshprintf(("%s: ssh: conn_read registering event handler for %s\n", debug_prefix_time(NULL),
-       rc->hostname));
-    rc->ev_read = event_register(rc->read, EV_READFD, conn_read_callback, rc);
-    rc->ev_read_refcnt = 1;
-}
-
-static void
-conn_read_cancel(rc)
-    struct ssh_conn *rc;
-{
-
-    --rc->ev_read_refcnt;
-    sshprintf(("%s: ssh: conn_read_cancel: decremented ev_read_refcnt to %d for %s\n", debug_prefix_time(NULL),
-       rc->ev_read_refcnt, rc->hostname));
-    if(rc->ev_read_refcnt > 0) {
-       return;
-    }
-    sshprintf(("%s: ssh: conn_read_cancel: releasing event handler for %s\n", debug_prefix_time(NULL),
-       rc->hostname));
-    event_release(rc->ev_read);
-    rc->ev_read = NULL;
-}
-
-/*
- * frees a handle allocated by the above
- */
-static void
-ssh_close(inst)
-    void *inst;
-{
-    struct ssh_handle *rh = inst;
-
-    assert(rh != NULL);
-
-    sshprintf(("%s: ssh: closing handle to %s\n", debug_prefix_time(NULL), rh->hostname));
-
-    if (rh->rs != NULL) {
-       /* This may be null if we get here on an error */
-       ssh_recvpkt_cancel(rh);
-       security_stream_close(&rh->rs->secstr);
-    }
-    /* keep us from getting here again */
-    rh->sech.driver = NULL;
-    amfree(rh);
-}
-
 /*
  * Forks a ssh to the host listed in rc->hostname
  * Returns negative on error, with an errmsg in rc->errmsg.
  */
 static int
-runssh(rc)
-    struct ssh_conn *rc;
+runssh(
+    struct tcp_conn *  rc,
+    const char *       amandad_path,
+    const char *       client_username,
+    const char *       ssh_keys)
 {
     int rpipe[2], wpipe[2];
-    char *amandad_path;
+    char *xamandad_path = (char *)amandad_path;
+    char *xclient_username = (char *)client_username;
+    char *xssh_keys = (char *)ssh_keys;
 
+    memset(rpipe, -1, SIZEOF(rpipe));
+    memset(wpipe, -1, SIZEOF(wpipe));
     if (pipe(rpipe) < 0 || pipe(wpipe) < 0) {
-       rc->errmsg = newvstralloc("pipe: ", strerror(errno), NULL);
+       rc->errmsg = newvstralloc(rc->errmsg, "pipe: ", strerror(errno), NULL);
        return (-1);
     }
+
     switch (rc->pid = fork()) {
     case -1:
-       rc->errmsg = newvstralloc("fork: ", strerror(errno), NULL);
+       rc->errmsg = newvstralloc(rc->errmsg, "fork: ", strerror(errno), NULL);
        aclose(rpipe[0]);
        aclose(rpipe[1]);
        aclose(wpipe[0]);
@@ -516,7 +239,6 @@ runssh(rc)
     case 0:
        dup2(wpipe[0], 0);
        dup2(rpipe[1], 1);
-       dup2(rpipe[1], 2);
        break;
     default:
        rc->read = rpipe[0];
@@ -528,712 +250,25 @@ runssh(rc)
 
     safe_fd(-1, 0);
 
-    amandad_path = vstralloc(libexecdir, "/", "amandad", versionsuffix(),
-       NULL);
-    execlp(SSH_PATH, SSH_PATH, SSH_ARGS, rc->hostname, amandad_path,
-       "-auth=ssh", NULL);
-    error("error: couldn't exec %s: %s", SSH_PATH, strerror(errno));
-
-    /* should nerver go here, shut up compiler warning */
-    return(-1);
-}
-
-/*
- * Transmit a packet.
- */
-static int
-ssh_sendpkt(cookie, pkt)
-    void *cookie;
-    pkt_t *pkt;
-{
-    char buf[sizeof(pkt_t)];
-    struct ssh_handle *rh = cookie;
-    size_t len;
-
-    assert(rh != NULL);
-    assert(pkt != NULL);
-
-    sshprintf(("%s: ssh: sendpkt: enter\n", debug_prefix_time(NULL)));
-
-    len = strlen(pkt->body) + 2;
-    buf[0] = (char)pkt->type;
-    strcpy(&buf[1], pkt->body);
-
-    sshprintf(("%s: ssh: sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n", debug_prefix_time(NULL),
-       pkt_type2str(pkt->type), pkt->type, strlen(pkt->body), pkt->body));
-
-    if (ssh_stream_write(rh->rs, buf, len) < 0) {
-       security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
-       return (-1);
-    }
-    return (0);
-}
-
-/*
- * Set up to receive a packet asyncronously, and call back when
- * it has been read.
- */
-static void
-ssh_recvpkt(cookie, fn, arg, timeout)
-    void *cookie, *arg;
-    void (*fn) P((void *, pkt_t *, security_status_t));
-    int timeout;
-{
-    struct ssh_handle *rh = cookie;
-
-    assert(rh != NULL);
-
-    sshprintf(("%s: ssh: recvpkt registered for %s\n", debug_prefix_time(NULL), rh->hostname));
-
-    /*
-     * Reset any pending timeout on this handle
-     */
-    if (rh->ev_timeout != NULL)
-       event_release(rh->ev_timeout);
-
-    /*
-     * Negative timeouts mean no timeout
-     */
-    if (timeout < 0)
-       rh->ev_timeout = NULL;
-    else
-       rh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, rh);
-
-    rh->fn.recvpkt = fn;
-    rh->arg = arg;
-    ssh_stream_read(rh->rs, recvpkt_callback, rh);
-}
-
-/*
- * Remove a async receive request from the queue
- */
-static void
-ssh_recvpkt_cancel(cookie)
-    void *cookie;
-{
-    struct ssh_handle *rh = cookie;
-
-    sshprintf(("%s: ssh: cancelling recvpkt for %s\n", debug_prefix_time(NULL), rh->hostname));
-
-    assert(rh != NULL);
-
-    ssh_stream_read_cancel(rh->rs);
-    if (rh->ev_timeout != NULL) {
-       event_release(rh->ev_timeout);
-       rh->ev_timeout = NULL;
-    }
-}
-
-/*
- * This is called when a handle is woken up because data read off of the
- * net is for it.
- */
-static void
-recvpkt_callback(cookie, buf, bufsize)
-    void *cookie, *buf;
-    ssize_t bufsize;
-{
-    pkt_t pkt;
-    struct ssh_handle *rh = cookie;
-
-    assert(rh != NULL);
-
-    /*
-     * We need to cancel the recvpkt request before calling
-     * the callback because the callback may reschedule us.
-     */
-    ssh_recvpkt_cancel(rh);
-
-    switch (bufsize) {
-    case 0:
-       security_seterror(&rh->sech,
-           "EOF on read from %s", rh->hostname);
-       (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
-       return;
-    case -1:
-       security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
-       (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
-       return;
-    default:
-       break;
-    }
-
-    parse_pkt(&pkt, buf, bufsize);
-    sshprintf(("%s: ssh: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n", debug_prefix_time(NULL),
-       pkt_type2str(pkt.type), pkt.type, rh->hostname, pkt.body));
-    (*rh->fn.recvpkt)(rh->arg, &pkt, S_OK);
-}
-
-/*
- * This is called when a handle times out before receiving a packet.
- */
-static void
-recvpkt_timeout(cookie)
-    void *cookie;
-{
-    struct ssh_handle *rh = cookie;
-
-    assert(rh != NULL);
-
-    sshprintf(("%s: ssh: recvpkt timeout for %s\n", debug_prefix_time(NULL), rh->hostname));
-
-    ssh_recvpkt_cancel(rh);
-    (*rh->fn.recvpkt)(rh->arg, NULL, S_TIMEOUT);
-}
-
-/*
- * Create the server end of a stream.  For ssh, this means setup a stream
- * object and allocate a new handle for it.
- */
-static void *
-ssh_stream_server(h)
-    void *h;
-{
-    struct ssh_handle *rh = h;
-    struct ssh_stream *rs;
-
-    assert(rh != NULL);
-
-    rs = alloc(sizeof(*rs));
-    security_streaminit(&rs->secstr, &ssh_security_driver);
-    rs->rc = conn_get(rh->hostname);
-    /*
-     * Stream should already be setup!
-     */
-    if (rs->rc->read < 0) {
-       conn_put(rs->rc);
-       amfree(rs);
-       security_seterror(&rh->sech, "lost connection to %s", rh->hostname);
-       return (NULL);
-    }
-    rh->hostname = rs->rc->hostname;
-    /*
-     * so as not to conflict with the amanda server's handle numbers,
-     * we start at 5000 and work down
-     */
-    rs->handle = 5000 - newhandle++;
-    rs->ev_read = NULL;
-    sshprintf(("%s: ssh: stream_server: created stream %d\n", debug_prefix_time(NULL), rs->handle));
-    return (rs);
-}
-
-/*
- * Accept an incoming connection on a stream_server socket
- * Nothing needed for ssh.
- */
-static int
-ssh_stream_accept(s)
-    void *s;
-{
-
-    return (0);
-}
-
-/*
- * Return a connected stream.  For ssh, this means setup a stream
- * with the supplied handle.
- */
-static void *
-ssh_stream_client(h, id)
-    void *h;
-    int id;
-{
-    struct ssh_handle *rh = h;
-    struct ssh_stream *rs;
-
-    assert(rh != NULL);
-
-    if (id <= 0) {
-       security_seterror(&rh->sech,
-           "%d: invalid security stream id", id);
-       return (NULL);
-    }
-
-    rs = alloc(sizeof(*rs));
-    security_streaminit(&rs->secstr, &ssh_security_driver);
-    rs->handle = id;
-    rs->ev_read = NULL;
-    rs->rc = conn_get(rh->hostname);
-
-    sshprintf(("%s: ssh: stream_client: connected to stream %d\n", debug_prefix_time(NULL), id));
-
-    return (rs);
-}
-
-/*
- * Close and unallocate resources for a stream.
- */
-static void
-ssh_stream_close(s)
-    void *s;
-{
-    struct ssh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    sshprintf(("%s: ssh: stream_close: closing stream %d\n", debug_prefix_time(NULL), rs->handle));
-
-    ssh_stream_read_cancel(rs);
-    conn_put(rs->rc);
-    amfree(rs);
-}
-
-/*
- * Authenticate a stream
- * Nothing needed for ssh.  The connection is authenticated by sshd
- * on startup.
- */
-static int
-ssh_stream_auth(s)
-    void *s;
-{
-
-    return (0);
-}
-
-/*
- * Returns the stream id for this stream.  This is just the local
- * port.
- */
-static int
-ssh_stream_id(s)
-    void *s;
-{
-    struct ssh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    return (rs->handle);
-}
-
-/*
- * Write a chunk of data to a stream.  Blocks until completion.
- */
-static int
-ssh_stream_write(s, buf, size)
-    void *s;
-    const void *buf;
-    size_t size;
-{
-    struct ssh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    sshprintf(("%s: ssh: stream_write: writing %d bytes to %s:%d\n", debug_prefix_time(NULL), size,
-       rs->rc->hostname, rs->handle));
-
-    if (send_token(rs->rc, rs->handle, buf, size) < 0) {
-       security_stream_seterror(&rs->secstr, rs->rc->errmsg);
-       return (-1);
-    }
-    return (0);
-}
-
-/*
- * Submit a request to read some data.  Calls back with the given
- * function and arg when completed.
- */
-static void
-ssh_stream_read(s, fn, arg)
-    void *s, *arg;
-    void (*fn) P((void *, void *, ssize_t));
-{
-    struct ssh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    /*
-     * Only one read request can be active per stream.
-     */
-    if (rs->ev_read == NULL) {
-       rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
-           stream_read_callback, rs);
-       conn_read(rs->rc);
-    }
-    rs->fn = fn;
-    rs->arg = arg;
-}
-
-/*
- * Cancel a previous stream read request.  It's ok if we didn't have a read
- * scheduled.
- */
-static void
-ssh_stream_read_cancel(s)
-    void *s;
-{
-    struct ssh_stream *rs = s;
-
-    assert(rs != NULL);
-
-    if (rs->ev_read != NULL) {
-       event_release(rs->ev_read);
-       rs->ev_read = NULL;
-       conn_read_cancel(rs->rc);
-    }
-}
-
-/*
- * Callback for ssh_stream_read
- */
-static void
-stream_read_callback(arg)
-    void *arg;
-{
-    struct ssh_stream *rs = arg;
-    assert(rs != NULL);
-
-    sshprintf(("%s: ssh: stream_read_callback: handle %d\n", debug_prefix_time(NULL), rs->handle));
-
-    /*
-     * Make sure this was for us.  If it was, then blow away the handle
-     * so it doesn't get claimed twice.  Otherwise, leave it alone.
-     *
-     * If the handle is EOF, pass that up to our callback.
-     */
-    if (rs->rc->handle == rs->handle) {
-       sshprintf(("%s: ssh: stream_read_callback: it was for us\n", debug_prefix_time(NULL)));
-       rs->rc->handle = H_TAKEN;
-    } else if (rs->rc->handle != H_EOF) {
-       sshprintf(("%s: ssh: stream_read_callback: not for us\n", debug_prefix_time(NULL)));
-       return;
-    }
-
-    /*
-     * Remove the event first, and then call the callback.
-     * We remove it first because we don't want to get in their
-     * way if they reschedule it.
-     */
-    ssh_stream_read_cancel(rs);
-
-    if (rs->rc->pktlen == 0) {
-       sshprintf(("%s: ssh: stream_read_callback: EOF\n", debug_prefix_time(NULL)));
-       (*rs->fn)(rs->arg, NULL, 0);
-       return;
-    }
-    sshprintf(("%s: ssh: stream_read_callback: read %ld bytes from %s:%d\n", debug_prefix_time(NULL),
-       rs->rc->pktlen, rs->rc->hostname, rs->handle));
-    (*rs->fn)(rs->arg, rs->rc->pkt, rs->rc->pktlen);
-}
-
-/*
- * The callback for the netfd for the event handler
- * Determines if this packet is for this security handle,
- * and does the real callback if so.
- */
-static void
-conn_read_callback(cookie)
-    void *cookie;
-{
-    struct ssh_conn *rc = cookie;
-    struct ssh_handle *rh;
-    pkt_t pkt;
-    int rval;
-
-    assert(cookie != NULL);
-
-    sshprintf(("%s: ssh: conn_read_callback\n",debug_prefix_time(NULL)));
-
-    /* Read the data off the wire.  If we get errors, shut down. */
-    rval = recv_token(rc, 60);
-    sshprintf(("%s: ssh: conn_read_callback: recv_token returned %d\n", debug_prefix_time(NULL), rval));
-    if (rval <= 0) {
-       rc->pktlen = 0;
-       rc->handle = H_EOF;
-       rval = event_wakeup((event_id_t)rc);
-       sshprintf(("%s: ssh: conn_read_callback: event_wakeup return %d\n", debug_prefix_time(NULL), rval));
-       /* delete our 'accept' reference */
-       if (accept_fn != NULL)
-           conn_put(rc);
-       accept_fn = NULL;
-       return;
-    }
-
-    /* If there are events waiting on this handle, we're done */
-    rval = event_wakeup((event_id_t)rc);
-    sshprintf(("%s: ssh: conn_read_callback: event_wakeup return %d\n", debug_prefix_time(NULL), rval));
-    if (rval > 0)
-       return;
-
-    /* If there is no accept fn registered, then drop the packet */
-    if (accept_fn == NULL)
-       return;
-
-    rh = alloc(sizeof(*rh));
-    security_handleinit(&rh->sech, &ssh_security_driver);
-    rh->hostname = rc->hostname;
-    rh->rs = ssh_stream_client(rh, rc->handle);
-    rh->ev_timeout = NULL;
-
-    sshprintf(("%s: ssh: new connection\n", debug_prefix_time(NULL)));
-    parse_pkt(&pkt, rc->pkt, rc->pktlen);
-    sshprintf(("%s: ssh: calling accept_fn\n", debug_prefix_time(NULL)));
-    (*accept_fn)(&rh->sech, &pkt);
-}
-
-static void
-parse_pkt(pkt, buf, bufsize)
-    pkt_t *pkt;
-    const void *buf;
-    size_t bufsize;
-{
-    const unsigned char *bufp = buf;
-
-    sshprintf(("%s: ssh: parse_pkt: parsing buffer of %d bytes\n", debug_prefix_time(NULL), bufsize));
-
-    pkt->type = (pktype_t)*bufp++;
-    bufsize--;
-
-    if (bufsize == 0) {
-       pkt->body[0] = '\0';
-    } else {
-       if (bufsize > sizeof(pkt->body) - 1)
-           bufsize = sizeof(pkt->body) - 1;
-       memcpy(pkt->body, bufp, bufsize);
-       pkt->body[sizeof(pkt->body) - 1] = '\0';
-    }
-
-    sshprintf(("%s: ssh: parse_pkt: %s (%d): \"%s\"\n", debug_prefix_time(NULL), pkt_type2str(pkt->type),
-       pkt->type, pkt->body));
-}
-
-
-/*
- * Transmits a chunk of data over a ssh_handle, adding
- * the necessary headers to allow the remote end to decode it.
- */
-static int
-send_token(rc, handle, buf, len)
-    struct ssh_conn *rc;
-    int handle;
-    const void *buf;
-    size_t len;
-{
-    unsigned int netlength, nethandle;
-    struct iovec iov[3];
-
-    sshprintf(("%s: ssh: send_token: handle %d writing %d bytes to %s\n", debug_prefix_time(NULL), handle, len,
-       rc->hostname));
-
-    assert(sizeof(netlength) == 4);
-
-    /*
-     * Format is:
-     *   32 bit length (network byte order)
-     *   32 bit handle (network byte order)
-     *   data
-     */
-    netlength = htonl(len);
-    iov[0].iov_base = (void *)&netlength;
-    iov[0].iov_len = sizeof(netlength);
-
-    nethandle = htonl(handle);
-    iov[1].iov_base = (void *)&nethandle;
-    iov[1].iov_len = sizeof(nethandle);
-
-    iov[2].iov_base = (void *)buf;
-    iov[2].iov_len = len;
-
-    if (net_writev(rc->write, iov, 3) < 0) {
-       rc->errmsg = newvstralloc(rc->errmsg, "ssh write error to ",
-           rc->hostname, ": ", strerror(errno), NULL);
-       return (-1);
+    if(!xamandad_path || strlen(xamandad_path) <= 1) 
+       xamandad_path = vstralloc(libexecdir, "/", "amandad",
+                                versionsuffix(), NULL);
+    if(!xclient_username || strlen(xclient_username) <= 1)
+       xclient_username = CLIENT_LOGIN;
+    if(!ssh_keys || strlen(ssh_keys) <= 1) {
+       execlp(SSH_PATH, SSH_PATH, SSH_ARGS, "-l", xclient_username,
+              rc->hostname, xamandad_path, "-auth=ssh", "amdump", "amindexd",
+              "amidxtaped", (char *)NULL);
     }
-    return (0);
-}
-
-static int
-recv_token(rc, timeout)
-    struct ssh_conn *rc;
-    int timeout;
-{
-    unsigned int netint;
-
-    assert(sizeof(netint) == 4);
-
-    assert(rc->read >= 0);
-
-    sshprintf(("%s: ssh: recv_token: reading from %s\n", debug_prefix_time(NULL), rc->hostname));
-
-    switch (net_read(rc, &netint, sizeof(netint), timeout)) {
-    case -1:
-       rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
-           NULL);
-       sshprintf(("%s: ssh: recv_token: A return(-1)\n", debug_prefix_time(NULL)));
-       return (-1);
-    case 0:
-       rc->pktlen = 0;
-       sshprintf(("%s: ssh: recv_token: A return(0)\n", debug_prefix_time(NULL)));
-       return (0);
-    default:
-       break;
+    else {
+       execlp(SSH_PATH, SSH_PATH, SSH_ARGS, "-l", xclient_username,
+              "-i", xssh_keys, rc->hostname, xamandad_path, "-auth=ssh",
+              "amdump", "amindexd", "amidxtaped", (char *)NULL);
     }
-    rc->pktlen = ntohl(netint);
-    if (rc->pktlen > sizeof(rc->pkt)) {
-       rc->errmsg = newstralloc(rc->errmsg, "recv error: huge packet");
-       sshprintf(("%s: ssh: recv_token: B return(-1)\n", debug_prefix_time(NULL)));
-       return (-1);
-    }
-
-    switch (net_read(rc, &netint, sizeof(netint), timeout)) {
-    case -1:
-       rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
-           NULL);
-       sshprintf(("%s: ssh: recv_token: C return(-1)\n", debug_prefix_time(NULL)));
-       return (-1);
-    case 0:
-       rc->pktlen = 0;
-       sshprintf(("%s: ssh: recv_token: D return(0)\n", debug_prefix_time(NULL)));
-       return (0);
-    default:
-       break;
-    }
-    rc->handle = ntohl(netint);
-
-    switch (net_read(rc, rc->pkt, rc->pktlen, timeout)) {
-    case -1:
-       rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
-           NULL);
-       sshprintf(("%s: ssh: recv_token: E return(-1)\n", debug_prefix_time(NULL)));
-       return (-1);
-    case 0:
-       rc->pktlen = 0;
-       break;
-    default:
-       break;
-    }
-
-    sshprintf(("%s: ssh: recv_token: read %ld bytes from %s\n", debug_prefix_time(NULL), rc->pktlen,
-       rc->hostname));
-    sshprintf(("%s: ssh: recv_token: end %d\n", debug_prefix_time(NULL),rc->pktlen));
-    return (rc->pktlen);
-}
-
-/*
- * Writes out the entire iovec
- */
-static int
-net_writev(fd, iov, iovcnt)
-    int fd, iovcnt;
-    struct iovec *iov;
-{
-    int delta, n, total;
-
-    assert(iov != NULL);
-
-    total = 0;
-    while (iovcnt > 0) {
-       /*
-        * Write the iovec
-        */
-       total += n = writev(fd, iov, iovcnt);
-       if (n < 0)
-           return (-1);
-       if (n == 0) {
-           errno = EIO;
-           return (-1);
-       }
-       /*
-        * Iterate through each iov.  Figure out what we still need
-        * to write out.
-        */
-       for (; n > 0; iovcnt--, iov++) {
-           /* 'delta' is the bytes written from this iovec */
-           delta = n < iov->iov_len ? n : iov->iov_len;
-           /* subtract from the total num bytes written */
-           n -= delta;
-           assert(n >= 0);
-           /* subtract from this iovec */
-           iov->iov_len -= delta;
-           iov->iov_base = (char *)iov->iov_base + delta;
-           /* if this iovec isn't empty, run the writev again */
-           if (iov->iov_len > 0)
-               break;
-       }
-    }
-    return (total);
-}
-
-/*
- * Like read(), but waits until the entire buffer has been filled.
- */
-static ssize_t
-net_read(rc, vbuf, origsize, timeout)
-    struct ssh_conn *rc;
-    void *vbuf;
-    size_t origsize;
-    int timeout;
-{
-    char *buf = vbuf, *off;    /* ptr arith */
-    int nread;
-    size_t size = origsize;
-
-    sshprintf(("%s: ssh: net_read: begin %d\n", debug_prefix_time(NULL), origsize));
-    while (size > 0) {
-       sshprintf(("%s: ssh: net_read: while %d\n", debug_prefix_time(NULL), size));
-       if (rc->readbuf.left == 0) {
-           if (net_read_fillbuf(rc, timeout, size) < 0) {
-               sshprintf(("%s: ssh: net_read: end retrun(-1)\n", debug_prefix_time(NULL)));
-               return (-1);
-           }
-           if (rc->readbuf.size == 0) {
-               sshprintf(("%s: ssh: net_read: end retrun(0)\n", debug_prefix_time(NULL)));
-               return (0);
-           }
-       }
-       nread = min(rc->readbuf.left, size);
-       off = rc->readbuf.buf + rc->readbuf.size - rc->readbuf.left;
-       memcpy(buf, off, nread);
-
-       buf += nread;
-       size -= nread;
-       rc->readbuf.left -= nread;
-    }
-    sshprintf(("%s: ssh: net_read: end %d\n", debug_prefix_time(NULL), origsize));
-    return ((ssize_t)origsize);
-}
-
-/*
- * net_read likes to do a lot of little reads.  Buffer it.
- */
-static int
-net_read_fillbuf(rc, timeout, size)
-    struct ssh_conn *rc;
-    int timeout;
-    int size;
-{
-    fd_set readfds;
-    struct timeval tv;
-    if(size > sizeof(rc->readbuf.buf)) size = sizeof(rc->readbuf.buf);
+    error("error: couldn't exec %s: %s", SSH_PATH, strerror(errno));
 
-    sshprintf(("%s: ssh: net_read_fillbuf: begin\n", debug_prefix_time(NULL)));
-    FD_ZERO(&readfds);
-    FD_SET(rc->read, &readfds);
-    tv.tv_sec = timeout;
-    tv.tv_usec = 0;
-    switch (select(rc->read + 1, &readfds, NULL, NULL, &tv)) {
-    case 0:
-       errno = ETIMEDOUT;
-       /* FALLTHROUGH */
-    case -1:
-       sshprintf(("%s: ssh: net_read_fillbuf: case -1\n", debug_prefix_time(NULL)));
-       return (-1);
-    case 1:
-       sshprintf(("%s: ssh: net_read_fillbuf: case 1\n", debug_prefix_time(NULL)));
-       assert(FD_ISSET(rc->read, &readfds));
-       break;
-    default:
-       sshprintf(("%s: ssh: net_read_fillbuf: case default\n", debug_prefix_time(NULL)));
-       assert(0);
-       break;
-    }
-    rc->readbuf.left = 0;
-    rc->readbuf.size = read(rc->read, rc->readbuf.buf, size);
-    if (rc->readbuf.size < 0)
-       return (-1);
-    rc->readbuf.left = rc->readbuf.size;
-    sshprintf(("%s: ssh: net_read_fillbuf: end %d\n", debug_prefix_time(NULL),rc->readbuf.size));
-    return (0);
+    /* should never go here, shut up compiler warning */
+    return(-1);
 }
 
 #endif /* SSH_SECURITY */
index 5f5270feebd28e7340b045e09c95603c34d9b661..9e1d3cd1932cd190f5a3bc766093c558a9745f83 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: statfs.c,v 1.13 2005/09/30 19:13:27 martinea Exp $
+ * $Id: statfs.c,v 1.16 2006/08/24 17:05:35 martinea Exp $
  *
  * a generic statfs-like routine
  */
@@ -98,7 +98,7 @@
 #    define STATFS_FAVAIL(buf) (buf).f_ffree
 #    define STATFS_FFREE(buf)  (buf).f_ffree
 #    define STATFS_SCALE(buf)  (buf).f_bsize
-#    define STATFS(path, buffer)       statfs(path, &buffer, sizeof(STATFS_STRUCT), 0)
+#    define STATFS(path, buffer)       statfs(path, &buffer, SIZEOF(STATFS_STRUCT), 0)
 #   else
 #    if HAVE_SYS_MOUNT_H
 /*
 #     define STATFS_SCALE(buf) (buf).f_bsize
 #     define STATFS(path, buffer)      statfs(path, &buffer)
 #     ifdef STATFS_OSF1
-#      define STATFS(path, buffer)     statfs(path, &buffer, sizeof(STATFS_STRUCT))
+#      define STATFS(path, buffer)     statfs(path, &buffer, SIZEOF(STATFS_STRUCT))
 #     endif
 #    endif
 #   endif
 # endif
 #endif
 
-#define scale(r,s)     ( (r) == -1? -1 : (int)((r)*(double)(s)/1024.0) )
 
-int get_fs_stats(dir, sp)
-char *dir;
-generic_fs_stats_t *sp;
+off_t scale(off_t r, off_t s);
+
+off_t
+scale(
+    off_t r,
+    off_t s)
+{
+    if (r == (off_t)-1)
+       return (off_t)-1;
+    return r*(s/(off_t)1024);
+}
+
+int
+get_fs_stats(
+    char *             dir,
+    generic_fs_stats_t *sp)
 {
     STATFS_STRUCT statbuf;
 
@@ -140,15 +152,18 @@ generic_fs_stats_t *sp;
 
     /* total, avail, free: converted to kbytes, rounded down */
 
-    sp->total = scale(STATFS_TOTAL(statbuf), STATFS_SCALE(statbuf));
-    sp->avail = scale(STATFS_AVAIL(statbuf), STATFS_SCALE(statbuf));
-    sp->free  = scale(STATFS_FREE(statbuf),  STATFS_SCALE(statbuf));
+    sp->total = scale((off_t)STATFS_TOTAL(statbuf),
+                     (off_t)STATFS_SCALE(statbuf));
+    sp->avail = scale((off_t)STATFS_AVAIL(statbuf),
+                     (off_t)STATFS_SCALE(statbuf));
+    sp->free  = scale((off_t)STATFS_FREE(statbuf),
+                     (off_t)STATFS_SCALE(statbuf));
 
     /* inode stats */
 
-    sp->files  = STATFS_FILES(statbuf);
-    sp->favail = STATFS_FAVAIL(statbuf);
-    sp->ffree  = STATFS_FFREE(statbuf);
+    sp->files  = (off_t)STATFS_FILES(statbuf);
+    sp->favail = (off_t)STATFS_FAVAIL(statbuf);
+    sp->ffree  = (off_t)STATFS_FFREE(statbuf);
 
     return 0;
 }
@@ -156,9 +171,10 @@ generic_fs_stats_t *sp;
 #ifdef TEST
 /* ----- test scaffolding ----- */
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     generic_fs_stats_t statbuf;
 
@@ -166,6 +182,8 @@ char **argv;
 
     set_pname(argv[0]);
 
+    dbopen(NULL);
+
     if(argc < 2) {
        fprintf(stderr, "Usage: %s files ...\n", get_pname());
        return 1;
index 8260d6cfd048767f8dbd86f3a9cb62d61a087879..7252e8f3a6be26f20b9f2a4241bb1091fa61a944 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: statfs.h,v 1.3 1998/07/04 00:18:58 oliva Exp $
+ * $Id: statfs.h,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
  *
  * interface to statfs module
  */
+#ifndef STATFS_H
+#define STATFS_H
+
 #include "amanda.h"
 
 typedef struct generic_fs_stats {
-    long total;                /* total KB in filesystem */
-    long avail;                /* KB available to non-superuser */
-    long free;         /* KB free for superuser */
+    off_t total;               /* total KB in filesystem */
+    off_t avail;               /* KB available to non-superuser */
+    off_t free;                /* KB free for superuser */
 
-    long files;                /* total # of files in filesystem */
-    long favail;       /* # files avail for non-superuser */
-    long ffree;                /* # files free for superuser */
+    off_t files;               /* total # of files in filesystem */
+    off_t favail;              /* # files avail for non-superuser */
+    off_t ffree;               /* # files free for superuser */
 } generic_fs_stats_t;
 
-int get_fs_stats P((char *dir, generic_fs_stats_t *sp));
+int get_fs_stats(char *dir, generic_fs_stats_t *sp);
+
+#endif /* !STATFS_H */
index b3dd1fab85951b0ce7e95c88265ce60837f6a305..ac5f79f0948607ea52230906bf56edb202d59750 100644 (file)
@@ -1,21 +1,13 @@
 /* Provided by Michael Schmitz <mschmitz@sema.de>; public domain? */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
+#include "amanda.h"
 
 /* Compare S1 and S2 ignoring case, returning less than,
    equal to or greater than zero if S1 is lexicographically
    less than, equal to or greater than S2.  */
 int
-strcasecmp(s1, s2)
-      const char *s1;
-      const char *s2;
+strcasecmp(
+    const char *s1,
+    const char *s2)
 {
   register const unsigned char *p1 = (const unsigned char *) s1;
   register const unsigned char *p2 = (const unsigned char *) s2;
@@ -24,11 +16,10 @@ strcasecmp(s1, s2)
   if (p1 == p2)
     return 0;
 
-  do
-    {
+  do {
       c1 = tolower (*p1++);
       c2 = tolower (*p2++);
       if (c1 == '\0' || c2 == '\0' || c1 != c2)
         return c1 - c2;
-    } while ( 1 == 1 );
+  } while ( 1 == 1 );
 }
index b5e24456e7cc64355b77367d064f87dcf198de6b..5d29b19ebd3323236e79b4bb2dbf301aafe30972 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: stream.c,v 1.31 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: stream.c,v 1.39 2006/08/24 01:57:15 paddy_s Exp $
  *
  * functions for managing stream sockets
  */
 #include "util.h"
 
 /* local functions */
-static void try_socksize P((int sock, int which, int size));
+static void try_socksize(int sock, int which, size_t size);
+static int stream_client_internal(const char *hostname, in_port_t port,
+               size_t sendsize, size_t recvsize, in_port_t *localport,
+               int nonblock, int priv);
 
-int stream_server(portp, sendsize, recvsize)
-int *portp;
-int sendsize, recvsize;
+int
+stream_server(
+    in_port_t *portp,
+    size_t sendsize,
+    size_t recvsize,
+    int    priv)
 {
-    int server_socket;
+    int server_socket, retries;
     socklen_t len;
-#ifdef SO_KEEPALIVE
-    int on = 1;
+#if defined(SO_KEEPALIVE) || defined(USE_REUSEADDR)
+    const int on = 1;
     int r;
 #endif
     struct sockaddr_in server;
     int save_errno;
 
-    *portp = -1;                               /* in case we error exit */
+    *portp = USHRT_MAX;                                /* in case we error exit */
     if((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        save_errno = errno;
        dbprintf(("%s: stream_server: socket() failed: %s\n",
@@ -59,7 +65,7 @@ int sendsize, recvsize;
        errno = save_errno;
        return -1;
     }
-    if(server_socket < 0 || server_socket >= FD_SETSIZE) {
+    if(server_socket < 0 || server_socket >= (int)FD_SETSIZE) {
        aclose(server_socket);
        errno = EMFILE;                         /* out of range */
        save_errno = errno;
@@ -69,14 +75,22 @@ int sendsize, recvsize;
        errno = save_errno;
        return -1;
     }
-    memset(&server, 0, sizeof(server));
-    server.sin_family = AF_INET;
+    memset(&server, 0, SIZEOF(server));
+    server.sin_family = (sa_family_t)AF_INET;
     server.sin_addr.s_addr = INADDR_ANY;
 
-    if(sendsize >= 0) 
-        try_socksize(server_socket, SO_SNDBUF, sendsize);
-    if(recvsize >= 0) 
-        try_socksize(server_socket, SO_RCVBUF, recvsize);
+#ifdef USE_REUSEADDR
+    r = setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR,
+       (void *)&on, (socklen_t)sizeof(on));
+    if (r < 0) {
+       dbprintf(("%s: stream_server: setsockopt(SO_REUSEADDR) failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(errno)));
+    }
+#endif
+
+    try_socksize(server_socket, SO_SNDBUF, sendsize);
+    try_socksize(server_socket, SO_RCVBUF, recvsize);
 
     /*
      * If a port range was specified, we try to get a port in that
@@ -89,31 +103,51 @@ int sendsize, recvsize;
      * to get the desired port, and to make sure we return a port that
      * is within the range it requires.
      */
+    for (retries = 0; ; retries++) {
 #ifdef TCPPORTRANGE
-    if (bind_portrange(server_socket, &server, TCPPORTRANGE, "tcp") == 0)
-       goto out;
+       if (bind_portrange(server_socket, &server, TCPPORTRANGE, "tcp") == 0)
+           goto out;
+       dbprintf(("%s: stream_server: Could not bind to port in range: %d - %d.\n",
+                 debug_prefix(NULL), TCPPORTRANGE));
 #endif
 
-    if (bind_portrange(server_socket, &server, 512, IPPORT_RESERVED - 1, "tcp") == 0)
-       goto out;
+       if(priv) {
+           if (bind_portrange(server_socket, &server,
+                          (in_port_t)512, (in_port_t)(IPPORT_RESERVED - 1), "tcp") == 0)
+               goto out;
+           dbprintf(("%s: stream_server: Could not bind to port in range 512 - %d.\n",
+                     debug_prefix(NULL), IPPORT_RESERVED - 1));
+       }
 
-    server.sin_port = INADDR_ANY;
-    if (bind(server_socket, (struct sockaddr *)&server, (socklen_t) sizeof(server)) == -1) {
-       save_errno = errno;
-       dbprintf(("%s: stream_server: bind(INADDR_ANY) failed: %s\n",
+       server.sin_port = INADDR_ANY;
+       if (bind(server_socket, (struct sockaddr *)&server, (socklen_t)sizeof(server)) == 0)
+           goto out;
+       dbprintf(("%s: stream_server: Could not bind to any port: %s\n",
+                 debug_prefix(NULL), strerror(errno)));
+
+       if (retries >= BIND_CYCLE_RETRIES)
+           break;
+
+       dbprintf(("%s: stream_server: Retrying entire range after 10 second delay.\n",
+                 debug_prefix(NULL)));
+
+       sleep(15);
+    }
+
+    save_errno = errno;
+    dbprintf(("%s: stream_server: bind(INADDR_ANY) failed: %s\n",
                  debug_prefix(NULL),
                  strerror(save_errno)));
-       aclose(server_socket);
-       errno = save_errno;
-       return -1;
-    }
+    aclose(server_socket);
+    errno = save_errno;
+    return -1;
 
 out:
     listen(server_socket, 1);
 
     /* find out what port was actually used */
 
-    len = sizeof(server);
+    len = SIZEOF(server);
     if(getsockname(server_socket, (struct sockaddr *)&server, &len) == -1) {
        save_errno = errno;
        dbprintf(("%s: stream_server: getsockname() failed: %s\n",
@@ -138,7 +172,7 @@ out:
     }
 #endif
 
-    *portp = (int) ntohs(server.sin_port);
+    *portp = (in_port_t)ntohs(server.sin_port);
     dbprintf(("%s: stream_server: waiting for connection: %s.%d\n",
              debug_prefix_time(NULL),
              inet_ntoa(server.sin_addr),
@@ -147,31 +181,25 @@ out:
 }
 
 static int
-stream_client_internal(hostname,
-                      port,
-                      sendsize,
-                      recvsize,
-                      localport,
-                      nonblock,
-                      priv)
-    const char *hostname;
-    int port, sendsize, recvsize, *localport, nonblock, priv;
+stream_client_internal(
+    const char *hostname,
+    in_port_t port,
+    size_t sendsize,
+    size_t recvsize,
+    in_port_t *localport,
+    int nonblock,
+    int priv)
 {
-    int client_socket;
-    socklen_t len;
-#ifdef SO_KEEPALIVE
-    int on = 1;
-    int r;
-#endif
     struct sockaddr_in svaddr, claddr;
     struct hostent *hostp;
     int save_errno;
     char *f;
+    int client_socket;
 
     f = priv ? "stream_client_privileged" : "stream_client";
 
     if((hostp = gethostbyname(hostname)) == NULL) {
-       save_errno = errno;
+       save_errno = EHOSTUNREACH;
        dbprintf(("%s: %s: gethostbyname(%s) failed\n",
                  debug_prefix(NULL),
                  f,
@@ -180,43 +208,14 @@ stream_client_internal(hostname,
        return -1;
     }
 
-    memset(&svaddr, 0, sizeof(svaddr));
-    svaddr.sin_family = AF_INET;
-    svaddr.sin_port = htons(port);
-    memcpy(&svaddr.sin_addr, hostp->h_addr, hostp->h_length);
+    memset(&svaddr, 0, SIZEOF(svaddr));
+    svaddr.sin_family = (sa_family_t)AF_INET;
+    svaddr.sin_port = (in_port_t)htons(port);
+    memcpy(&svaddr.sin_addr, hostp->h_addr, (size_t)hostp->h_length);
 
-    if((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-       save_errno = errno;
-       dbprintf(("%s: %s: socket() failed: %s\n",
-                 debug_prefix(NULL),
-                 f,
-                 strerror(save_errno)));
-       errno = save_errno;
-       return -1;
-    }
-    if(client_socket < 0 || client_socket >= FD_SETSIZE) {
-       aclose(client_socket);
-       errno = EMFILE;                         /* out of range */
-       return -1;
-    }
 
-#ifdef SO_KEEPALIVE
-    r = setsockopt(client_socket, SOL_SOCKET, SO_KEEPALIVE,
-       (void *)&on, sizeof(on));
-    if(r == -1) {
-       save_errno = errno;
-       dbprintf(("%s: %s: setsockopt() failed: %s\n",
-                 debug_prefix(NULL),
-                 f,
-                 strerror(save_errno)));
-        aclose(client_socket);
-       errno = save_errno;
-        return -1;
-    }
-#endif
-
-    memset(&claddr, 0, sizeof(claddr));
-    claddr.sin_family = AF_INET;
+    memset(&claddr, 0, SIZEOF(claddr));
+    claddr.sin_family = (sa_family_t)AF_INET;
     claddr.sin_addr.s_addr = INADDR_ANY;
 
     /*
@@ -230,104 +229,68 @@ stream_client_internal(hostname,
      * is within the range it requires.
      */
     if (priv) {
-       int b;
-
-       b = bind_portrange(client_socket, &claddr, 512, IPPORT_RESERVED - 1, "tcp");
-       if (b == 0) {
-           goto out;                           /* got what we wanted */
-       }
-       save_errno = errno;
-       dbprintf(("%s: %s: bind(IPPORT_RESERVED) failed: %s\n",
-                 debug_prefix(NULL),
-                 f,
-                 strerror(save_errno)));
-       aclose(client_socket);
-       errno = save_errno;
-       return -1;
+#ifdef LOW_TCPPORTRANGE
+       client_socket = connect_portrange(&claddr, LOW_TCPPORTRANGE,
+                                          "tcp", &svaddr, nonblock);
+#else
+       client_socket = connect_portrange(&claddr, (socklen_t)512,
+                                         (socklen_t)(IPPORT_RESERVED - 1),
+                                          "tcp", &svaddr, nonblock);
+#endif
+                                         
+       if (client_socket > 0)
+           goto out;
+
+#ifdef LOW_TCPPORTRANGE
+       dbprintf((
+               "%s: stream_client: Could not bind to port in range %d-%d.\n",
+               debug_prefix(NULL), LOW_TCPPORTRANGE));
+#else
+       dbprintf((
+               "%s: stream_client: Could not bind to port in range 512-%d.\n",
+               debug_prefix(NULL), IPPORT_RESERVED - 1));
+#endif
     }
 
 #ifdef TCPPORTRANGE
-    if (bind_portrange(client_socket, &claddr, TCPPORTRANGE, "tcp") == 0)
+    client_socket = connect_portrange(&claddr, TCPPORTRANGE,
+                                      "tcp", &svaddr, nonblock);
+    if(client_socket > 0)
        goto out;
-#endif
-
-    claddr.sin_port = INADDR_ANY;
-    if (bind(client_socket, (struct sockaddr *)&claddr, sizeof(claddr)) == -1) {
-       save_errno = errno;
-       dbprintf(("%s: %s: bind(INADDR_ANY) failed: %s\n",
-                 debug_prefix(NULL),
-                 f,
-                 strerror(save_errno)));
-       aclose(client_socket);
-       errno = save_errno;
-       return -1;
-    }
 
-out:
-
-    /* find out what port was actually used */
-
-    len = sizeof(claddr);
-    if(getsockname(client_socket, (struct sockaddr *)&claddr, &len) == -1) {
-       save_errno = errno;
-       dbprintf(("%s: %s: getsockname() failed: %s\n",
-                 debug_prefix(NULL),
-                 f,
-                 strerror(save_errno)));
-       aclose(client_socket);
-       errno = save_errno;
-       return -1;
-    }
+    dbprintf(("%s: stream_client: Could not bind to port in range %d - %d.\n",
+             debug_prefix(NULL), TCPPORTRANGE));
+#endif
 
-    if (nonblock)
-       fcntl(client_socket, F_SETFL,
-           fcntl(client_socket, F_GETFL, 0)|O_NONBLOCK);
+    client_socket = connect_portrange(&claddr, (socklen_t)(IPPORT_RESERVED+1),
+                                     (socklen_t)(65535),
+                                      "tcp", &svaddr, nonblock);
 
-    if(connect(client_socket, (struct sockaddr *)&svaddr, sizeof(svaddr))
-       == -1 && !nonblock) {
-       save_errno = errno;
-       dbprintf(("%s: %s: connect to %s.%d failed: %s\n",
-                 debug_prefix_time(NULL),
-                 f,
-                 inet_ntoa(svaddr.sin_addr),
-                 ntohs(svaddr.sin_port),
-                 strerror(save_errno)));
-       aclose(client_socket);
-       errno = save_errno;
-       return -1;
-    }
+    if(client_socket > 0)
+       goto out;
 
-    dbprintf(("%s: %s: connected to %s.%d\n",
-             debug_prefix_time(NULL),
-             f,
-             inet_ntoa(svaddr.sin_addr),
-             ntohs(svaddr.sin_port)));
-    dbprintf(("%s: %s: our side is %s.%d\n",
-             debug_prefix(NULL),
-             f,
-             inet_ntoa(claddr.sin_addr),
-             ntohs(claddr.sin_port)));
-
-    if(sendsize >= 0) 
-       try_socksize(client_socket, SO_SNDBUF, sendsize);
-    if(recvsize >= 0) 
-       try_socksize(client_socket, SO_RCVBUF, recvsize);
+    save_errno = errno;
+    dbprintf(("%s: stream_client: Could not bind to any port: %s\n",
+             debug_prefix(NULL), strerror(save_errno)));
+    errno = save_errno;
+    return -1;
 
+out:
+    try_socksize(client_socket, SO_SNDBUF, sendsize);
+    try_socksize(client_socket, SO_RCVBUF, recvsize);
     if (localport != NULL)
-       *localport = ntohs(claddr.sin_port);
-
+       *localport = (in_port_t)ntohs(claddr.sin_port);
     return client_socket;
 }
 
 int
-stream_client_privileged(hostname,
-                        port,
-                        sendsize,
-                        recvsize,
-                        localport,
-                        nonblock)
-    const char *hostname;
-    int port, sendsize, recvsize, *localport, nonblock;
+stream_client_privileged(
+    const char *hostname,
+    in_port_t port,
+    size_t sendsize,
+    size_t recvsize,
+    in_port_t *localport,
+    int nonblock)
 {
     return stream_client_internal(hostname,
                                  port,
@@ -339,9 +302,13 @@ stream_client_privileged(hostname,
 }
 
 int
-stream_client(hostname, port, sendsize, recvsize, localport, nonblock)
-    const char *hostname;
-    int port, sendsize, recvsize, *localport, nonblock;
+stream_client(
+    const char *hostname,
+    in_port_t port,
+    size_t sendsize,
+    size_t recvsize,
+    in_port_t *localport,
+    int nonblock)
 {
     return stream_client_internal(hostname,
                                  port,
@@ -356,62 +323,69 @@ stream_client(hostname, port, sendsize, recvsize, localport, nonblock)
 static struct sockaddr_in addr;
 static socklen_t addrlen;
 
-int stream_accept(server_socket, timeout, sendsize, recvsize)
-int server_socket, timeout, sendsize, recvsize;
+int
+stream_accept(
+    int server_socket,
+    int timeout,
+    size_t sendsize,
+    size_t recvsize)
 {
-    fd_set readset;
+    SELECT_ARG_TYPE readset;
     struct timeval tv;
     int nfound, connected_socket;
     int save_errno;
+    int ntries = 0;
 
     assert(server_socket >= 0);
 
-    tv.tv_sec = timeout;
-    tv.tv_usec = 0;
-    FD_ZERO(&readset);
-    FD_SET(server_socket, &readset);
-    nfound = select(server_socket+1, (SELECT_ARG_TYPE *)&readset, NULL, NULL, &tv);
-    if(nfound <= 0 || !FD_ISSET(server_socket, &readset)) {
-       save_errno = errno;
-       if(nfound < 0) {
-           dbprintf(("%s: stream_accept: select() failed: %s\n",
+    do {
+       ntries++;
+       memset(&tv, 0, SIZEOF(tv));
+       tv.tv_sec = timeout;
+       memset(&readset, 0, SIZEOF(readset));
+       FD_ZERO(&readset);
+       FD_SET(server_socket, &readset);
+       nfound = select(server_socket+1, &readset, NULL, NULL, &tv);
+       if(nfound <= 0 || !FD_ISSET(server_socket, &readset)) {
+           save_errno = errno;
+           if(nfound < 0) {
+               dbprintf(("%s: stream_accept: select() failed: %s\n",
                      debug_prefix_time(NULL),
                      strerror(save_errno)));
-       } else if(nfound == 0) {
-           dbprintf(("%s: stream_accept: timeout after %d second%s\n",
+           } else if(nfound == 0) {
+               dbprintf(("%s: stream_accept: timeout after %d second%s\n",
                      debug_prefix_time(NULL),
                      timeout,
                      (timeout == 1) ? "" : "s"));
-           save_errno = ENOENT;                        /* ??? */
-       } else if (!FD_ISSET(server_socket, &readset)) {
-           int i;
-
-           for(i = 0; i < server_socket + 1; i++) {
-               if(FD_ISSET(i, &readset)) {
-                   dbprintf(("%s: stream_accept: got fd %d instead of %d\n",
+               errno = ENOENT;                 /* ??? */
+               return -1;
+           } else if (!FD_ISSET(server_socket, &readset)) {
+               int i;
+
+               for(i = 0; i < server_socket + 1; i++) {
+                   if(FD_ISSET(i, &readset)) {
+                       dbprintf(("%s: stream_accept: got fd %d instead of %d\n",
                              debug_prefix_time(NULL),
                              i,
                              server_socket));
+                   }
                }
+               save_errno = EBADF;
            }
-           save_errno = EBADF;
-       }
-       errno = save_errno;
-       return -1;
-    }
+           if (ntries > 5) {
+               errno = save_errno;
+               return -1;
+           }
+        }
+    } while (nfound <= 0);
 
     while(1) {
-       addrlen = sizeof(struct sockaddr);
+       addrlen = (socklen_t)sizeof(struct sockaddr);
        connected_socket = accept(server_socket,
                                  (struct sockaddr *)&addr,
                                  &addrlen);
        if(connected_socket < 0) {
-           save_errno = errno;
-           dbprintf(("%s: stream_accept: accept() failed: %s\n",
-                     debug_prefix_time(NULL),
-                     strerror(save_errno)));
-           errno = save_errno;
-           return -1;
+           break;
        }
        dbprintf(("%s: stream_accept: connection from %s.%d\n",
                  debug_prefix_time(NULL),
@@ -421,10 +395,13 @@ int server_socket, timeout, sendsize, recvsize;
         * Make certain we got an inet connection and that it is not
         * from port 20 (a favorite unauthorized entry tool).
         */
-       if(addr.sin_family == AF_INET && ntohs(addr.sin_port) != 20) {
-           break;
+       if((addr.sin_family == (sa_family_t)AF_INET)
+         && (ntohs(addr.sin_port) != (in_port_t)20)) {
+           try_socksize(connected_socket, SO_SNDBUF, sendsize);
+           try_socksize(connected_socket, SO_RCVBUF, recvsize);
+           return connected_socket;
        }
-       if(addr.sin_family != AF_INET) {
+       if(addr.sin_family != (sa_family_t)AF_INET) {
            dbprintf(("%s: family is %d instead of %d(AF_INET): ignored\n",
                      debug_prefix_time(NULL),
                      addr.sin_family,
@@ -438,24 +415,32 @@ int server_socket, timeout, sendsize, recvsize;
        aclose(connected_socket);
     }
 
-    if(sendsize >= 0) 
-       try_socksize(connected_socket, SO_SNDBUF, sendsize);
-    if(recvsize >= 0) 
-       try_socksize(connected_socket, SO_RCVBUF, recvsize);
-
-    return connected_socket;
+    save_errno = errno;
+    dbprintf(("%s: stream_accept: accept() failed: %s\n",
+             debug_prefix_time(NULL),
+             strerror(save_errno)));
+    errno = save_errno;
+    return -1;
 }
 
-static void try_socksize(sock, which, size)
-int sock, which, size;
+static void
+try_socksize(
+    int sock,
+    int which,
+    size_t size)
 {
-    int origsize;
+    size_t origsize;
+
+    if (size == 0)
+       return;
 
     origsize = size;
     /* keep trying, get as big a buffer as possible */
-    while(size > 1024 &&
-         setsockopt(sock, SOL_SOCKET, which, (void *) &size, sizeof(int)) < 0)
+    while((size > 1024) &&
+         (setsockopt(sock, SOL_SOCKET,
+                     which, (void *) &size, (socklen_t)sizeof(int)) < 0)) {
        size -= 1024;
+    }
     if(size > 1024) {
        dbprintf(("%s: try_socksize: %s buffer size is %d\n",
                  debug_prefix(NULL),
index 6835cf4ce3649dcfac16f12553a1c1f96d29b9fb..eb73dd4715ed02d47cc64ae41f1155ca61aef5f8 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: stream.h,v 1.10 2001/08/14 22:38:26 jrjackson Exp $
+ * $Id: stream.h,v 1.12 2006/06/01 14:44:05 martinea Exp $
  *
  * interface to stream module
  */
 #define NETWORK_BLOCK_BYTES    DISK_BLOCK_BYTES
 #define STREAM_BUFSIZE         (NETWORK_BLOCK_BYTES * 2)
 
-int stream_server P((int *port, int sendsize, int recvsize));
-int stream_accept P((int sock, int timeout, int sendsize, int recvsize));
-int stream_client_privileged P((const char *hostname,
-                               int port,
-                               int sendsize,
-                               int recvsize,
-                               int *localport,
-                               int nonblock));
-int stream_client P((const char *hostname,
-                    int port,
-                    int sendsize,
-                    int recvsize,
-                    int *localport,
-                    int nonblock));
+int stream_server(in_port_t *port, size_t sendsize, size_t recvsize, int priv);
+int stream_accept(int sock, int timeout, size_t sendsize, size_t recvsize);
+int stream_client_privileged(const char *hostname,
+                               in_port_t port,
+                               size_t sendsize,
+                               size_t recvsize,
+                               in_port_t *localport,
+                               int nonblock);
+int stream_client(const char *hostname,
+                    in_port_t port,
+                    size_t sendsize,
+                    size_t recvsize,
+                    in_port_t *localport,
+                    int nonblock);
 
 #endif
index b33db7adc90badc113f0dbd3a2ebfd7f457931b5..2ec138cc3994e669fff3ee4f6e4e18fbf0f2f1c1 100644 (file)
@@ -15,7 +15,7 @@
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-/* $Id: strerror.c,v 1.6 1999/05/18 20:38:53 kashmir Exp $ */
+/* $Id: strerror.c,v 1.7 2006/05/25 01:47:12 johnfranks Exp $ */
 
 #include "amanda.h"
 
@@ -31,12 +31,12 @@ strerror(e)
     extern int sys_nerr;
     extern char *sys_errlist[];
     unsigned int errnum;
-    static char buf[NUM_STR_SIZE + sizeof(UPREFIX) + 1];
+    static char buf[NUM_STR_SIZE + SIZEOF(UPREFIX) + 1];
 
     errnum = e;                /* convert to unsigned */
 
     if (errnum < sys_nerr)
        return (sys_errlist[errnum]);
-    snprintf(buf, sizeof(buf), UPREFIX, errnum);
+    snprintf(buf, SIZEOF(buf), UPREFIX, errnum);
     return (buf);
 }
index fe0a497da451bff08e64f7336c09dcaacfc84292..c18098597569f5a65ef3500221fbbf18d38414bc 100644 (file)
 static char sccsid[] = "@(#)strftime.c 5.8 (Berkeley) 6/1/90";
 #endif /* LIBC_SCCS and not lint */
 
-#include <sys/types.h>
-#include <sys/time.h>
-#ifndef        linux
-# include <tzfile.h>
-#endif /* linux */
-#include <string.h>
+#include "amanda.h"
+#include <tzfile.h>
 
 static char *afmt[] = {
        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
@@ -237,7 +233,7 @@ _conv(n, digits, pad)
        static char buf[10];
        register char *p;
 
-       for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
+       for (p = buf + SIZEOF(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
                *p-- = n % 10 + '0';
        while (p > buf && digits-- > 0)
                *p-- = pad;
index 3bcbb94939113be14589a53b93abd4aa0385dc20..655746b16061aa2ca745bb5b52535e105b536d5f 100644 (file)
@@ -1,13 +1,4 @@
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
+#include "amanda.h"
 
 /*
  * The following function compares the first 'n' characters in 's1'
index 8d39cab6b5bbdd36c9b18c94b88bd2e3388a9c4d..194db84287c5ce5ddc74db72fdeb581e00a85278 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: tapelist.c,v 1.3 2006/01/15 21:00:59 martinea Exp $
+ * $Id: tapelist.c,v 1.8 2006/06/12 15:34:48 martinea Exp $
  *
  * Support code for amidxtaped and amindexd.
  */
 /*
  * Count the number of entries in this tapelist
  */
-int num_entries (tapelist)
-tapelist_t *tapelist;
+int
+num_entries(
+    tapelist_t *       tapelist)
 {
     tapelist_t *cur_tape;
     int count = 0;
 
-    for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next) count++;
+    for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next)
+       count++;
 
+    dbprintf(("num_entries(tapelist=%p)=%d\n", tapelist, count));
     return(count);
 }
 
+void
+dump_tapelist(
+    tapelist_t *tapelist)
+{
+    tapelist_t *cur_tape;
+    int count = 0;
+    int file;
+
+    dbprintf(("dump_tapelist(%p):\n", tapelist));
+    for(cur_tape = tapelist ; cur_tape != NULL ; cur_tape = cur_tape->next) {
+       dbprintf(("  %p->next     = %p\n", cur_tape, cur_tape->next));
+       dbprintf(("  %p->label    = %s\n", cur_tape, cur_tape->label));
+       dbprintf(("  %p->isafile  = %d\n", cur_tape, cur_tape->isafile));
+       dbprintf(("  %p->numfiles = %d\n", cur_tape, cur_tape->numfiles));
+       for (file=0; file < cur_tape->numfiles; file++) {
+           dbprintf(("  %p->files[%d] = " OFF_T_FMT "\n",
+                    cur_tape, file, (OFF_T_FMT_TYPE)cur_tape->files[file]));
+       }
+       count++;
+    }
+    dbprintf(("  %p count     = %d\n", tapelist, count));
+}
+
 /*
  * Add a tape entry with the given label to the given tapelist, creating a new
  * tapelist if handed a NULL one.  Squashes duplicates.
  */
-tapelist_t *append_to_tapelist (tapelist, label, file, isafile)
-tapelist_t *tapelist;
-char *label;
-int file, isafile;
+tapelist_t *
+append_to_tapelist(
+    tapelist_t *tapelist,
+    char *     label,
+    off_t      file,
+    int                isafile)
 {
     tapelist_t *new_tape, *cur_tape;
     int c;
 
+    dbprintf(("append_to_tapelist(tapelist=%p, label='%s', , file="
+               OFF_T_FMT ", isafile=%d)\n",
+               tapelist, label, (OFF_T_FMT_TYPE)file, isafile));
+
     /* see if we have this tape already, and if so just add to its file list */
-    for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next){
-       if(!strcmp(label, cur_tape->label)){
+    for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next) {
+       if(strcmp(label, cur_tape->label) == 0) {
            int d_idx = 0;
-           int *newfiles;
-           if(file >= 0){
-               newfiles = alloc(sizeof(int) * (cur_tape->numfiles + 1));
-               for(c = 0; c < cur_tape->numfiles ; c++){
-                   if(cur_tape->files[c] > file && c == d_idx){
+           off_t *newfiles;
+
+           if(file >= (off_t)0) {
+               newfiles = alloc(SIZEOF(*newfiles) *
+                                (cur_tape->numfiles + 1));
+               for(c = 0; c < cur_tape->numfiles ; c++) {
+                   if(cur_tape->files[c] > file && c == d_idx) {
                        newfiles[d_idx] = file;
                        d_idx++;
                    }
                    newfiles[d_idx] = cur_tape->files[c];
                    d_idx++;
                }
-               if(c == d_idx) newfiles[d_idx] = file;
+               if(c == d_idx)
+                   newfiles[d_idx] = file;
                cur_tape->numfiles++;
                amfree(cur_tape->files);
                cur_tape->files = newfiles;
            }
+           dump_tapelist(tapelist);
            return(tapelist);
        }
     }
 
-    new_tape = alloc(sizeof(tapelist_t));
-    memset(new_tape, 0, sizeof(tapelist_t));
+    new_tape = alloc(SIZEOF(tapelist_t));
+    memset(new_tape, 0, SIZEOF(tapelist_t));
     new_tape->label = stralloc(label);
-    if(file >= 0){
-       new_tape->files = alloc(sizeof(int));
+    if(file >= (off_t)0){
+       new_tape->files = alloc(SIZEOF(*(new_tape->files)));
        new_tape->files[0] = file;
        new_tape->numfiles = 1;
        new_tape->isafile = isafile;
@@ -95,21 +131,24 @@ int file, isafile;
     /* first instance of anything, start our tapelist with it */
     if(!tapelist){
        tapelist = new_tape;
-       return(tapelist);
+    } else {
+       /* new tape, tack it onto the end of the list */
+       cur_tape = tapelist;
+       while (cur_tape->next != NULL)
+           cur_tape = cur_tape->next;
+       cur_tape->next = new_tape;
     }
 
-    /* new tape, tack it onto the end of the list */
-    for(cur_tape = tapelist; cur_tape->next; cur_tape = cur_tape->next);
-    cur_tape->next = new_tape;
-
+    dump_tapelist(tapelist);
     return(tapelist);
 }
 
 /*
  * Backslash-escape all of the commas (and backslashes) in a label string.
  */
-char *escape_label (label)
-char *label;
+char *
+escape_label(
+    char *     label)
 {
     char *cooked_str, *temp_str;
     int s_idx = 0, d_idx = 0;
@@ -139,8 +178,9 @@ char *label;
 /*
  * Strip out any escape characters (backslashes)
  */
-char *unescape_label(label)
-char *label;
+char *
+unescape_label(
+    char *     label)
 {
     char *cooked_str, *temp_str;
     int s_idx = 0, d_idx = 0, prev_esc = 0;
@@ -171,9 +211,10 @@ char *label;
 /*
  * Convert a tapelist into a parseable string of tape labels and file numbers.
  */
-char *marshal_tapelist (tapelist, do_escape)
-tapelist_t *tapelist;
-int do_escape;
+char *
+marshal_tapelist(
+    tapelist_t *tapelist,
+    int                do_escape)
 {
     tapelist_t *cur_tape;
     char *str = NULL;
@@ -188,13 +229,18 @@ int do_escape;
 
        for(c = 0; c < cur_tape->numfiles ; c++){
            char num_str[NUM_STR_SIZE];
-           snprintf(num_str, sizeof(num_str), "%d", cur_tape->files[c]);
-           if(!files_str) files_str = stralloc(num_str);
-           else files_str = vstralloc(files_str, ",", num_str, NULL);
+           snprintf(num_str, SIZEOF(num_str), OFF_T_FMT,
+                       (OFF_T_FMT_TYPE)cur_tape->files[c]);
+           if (!files_str)
+               files_str = stralloc(num_str);
+           else
+               vstrextend(&files_str, ",", num_str, NULL);
        }
 
-       if(!str) str = vstralloc(esc_label, ":", files_str, NULL);
-       else str = vstralloc(str, ";", esc_label, ":", files_str, NULL);
+       if (!str)
+           str = vstralloc(esc_label, ":", files_str, NULL);
+       else
+           vstrextend(&str, ";", esc_label, ":", files_str, NULL);
 
        amfree(esc_label);
        amfree(files_str);
@@ -207,11 +253,13 @@ int do_escape;
  * Convert a previously str-ified and escaped list of tapes back into a
  * tapelist structure.
  */
-tapelist_t *unmarshal_tapelist_str (tapelist_str)
-char *tapelist_str;
+tapelist_t *
+unmarshal_tapelist_str(
+    char *     tapelist_str)
 {
     char *temp_label, *temp_filenum;
-    int l_idx, n_idx, input_length;
+    int l_idx, n_idx;
+    size_t input_length;
     tapelist_t *tapelist = NULL;
 
     if(!tapelist_str) return(NULL);
@@ -226,32 +274,38 @@ char *tapelist_str;
        memset(temp_label, '\0', input_length+1);
         l_idx = 0;
        while(*tapelist_str != ':' && *tapelist_str != '\0'){
-           if(*tapelist_str == '\\') *tapelist_str++; /* skip escapes */
+           if(*tapelist_str == '\\')
+               tapelist_str++; /* skip escapes */
            temp_label[l_idx] = *tapelist_str;
-           if(*tapelist_str == '\0') break; /* bad format, should kvetch */
-           *tapelist_str++;
+           if(*tapelist_str == '\0')
+               break; /* bad format, should kvetch */
+           tapelist_str++;
            l_idx++;
        }
-       if(*tapelist_str != '\0') *tapelist_str++;
-       tapelist = append_to_tapelist(tapelist, temp_label, -1, 0);
+       if(*tapelist_str != '\0')
+           tapelist_str++;
+       tapelist = append_to_tapelist(tapelist, temp_label, (off_t)-1, 0);
 
        /* now read the list of file numbers */
        while(*tapelist_str != ';' && *tapelist_str != '\0'){
-           int filenum = -1;
+           off_t filenum;
+
            memset(temp_filenum, '\0', input_length+1);
            n_idx = 0;
            while(*tapelist_str != ';' && *tapelist_str != ',' &&
                    *tapelist_str != '\0'){
                temp_filenum[n_idx] = *tapelist_str; 
-               *tapelist_str++;
+               tapelist_str++;
                n_idx++;
            }
-           filenum = atoi(temp_filenum);
+           filenum = OFF_T_ATOI(temp_filenum);
 
            tapelist = append_to_tapelist(tapelist, temp_label, filenum, 0);
-           if(*tapelist_str != '\0' && *tapelist_str != ';') *tapelist_str++;
+           if(*tapelist_str != '\0' && *tapelist_str != ';')
+               tapelist_str++;
        }
-       if(*tapelist_str != '\0') *tapelist_str++;
+       if(*tapelist_str != '\0')
+           tapelist_str++;
 
     } while(*tapelist_str != '\0');
 
@@ -264,18 +318,18 @@ char *tapelist_str;
 /*
  * Free up a list of tapes
  */
-void free_tapelist (tapelist)
-tapelist_t *tapelist;
+void
+free_tapelist(
+    tapelist_t *       tapelist)
 {
     tapelist_t *cur_tape;
     tapelist_t *prev = NULL;
 
     for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next){
-       if(cur_tape->label) amfree(cur_tape->label);
-       if(cur_tape->files) amfree(cur_tape->files);
-       if(prev) amfree(prev);
+       amfree(cur_tape->label);
+       amfree(cur_tape->files);
+       amfree(prev);
        prev = cur_tape;
     }
-    if(prev) amfree(prev);
-
+    amfree(prev);
 }
index 7d3e99bc2bc1787862e017d431cbded7faa6d1ff..e6b58e20dff93c90385520a7b9b427d414837a94 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: tapelist.h,v 1.1 2005/10/11 01:17:00 vectro Exp $
+ * $Id: tapelist.h,v 1.2 2006/05/25 01:47:12 johnfranks Exp $
  *
  */
 
@@ -44,17 +44,18 @@ typedef struct tapelist_s {
     struct tapelist_s *next;
     char *label;
     int isafile; /* set to 1 and make *label the path to the file */
-    int *files;
+    off_t *files;
     int numfiles;
 } tapelist_t;
 
-extern int num_entries P((tapelist_t *tapelist));
-extern tapelist_t *append_to_tapelist P((tapelist_t *tapelist, char *label,
-                                       int file, int isafile));
-extern char *marshal_tapelist P((tapelist_t *tapelist, int escape));
-extern tapelist_t *unmarshal_tapelist_str P((char *tapelist_str));
-extern char *escape_label P((char *label));
-extern char *unescape_label P((char *label));
-extern void free_tapelist P((tapelist_t *tapelist));
-
+int num_entries(tapelist_t *tapelist);
+tapelist_t *append_to_tapelist(tapelist_t *tapelist, char *label,
+                                       off_t file, int isafile);
+char *marshal_tapelist(tapelist_t *tapelist, int escape);
+tapelist_t *unmarshal_tapelist_str(char *tapelist_str);
+char *escape_label(char *label);
+char *unescape_label(char *label);
+void free_tapelist(tapelist_t *tapelist);
+void dump_tapelist(tapelist_t *);
 #endif /* !TAPELIST_H */
index d894f40575b614c9f586cbb9bae58882a403f4c8..5dd8569a9a6206ed378de578317a72fd7c2b9680 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: token.c,v 1.29 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: token.c,v 1.32 2006/07/19 17:41:15 martinea Exp $
  *
  * token bashing routines
  */
 ** Inspired by awk and a routine called splitter() that I snarfed from
 ** the net ages ago (original author long forgotten).
 */
-int split(str, token, toklen, sep)
-char *str;     /* String to split */
-char **token;  /* Array of token pointers */
-int toklen;    /* Size of token[] */
-char *sep;     /* Token separators - usually " " */
+int
+split(
+    char *     str,    /* String to split */
+    char **    token,  /* Array of token pointers */
+    int                toklen, /* Size of token[] */
+    char *     sep)    /* Token separators - usually " " */
 {
     register char *pi, *po;
     register int fld;
@@ -70,21 +71,7 @@ char *sep;   /* Token separators - usually " " */
     if (*sep == '\0' || *str == '\0' || toklen == 1) return fld;
 
     /* Calculate the length of the unquoted string. */
-
-    len = 0;
-    for (pi = str; *pi && *pi != '\n'; pi++) {
-       switch(*pi) {
-       case '\\':      /* had better not be trailing... */
-           pi++;
-           if (*pi >= '0' && *pi <= '3') pi = pi + 2;
-           len++;
-           break;
-       case '"':       /* just ignore "'s */
-           break;
-       default:
-           len++;
-       }
-    }
+    len = strlen(str);;
 
     /* Allocate some space */
 
@@ -95,29 +82,36 @@ char *sep;  /* Token separators - usually " " */
     in_quotes = 0;
     po = buf;
     token[++fld] = po;
-    for (pi = str; *pi && *pi != '\n'; pi++) {
-       if (*pi == '\\') {      /* escape */
-           pi++;
-           if (*pi >= '0' && *pi <= '3') {
-               *po =       ((*pi++ - '0') << 6);
-               *po = *po + ((*pi++ - '0') << 3);
-               *po = *po + ((*pi   - '0')     );
-           }
-           else *po = *pi;
-           po++;
-       }
-       else if (*pi == '"') {  /* quotes */
-           in_quotes = !in_quotes;
-       }
-       else if (!in_quotes && strchr(sep, *pi)) {      /* separator */
+    for (pi = str; *pi && *pi != '\0'; pi++) {
+       if (*pi == '\n' && !in_quotes)
+           break;
+
+       if (!in_quotes && strchr(sep, *pi)) {
+           /*
+            * separator
+            * Advance to next field.
+            */
            *po = '\0'; /* end of token */
            if (fld+1 >= toklen) return fld; /* too many tokens */
            token[++fld] = po + 1;
            po++;
+           continue;
        }
-       else {
-           *po++ = *pi;        /* normal */
+
+       if (*pi == '"') {
+           /*
+            * Start or end of quote
+            * Emit quote in either case
+            */
+           in_quotes = !in_quotes;
+       } else if (in_quotes && *pi == '\\' && (*(pi + 1) == '"')) {
+           /*
+            * Quoted quote.
+            * emit '/' - default will pick up '"'
+            */
+           *po++ = *pi++;
        }
+       *po++ = *pi;    /* Emit character */
     }
     *po = '\0';
 
@@ -141,7 +135,7 @@ printf_arglist_function(char *squotef, char *, format)
        /* Format the token */
 
        arglist_start(argp, format);
-       vsnprintf(linebuf, sizeof(linebuf), format, argp);
+       vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
        arglist_end(argp);
 
        return quote(" ", linebuf);
@@ -155,21 +149,22 @@ printf_arglist_function1(char *quotef, char *, sep, char *, format)
        /* Format the token */
 
        arglist_start(argp, format);
-       vsnprintf(linebuf, sizeof(linebuf), format, argp);
+       vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
        arglist_end(argp);
 
        return quote(sep, linebuf);
 }
 
-char *squote(str)
-char *str;     /* the string to quote */
+char *squote(
+    char *     str)    /* the string to quote */
 {
        return quote(" ", str);
 }
 
-char *quote(sepchr, str)
-char *sepchr;  /* separators that also need quoting */
-char *str;     /* the string to quote */
+char *
+quote(
+    char *     sepchr, /* separators that also need quoting */
+    char *     str)    /* the string to quote */
 {
     register char *pi, *po;
     register size_t len;
@@ -178,7 +173,8 @@ char *str;  /* the string to quote */
 
     /* Calculate the length of the quoted token. */
 
-    len = sep = 0;
+    sep = 0;
+    len = 0;
     for (pi = str; *pi; pi++) {
        if (*pi < ' ' || *pi > '~')
            len = len + 4;
@@ -209,9 +205,9 @@ char *str;  /* the string to quote */
     for (pi = str; *pi; pi++) {
        if (*pi < ' ' || *pi > '~') {
            *po++ = '\\';
-           *po++ = ((*pi >> 6) & 07) + '0';
-           *po++ = ((*pi >> 3) & 07) + '0';
-           *po++ = ((*pi     ) & 07) + '0';
+           *po++ = (char)(((*pi >> 6) & 07) + '0');
+           *po++ = (char)(((*pi >> 3) & 07) + '0');
+           *po++ = (char)(((*pi     ) & 07) + '0');
        }
        else if (*pi == '\\' || *pi == '"') {
            *po++ = '\\';
@@ -224,14 +220,15 @@ char *str;        /* the string to quote */
 
     *po = '\0';
 
-    assert(po - buf == len);   /* Just checking! */
+    assert(po == (buf + len)); /* Just checking! */
 
     return buf;
 }
 
 /* Quote a string so that it can be used as a regular expression */
-char *rxquote(str)
-char *str;     /* the string to quote */
+char *
+rxquote(
+    char *     str)    /* the string to quote */
 {
     char *pi, *po;
     size_t len;
@@ -289,15 +286,16 @@ char *str;        /* the string to quote */
 
     *po = '\0';
 
-    assert(po - buf == len);   /* Just checking! */
+    assert(po == (buf + len)); /* Just checking! */
 
     return buf;
 }
 
 #ifndef HAVE_SHQUOTE
 /* Quote a string so that it can be safely passed to a shell */
-char *shquote(str)
-char *str;     /* the string to quote */
+char *
+shquote(
+    char *     str)    /* the string to quote */
 {
     char *pi, *po;
     size_t len;
@@ -364,7 +362,7 @@ char *str;  /* the string to quote */
 
     *po = '\0';
 
-    assert(po - buf == len);   /* Just checking! */
+    assert(po == (buf + len)); /* Just checking! */
 
     return buf;
 }
@@ -372,13 +370,15 @@ char *str;        /* the string to quote */
 
 /* Table lookup.
 */
-int table_lookup(table, str)
-table_t *table;
-char *str;
+int
+table_lookup(
+    table_t *  table,
+    char *     str)
 {
        while(table->word != (char *)0) {
-               if (*table->word == *str &&
-                   strcmp(table->word, str) == 0) return table->value;
+               if (*table->word == *str && strcmp(table->word, str) == 0) {
+                       return table->value;
+               }
                table++;
        }
 
@@ -387,12 +387,15 @@ char *str;
 
 /* Reverse table lookup.
 */
-char *table_lookup_r(table, val)
-table_t *table;
-int val;
+char *
+table_lookup_r(
+    /*@keep@*/ table_t *       table,
+               int             val)
 {
        while(table->word != (char *)0) {
-               if (table->value == val) return table->word;
+               if (table->value == val) {
+                       return table->word;
+               }
                table++;
        }
 
@@ -401,7 +404,10 @@ int val;
 
 #ifdef TEST
 
-int main()
+int
+main(
+    int                argc,
+    char **    argv)
 {
        char *str = NULL;
        char *t[20];
@@ -411,8 +417,14 @@ int main()
 
        safe_fd(-1, 0);
 
+       /* shut up compiler */
+       argc = argc;
+       argv = argv;
+
        set_pname("token test");
 
+       dbopen(NULL);
+
        /* Don't die when child closes pipe */
        signal(SIGPIPE, SIG_IGN);
 
@@ -443,8 +455,8 @@ int main()
                }
                sr = squote(str);
                printf("Quoted   = \"%s\"\n", sr);
-               strncpy(str,sr,sizeof(str)-1);
-               str[sizeof(str)-1] = '\0';
+               strncpy(str,sr,SIZEOF(str)-1);
+               str[SIZEOF(str)-1] = '\0';
                r = split(str, t, 20, " ");
                if (r != 1) printf("split()=%d!\n", r);
                printf("Unquoted = \"%s\"\n", t[1]);
index 6e33b7b3107ca96f8a51990058a065269a6c3d21..1856cbf8a6d632882d89a73bc93a9cc4d9047639 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: token.h,v 1.12 2003/03/26 20:17:13 kovert Exp $
+ * $Id: token.h,v 1.13 2006/05/25 01:47:12 johnfranks Exp $
  *
  * interface to token module
  */
 
 typedef struct {char *word; int value;} table_t;
 
-extern int split P((char *str, char **token, int toklen, char *sep));
-extern char *squotef P((char *format, ...))
+extern int split(char *str, char **token, int toklen, char *sep);
+extern char *squotef(char *format, ...)
     __attribute__ ((format (printf, 1, 2)));
-extern char *squote P((char *str));
-extern char *quotef P((char *sep, char *format, ...))
+extern char *squote(char *str);
+extern char *quotef(char *sep, char *format, ...)
     __attribute__ ((format (printf, 2, 3)));
-extern char *quote P((char *sep, char *str));
-extern char *rxquote P((char *str));
+extern char *quote(char *sep, char *str);
+extern char *rxquote(char *str);
 #ifndef HAVE_SHQUOTE
-extern char *shquote P((char *str));
+extern char *shquote(char *str);
 #endif
-extern int table_lookup P((table_t *table, char *str));
-extern char *table_lookup_r P((table_t *table, int val));
+extern int table_lookup(table_t *table, char *str);
+extern char *table_lookup_r(table_t *table, int val);
 
 #endif
index 0eafec0b74d6822f7305e453b69c498eac97f789..a5f88f8d57218a958685313e3313714f27923eba 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: util.c,v 1.17 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: util.c,v 1.42 2006/08/24 01:57:15 paddy_s Exp $
  */
 
 #include "amanda.h"
 #include "util.h"
+#include "arglist.h"
+#include "clock.h"
+
+int allow_overwrites;
+int token_pushed;
+
+tok_t tok, pushed_tok;
+val_t tokenval;
+
+int conf_line_num, got_parserror;
+FILE *conf_conf = (FILE *)NULL;
+char *conf_confname = NULL;
+char *conf_line = NULL;
+char *conf_char = NULL;
+
+/*#define NET_READ_DEBUG*/
+
+#ifdef NET_READ_DEBUG
+#define netprintf(x)    dbprintf(x)
+#else
+#define netprintf(x)
+#endif
+
+static int make_socket(void);
+static int connect_port(struct sockaddr_in *addrp, in_port_t port, char *proto,
+                       struct sockaddr_in *svaddr, int nonblock);
+
+char conftoken_getc(void);
+int conftoken_ungetc(int c);
 
 /*
  * Keep calling read() until we've read buflen's worth of data, or EOF,
  * Returns the number of bytes read, 0 on EOF, or negative on error.
  */
 ssize_t
-fullread(fd, vbuf, buflen)
-    int fd;
-    void *vbuf;
-    size_t buflen;
+fullread(
+    int                fd,
+    void *     vbuf,
+    size_t     buflen)
 {
     ssize_t nread, tot = 0;
     char *buf = vbuf;  /* cast to char so we can ++ it */
@@ -70,10 +99,10 @@ fullread(fd, vbuf, buflen)
  * Returns the number of bytes written, or negative on error.
  */
 ssize_t
-fullwrite(fd, vbuf, buflen)
-    int fd;
-    const void *vbuf;
-    size_t buflen;
+fullwrite(
+    int                fd,
+    const void *vbuf,
+    size_t     buflen)
 {
     ssize_t nwritten, tot = 0;
     const char *buf = vbuf;    /* cast to char so we can ++ it */
@@ -92,6 +121,208 @@ fullwrite(fd, vbuf, buflen)
     return (tot);
 }
 
+static int
+make_socket(void)
+{
+    int s;
+    int save_errno;
+#if defined(SO_KEEPALIVE) || defined(USE_REUSEADDR)
+    int on=1;
+    int r;
+#endif
+
+    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+        save_errno = errno;
+        dbprintf(("%s: make_socket: socket() failed: %s\n",
+                  debug_prefix(NULL),
+                  strerror(save_errno)));
+        errno = save_errno;
+        return -1;
+    }
+    if (s < 0 || s >= (int)FD_SETSIZE) {
+        aclose(s);
+        errno = EMFILE;                         /* out of range */
+        return -1;
+    }
+
+#ifdef USE_REUSEADDR
+    r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+    if (r < 0) {
+       save_errno = errno;
+       dbprintf(("%s: stream_server: setsockopt(SO_REUSEADDR) failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(errno)));
+       errno = save_errno;
+    }
+#endif
+
+#ifdef SO_KEEPALIVE
+    r = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
+                  (void *)&on, SIZEOF(on));
+    if (r == -1) {
+       save_errno = errno;
+       dbprintf(("%s: make_socket: setsockopt() failed: %s\n",
+                  debug_prefix(NULL),
+                  strerror(save_errno)));
+       aclose(s);
+       errno = save_errno;
+       return -1;
+    }
+#endif
+
+    return s;
+}
+
+/* addrp is my address */
+/* svaddr is the address of the remote machine */
+/* return socket on success */
+/* return -1     on failure */
+int
+connect_portrange(
+    struct sockaddr_in *addrp,
+    in_port_t          first_port,
+    in_port_t          last_port,
+    char *             proto,
+    struct sockaddr_in *svaddr,
+    int                        nonblock)
+{
+    int                        s;
+    in_port_t          port;
+    static in_port_t   port_in_use[1024];
+    static int         nb_port_in_use = 0;
+    int                        i;
+
+    assert(first_port <= last_port);
+
+    /* Try a port already used */
+    for(i=0; i < nb_port_in_use; i++) {
+       port = port_in_use[i];
+       if(port >= first_port && port <= last_port) {
+           s = connect_port(addrp, port, proto, svaddr, nonblock);
+           if(s == -2) return -1;
+           if(s > 0) {
+               return s;
+           }
+       }
+    }
+
+    /* Try a port in the range */
+    for (port = first_port; port <= last_port; port++) {
+       s = connect_port(addrp, port, proto, svaddr, nonblock);
+       if(s == -2) return -1;
+       if(s > 0) {
+           port_in_use[nb_port_in_use++] = port;
+           return s;
+       }
+    }
+
+    dbprintf(("%s: connect_portrange: all ports between %d and %d busy\n",
+             debug_prefix_time(NULL),
+             first_port,
+             last_port));
+    errno = EAGAIN;
+    return -1;
+}
+
+/* addrp is my address */
+/* svaddr is the address of the remote machine */
+/* return -2: Don't try again */
+/* return -1: Try with another port */
+/* return >0: this is the connected socket */
+int
+connect_port(
+    struct sockaddr_in *addrp,
+    in_port_t                  port,
+    char *             proto,
+    struct sockaddr_in *svaddr,
+    int                        nonblock)
+{
+    int                        save_errno;
+    struct servent *   servPort;
+    socklen_t          len;
+    int                        s;
+
+    servPort = getservbyport((int)htons(port), proto);
+    if (servPort != NULL && !strstr(servPort->s_name, "amanda")) {
+       dbprintf(("%s: connect_port: Skip port %d: Owned by %s.\n",
+                 debug_prefix_time(NULL), port, servPort->s_name));
+       return -1;
+    }
+
+    if(servPort == NULL)
+       dbprintf(("%s: connect_port: Try  port %d: Available   - ",
+                 debug_prefix_time(NULL), port));
+    else {
+       dbprintf(("%s: connect_port: Try  port %d: Owned by %s - ",
+                 debug_prefix_time(NULL), port, servPort->s_name));
+    }
+
+    if ((s = make_socket()) == -1) return -2;
+
+    addrp->sin_port = (in_port_t)htons(port);
+
+    if (bind(s, (struct sockaddr *)addrp, sizeof(*addrp)) != 0) {
+       save_errno = errno;
+       aclose(s);
+       if (save_errno != EADDRINUSE) {
+           dbprintf(("errno %d strerror %s\n",
+                     errno, strerror(errno)));
+           errno = save_errno;
+           return -2;
+       }
+       errno = save_errno;
+       return -1;
+    }
+
+    /* find out what port was actually used */
+
+    len = sizeof(*addrp);
+    if (getsockname(s, (struct sockaddr *)addrp, &len) == -1) {
+       save_errno = errno;
+       dbprintf(("%s: connect_port: getsockname() failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+       aclose(s);
+       errno = save_errno;
+       return -1;
+    }
+
+    if (nonblock)
+       fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0)|O_NONBLOCK);
+    if (connect(s, (struct sockaddr *)svaddr,
+               (socklen_t)sizeof(*svaddr)) == -1 && !nonblock) {
+       save_errno = errno;
+       dbprintf(("%s: connect_portrange: connect from %s.%d failed\n",
+                 debug_prefix_time(NULL),
+                 inet_ntoa(addrp->sin_addr),
+                 ntohs(addrp->sin_port),
+                 strerror(save_errno)));
+       dbprintf(("%s: connect_portrange: connect to %s.%d failed: %s\n",
+                 debug_prefix_time(NULL),
+                 inet_ntoa(svaddr->sin_addr),
+                 ntohs(svaddr->sin_port),
+                 strerror(save_errno)));
+       aclose(s);
+       errno = save_errno;
+       if (save_errno == ECONNREFUSED ||
+           save_errno == ETIMEDOUT)  {
+           return -2   ;
+       }
+       return -1;
+    }
+
+    dbprintf(("%s: connected to %s.%d\n",
+              debug_prefix_time(NULL),
+              inet_ntoa(svaddr->sin_addr),
+              ntohs(svaddr->sin_port)));
+    dbprintf(("%s: our side is %s.%d\n",
+              debug_prefix(NULL),
+              inet_ntoa(addrp->sin_addr),
+              ntohs(addrp->sin_port)));
+    return s;
+}
+
+
 /*
  * Bind to a port in the given range.  Takes a begin,end pair of port numbers.
  *
@@ -99,67 +330,59 @@ fullwrite(fd, vbuf, buflen)
  * on success.
  */
 int
-bind_portrange(s, addrp, first_port, last_port, proto)
-    int s;
-    struct sockaddr_in *addrp;
-    int first_port, last_port;
-    char *proto;
+bind_portrange(
+    int                        s,
+    struct sockaddr_in *addrp,
+    in_port_t          first_port,
+    in_port_t          last_port,
+    char *             proto)
 {
-    int port, cnt;
-    const int num_ports = last_port - first_port + 1;
-    int save_errno;
+    in_port_t port;
+    in_port_t cnt;
     struct servent *servPort;
+    const in_port_t num_ports = (in_port_t)(last_port - first_port + 1);
 
-    assert(first_port > 0 && first_port <= last_port && last_port < 65536);
+    assert(first_port <= last_port);
 
     /*
      * We pick a different starting port based on our pid and the current
      * time to avoid always picking the same reserved port twice.
      */
-    port = ((getpid() + time(0)) % num_ports) + first_port;
+    port = (in_port_t)(((getpid() + time(0)) % num_ports) + first_port);
+
     /*
      * Scan through the range, trying all available ports that are either 
      * not taken in /etc/services or registered for *amanda*.  Wrap around
      * if we don't happen to start at the beginning.
      */
     for (cnt = 0; cnt < num_ports; cnt++) {
-       servPort = getservbyport(htons(port), proto);
-       if((servPort == NULL) || strstr(servPort->s_name, "amanda")){
-           dbprintf(("%s: bind_portrange2: trying port=%d\n",
+       servPort = getservbyport((int)htons(port), proto);
+       if ((servPort == NULL) || strstr(servPort->s_name, "amanda")) {
+           if (servPort == NULL) {
+               dbprintf(("%s: bind_portrange2: Try  port %d: Available   - ",
                      debug_prefix_time(NULL), port));
-           addrp->sin_port = htons(port);
-           if (bind(s, (struct sockaddr *)addrp, sizeof(*addrp)) >= 0)
+           } else {
+               dbprintf(("%s: bind_portrange2: Try  port %d: Owned by %s - ",
+                     debug_prefix_time(NULL), port, servPort->s_name));
+           }
+           addrp->sin_port = (in_port_t)htons(port);
+           if (bind(s, (struct sockaddr *)addrp, (socklen_t)sizeof(*addrp)) >= 0) {
+               dbprintf(("Success\n"));
                return 0;
-           /*
-            * If the error was something other then port in use, stop.
-            */
-           if (errno != EADDRINUSE)
-               break;
+           }
+           dbprintf(("%s\n", strerror(errno)));
+       } else {
+               dbprintf(("%s: bind_portrange2: Skip port %d: Owned by %s.\n",
+                     debug_prefix_time(NULL), port, servPort->s_name));
        }
        if (++port > last_port)
            port = first_port;
     }
-    if (cnt == num_ports) {
-       dbprintf(("%s: bind_portrange: all ports between %d and %d busy\n",
+    dbprintf(("%s: bind_portrange: all ports between %d and %d busy\n",
                  debug_prefix_time(NULL),
                  first_port,
                  last_port));
-       errno = EAGAIN;
-    } else if (last_port < IPPORT_RESERVED
-              && getuid() != 0
-              && errno == EACCES) {
-       /*
-        * Do not bother with an error message in this case because it
-        * is expected.
-        */
-    } else {
-       save_errno = errno;
-       dbprintf(("%s: bind_portrange: port %d: %s\n",
-                 debug_prefix_time(NULL),
-                 port,
-                 strerror(errno)));
-       errno = save_errno;
-    }
+    errno = EAGAIN;
     return -1;
 }
 
@@ -167,20 +390,23 @@ bind_portrange(s, addrp, first_port, last_port, proto)
  * Construct a datestamp (YYYYMMDD) from a time_t.
  */
 char *
-construct_datestamp(t)
-    time_t *t;
+construct_datestamp(
+    time_t *t)
 {
     struct tm *tm;
-    char datestamp[3*NUM_STR_SIZE];
+    char datestamp[3 * NUM_STR_SIZE];
     time_t when;
 
-    if(t == NULL) {
+    if (t == NULL) {
        when = time((time_t *)NULL);
     } else {
        when = *t;
     }
     tm = localtime(&when);
-    snprintf(datestamp, sizeof(datestamp),
+    if (!tm)
+       return stralloc("19000101");
+
+    snprintf(datestamp, SIZEOF(datestamp),
              "%04d%02d%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
     return stralloc(datestamp);
 }
@@ -189,22 +415,2249 @@ construct_datestamp(t)
  * Construct a timestamp (YYYYMMDDHHMMSS) from a time_t.
  */
 char *
-construct_timestamp(t)
-    time_t *t;
+construct_timestamp(
+    time_t *t)
 {
     struct tm *tm;
-    char timestamp[6*NUM_STR_SIZE];
+    char timestamp[6 * NUM_STR_SIZE];
     time_t when;
 
-    if(t == NULL) {
+    if (t == NULL) {
        when = time((time_t *)NULL);
     } else {
        when = *t;
     }
     tm = localtime(&when);
-    snprintf(timestamp, sizeof(timestamp),
+    if (!tm)
+       return stralloc("19000101000000");
+
+    snprintf(timestamp, SIZEOF(timestamp),
             "%04d%02d%02d%02d%02d%02d",
             tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
             tm->tm_hour, tm->tm_min, tm->tm_sec);
     return stralloc(timestamp);
 }
+
+
+int
+needs_quotes(
+    const char * str)
+{
+    return (match("[ \t\f\r\n\"]", str) != 0);
+}
+
+
+/*
+ * For backward compatibility we are trying for minimal quoting.
+ * We only quote a string if it contains whitespace or is misquoted...
+ */
+
+char *
+quote_string(
+    const char *str)
+{
+    char *  s;
+    char *  ret;
+
+    if ((str == NULL) || (*str == '\0')) {
+       ret = stralloc("\"\"");
+    } else if ((match("[\\\"[:space:][:cntrl:]]", str)) == 0) {
+       /*
+        * String does not need to be quoted since it contains
+        * neither whitespace, control or quote characters.
+        */
+       ret = stralloc(str);
+    } else {
+       /*
+        * Allocate maximum possible string length.
+        * (a string of all quotes plus room for leading ", trailing " and NULL)
+        */
+       ret = s = alloc((strlen(str) * 2) + 2 + 1);
+       *(s++) = '"';
+       while (*str != '\0') {
+            if (*str == '\t') {
+                *(s++) = '\\';
+                *(s++) = 't';
+               str++;
+               continue;
+           } else if (*str == '\n') {
+                *(s++) = '\\';
+                *(s++) = 'n';
+               str++;
+               continue;
+           } else if (*str == '\r') {
+                *(s++) = '\\';
+                *(s++) = 'r';
+               str++;
+               continue;
+           } else if (*str == '\f') {
+                *(s++) = '\\';
+                *(s++) = 'f';
+               str++;
+               continue;
+           }
+            if (*str == '"')
+                *(s++) = '\\';
+            *(s++) = *(str++);
+        }
+        *(s++) = '"';
+        *s = '\0';
+    }
+    return (ret);
+}
+
+
+char *
+unquote_string(
+    const char *str)
+{
+    char * ret;
+
+    if ((str == NULL) || (*str == '\0')) {
+       ret = stralloc("");
+    } else {
+       char * in;
+       char * out;
+
+       ret = in = out = stralloc(str);
+       while (*in != '\0') {
+           if (*in == '"') {
+               in++;
+               continue;
+           }
+
+           if (*in == '\\') {
+               in++;
+               if (*in == 'n') {
+                   in++;
+                   *(out++) = '\n';
+                   continue;
+               } else if (*in == 't') {
+                   in++;
+                   *(out++) = '\t';
+                   continue;
+               } else if (*in == 'r') {
+                   in++;
+                   *(out++) = '\r';
+                   continue;
+               } else if (*in == 'f') {
+                   in++;
+                   *(out++) = '\f';
+                   continue;
+               }
+           }
+           *(out++) = *(in++);
+       }
+        *out = '\0';
+    }
+    return (ret);
+}
+
+char *
+sanitize_string(
+    const char *str)
+{
+    char * s;
+    char * ret;
+
+    if ((str == NULL) || (*str == '\0')) {
+       ret = stralloc("");
+    } else {
+       ret = stralloc(str);
+       for (s = ret; *s != '\0'; s++) {
+           if (iscntrl(*s))
+               *s = '?';
+       }
+    }
+    return (ret);
+}
+
+char *
+strquotedstr(void)
+{
+    char *  tok = strtok(NULL, " ");
+
+    if ((tok != NULL) && (tok[0] == '"')) {
+       char *  t;
+       size_t  len;
+
+        len = strlen(tok);
+       do {
+           t = strtok(NULL, " ");
+           tok[len] = ' ';
+           len = strlen(tok);
+       } while ((t != NULL) &&
+                (tok[len - 1] != '"') && (tok[len - 2] != '\\'));
+    }
+    return tok;
+}
+
+ssize_t
+hexdump(
+    const char *buffer,
+    size_t     len)
+{
+    ssize_t rc = -1;
+
+    FILE *stream = popen("od -w10 -c -x -", "w");
+       
+    if (stream != NULL) {
+       fflush(stdout);
+       rc = (ssize_t)fwrite(buffer, len, 1, stream);
+       if (ferror(stream))
+           rc = -1;
+       fclose(stream);
+    }
+    return rc;
+}
+
+/*
+   Return 0 if the following characters are present
+   * ( ) < > [ ] , ; : ! $ \ / "
+   else returns 1
+*/
+
+int
+validate_mailto(
+    const char *mailto)
+{
+    return !match("\\*|<|>|\\(|\\)|\\[|\\]|,|;|:|\\\\|/|\"|\\!|\\$|\\|", mailto);
+}
+
+
+t_conf_var *
+get_np(
+    t_conf_var *get_var,
+    int        parm)
+{
+    t_conf_var *np;
+
+    for(np = get_var; np->token != CONF_UNKNOWN; np++) {
+       if(np->parm == parm)
+           break;
+    }
+
+    if(np->token == CONF_UNKNOWN) {
+       error("error [unknown getconf_np parm: %d]", parm);
+       /* NOTREACHED */
+    }
+    return np;
+}
+
+void
+get_simple(
+    val_t  *var,
+    tok_t  type)
+{
+    ckseen(&var->seen);
+
+    switch(type) {
+    case CONF_STRING:
+    case CONF_IDENT:
+       get_conftoken(type);
+       var->v.s = newstralloc(var->v.s, tokenval.v.s);
+       malloc_mark(var->v.s);
+       break;
+
+    case CONF_INT:
+       var->v.i = get_int();
+       break;
+
+    case CONF_LONG:
+       var->v.l = get_long();
+       break;
+
+    case CONF_SIZE:
+       var->v.size = get_size();
+       break;
+
+    case CONF_AM64:
+       var->v.am64 = get_am64_t();
+       break;
+
+    case CONF_BOOL:
+       var->v.i = get_bool();
+       break;
+
+    case CONF_REAL:
+       get_conftoken(CONF_REAL);
+       var->v.r = tokenval.v.r;
+       break;
+
+    case CONF_TIME:
+       var->v.t = get_time();
+       break;
+
+    default:
+       error("error [unknown get_simple type: %d]", type);
+       /* NOTREACHED */
+    }
+    return;
+}
+
+time_t
+get_time(void)
+{
+    time_t hhmm;
+
+    get_conftoken(CONF_ANY);
+    switch(tok) {
+    case CONF_INT:
+#if SIZEOF_TIME_T < SIZEOF_INT
+       if ((off_t)tokenval.v.i >= (off_t)TIME_MAX)
+           conf_parserror("value too large");
+#endif
+       hhmm = (time_t)tokenval.v.i;
+       break;
+
+    case CONF_LONG:
+#if SIZEOF_TIME_T < SIZEOF_LONG
+       if ((off_t)tokenval.v.l >= (off_t)TIME_MAX)
+           conf_parserror("value too large");
+#endif
+       hhmm = (time_t)tokenval.v.l;
+       break;
+
+    case CONF_SIZE:
+#if SIZEOF_TIME_T < SIZEOF_SSIZE_T
+       if ((off_t)tokenval.v.size >= (off_t)TIME_MAX)
+           conf_parserror("value too large");
+#endif
+       hhmm = (time_t)tokenval.v.size;
+       break;
+
+    case CONF_AM64:
+#if SIZEOF_TIME_T < SIZEOF_LONG_LONG
+       if ((off_t)tokenval.v.am64 >= (off_t)TIME_MAX)
+           conf_parserror("value too large");
+#endif
+       hhmm = (time_t)tokenval.v.am64;
+       break;
+
+    case CONF_AMINFINITY:
+       hhmm = TIME_MAX;
+       break;
+
+    default:
+       conf_parserror("a time is expected");
+       hhmm = 0;
+       break;
+    }
+    return hhmm;
+}
+
+keytab_t numb_keytable[] = {
+    { "B", CONF_MULT1 },
+    { "BPS", CONF_MULT1 },
+    { "BYTE", CONF_MULT1 },
+    { "BYTES", CONF_MULT1 },
+    { "DAY", CONF_MULT1 },
+    { "DAYS", CONF_MULT1 },
+    { "INF", CONF_AMINFINITY },
+    { "K", CONF_MULT1K },
+    { "KB", CONF_MULT1K },
+    { "KBPS", CONF_MULT1K },
+    { "KBYTE", CONF_MULT1K },
+    { "KBYTES", CONF_MULT1K },
+    { "KILOBYTE", CONF_MULT1K },
+    { "KILOBYTES", CONF_MULT1K },
+    { "KPS", CONF_MULT1K },
+    { "M", CONF_MULT1M },
+    { "MB", CONF_MULT1M },
+    { "MBPS", CONF_MULT1M },
+    { "MBYTE", CONF_MULT1M },
+    { "MBYTES", CONF_MULT1M },
+    { "MEG", CONF_MULT1M },
+    { "MEGABYTE", CONF_MULT1M },
+    { "MEGABYTES", CONF_MULT1M },
+    { "G", CONF_MULT1G },
+    { "GB", CONF_MULT1G },
+    { "GBPS", CONF_MULT1G },
+    { "GBYTE", CONF_MULT1G },
+    { "GBYTES", CONF_MULT1G },
+    { "GIG", CONF_MULT1G },
+    { "GIGABYTE", CONF_MULT1G },
+    { "GIGABYTES", CONF_MULT1G },
+    { "MPS", CONF_MULT1M },
+    { "TAPE", CONF_MULT1 },
+    { "TAPES", CONF_MULT1 },
+    { "WEEK", CONF_MULT7 },
+    { "WEEKS", CONF_MULT7 },
+    { NULL, CONF_IDENT }
+};
+
+int
+get_int(void)
+{
+    int val;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = numb_keytable;
+
+    get_conftoken(CONF_ANY);
+    switch(tok) {
+    case CONF_INT:
+       val = tokenval.v.i;
+       break;
+
+    case CONF_LONG:
+#if SIZEOF_INT < SIZEOF_LONG
+       if ((off_t)tokenval.v.l > (off_t)INT_MAX)
+           conf_parserror("value too large");
+       if ((off_t)tokenval.v.l < (off_t)INT_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (int)tokenval.v.l;
+       break;
+
+    case CONF_SIZE:
+#if SIZEOF_INT < SIZEOF_SSIZE_T
+       if ((off_t)tokenval.v.size > (off_t)INT_MAX)
+           conf_parserror("value too large");
+       if ((off_t)tokenval.v.size < (off_t)INT_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (int)tokenval.v.size;
+       break;
+
+    case CONF_AM64:
+#if SIZEOF_INT < SIZEOF_LONG_LONG
+       if (tokenval.v.am64 > (off_t)INT_MAX)
+           conf_parserror("value too large");
+       if (tokenval.v.am64 < (off_t)INT_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (int)tokenval.v.am64;
+       break;
+
+    case CONF_AMINFINITY:
+       val = INT_MAX;
+       break;
+
+    default:
+       conf_parserror("an int is expected");
+       val = 0;
+       break;
+    }
+
+    /* 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;
+
+    default:   /* it was not a multiplier */
+       unget_conftoken();
+       break;
+    }
+
+    keytable = save_kt;
+    return val;
+}
+
+long
+get_long(void)
+{
+    long val;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = numb_keytable;
+
+    get_conftoken(CONF_ANY);
+
+    switch(tok) {
+    case CONF_LONG:
+       val = tokenval.v.l;
+       break;
+
+    case CONF_INT:
+#if SIZEOF_LONG < SIZEOF_INT
+       if ((off_t)tokenval.v.i > (off_t)LONG_MAX)
+           conf_parserror("value too large");
+       if ((off_t)tokenval.v.i < (off_t)LONG_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (long)tokenval.v.i;
+       break;
+
+    case CONF_SIZE:
+#if SIZEOF_LONG < SIZEOF_SSIZE_T
+       if ((off_t)tokenval.v.size > (off_t)LONG_MAX)
+           conf_parserror("value too large");
+       if ((off_t)tokenval.v.size < (off_t)LONG_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (long)tokenval.v.size;
+       break;
+
+    case CONF_AM64:
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+       if (tokenval.v.am64 > (off_t)LONG_MAX)
+           conf_parserror("value too large");
+       if (tokenval.v.am64 < (off_t)LONG_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (long)tokenval.v.am64;
+       break;
+
+    case CONF_AMINFINITY:
+       val = (long)LONG_MAX;
+       break;
+
+    default:
+       conf_parserror("a long 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 > (LONG_MAX / 7L))
+           conf_parserror("value too large");
+       if (val < (LONG_MIN / 7L))
+           conf_parserror("value too small");
+       val *= 7L;
+       break;
+
+    case CONF_MULT1M:
+       if (val > (LONG_MAX / 1024L))
+           conf_parserror("value too large");
+       if (val < (LONG_MIN / 1024L))
+           conf_parserror("value too small");
+       val *= 1024L;
+       break;
+
+    case CONF_MULT1G:
+       if (val > (LONG_MAX / (1024L * 1024L)))
+           conf_parserror("value too large");
+       if (val < (LONG_MIN / (1024L * 1024L)))
+           conf_parserror("value too small");
+       val *= 1024L * 1024L;
+       break;
+
+    default:   /* it was not a multiplier */
+       unget_conftoken();
+       break;
+    }
+
+    keytable = save_kt;
+    return val;
+}
+
+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 ((off_t)tokenval.v.i > (off_t)SSIZE_MAX)
+           conf_parserror("value too large");
+       if ((off_t)tokenval.v.i < (off_t)SSIZE_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (ssize_t)tokenval.v.i;
+       break;
+
+    case CONF_LONG:
+#if SIZEOF_SIZE_T < SIZEOF_LONG
+       if ((off_t)tokenval.v.l > (off_t)SSIZE_MAX)
+           conf_parserror("value too large");
+       if ((off_t)tokenval.v.l < (off_t)SSIZE_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (ssize_t)tokenval.v.l;
+       break;
+
+    case CONF_AM64:
+#if SIZEOF_SIZE_T < SIZEOF_LONG_LONG
+       if (tokenval.v.am64 > (off_t)SSIZE_MAX)
+           conf_parserror("value too large");
+       if (tokenval.v.am64 < (off_t)SSIZE_MIN)
+           conf_parserror("value too small");
+#endif
+       val = (ssize_t)tokenval.v.am64;
+       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;
+
+    default:   /* it was not a multiplier */
+       unget_conftoken();
+       break;
+    }
+
+    keytable = save_kt;
+    return val;
+}
+
+off_t
+get_am64_t(void)
+{
+    off_t val;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = numb_keytable;
+
+    get_conftoken(CONF_ANY);
+
+    switch(tok) {
+    case CONF_INT:
+       val = (off_t)tokenval.v.i;
+       break;
+
+    case CONF_LONG:
+       val = (off_t)tokenval.v.l;
+       break;
+
+    case CONF_SIZE:
+       val = (off_t)tokenval.v.size;
+       break;
+
+    case CONF_AM64:
+       val = tokenval.v.am64;
+       break;
+
+    case CONF_AMINFINITY:
+       val = AM64_MAX;
+       break;
+
+    default:
+       conf_parserror("an am64 is expected %d", tok);
+       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 > AM64_MAX/7 || val < AM64_MIN/7)
+           conf_parserror("value too large");
+       val *= 7;
+       break;
+
+    case CONF_MULT1M:
+       if (val > AM64_MAX/1024 || val < AM64_MIN/1024)
+           conf_parserror("value too large");
+       val *= 1024;
+       break;
+
+    case CONF_MULT1G:
+       if (val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
+           conf_parserror("value too large");
+       val *= 1024*1024;
+       break;
+
+    default:   /* it was not a multiplier */
+       unget_conftoken();
+       break;
+    }
+
+    keytable = save_kt;
+
+    return val;
+}
+
+keytab_t bool_keytable[] = {
+    { "Y", CONF_ATRUE },
+    { "YES", CONF_ATRUE },
+    { "T", CONF_ATRUE },
+    { "TRUE", CONF_ATRUE },
+    { "ON", CONF_ATRUE },
+    { "N", CONF_AFALSE },
+    { "NO", CONF_AFALSE },
+    { "F", CONF_AFALSE },
+    { "FALSE", CONF_AFALSE },
+    { "OFF", CONF_AFALSE },
+    { NULL, CONF_IDENT }
+};
+
+int
+get_bool(void)
+{
+    int val;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = bool_keytable;
+
+    get_conftoken(CONF_ANY);
+
+    switch(tok) {
+    case CONF_INT:
+       if (tokenval.v.i != 0)
+           val = 1;
+       else
+           val = 0;
+       break;
+
+    case CONF_LONG:
+       if (tokenval.v.l != 0L)
+           val = 1;
+       else
+           val = 0;
+       break;
+
+    case CONF_SIZE:
+       if (tokenval.v.size != (size_t)0)
+           val = 1;
+       else
+           val = 0;
+       break;
+
+    case CONF_AM64:
+       if (tokenval.v.am64 != (off_t)0)
+           val = 1;
+       else
+           val = 0;
+       break;
+
+    case CONF_ATRUE:
+       val = 1;
+       break;
+
+    case CONF_AFALSE:
+       val = 0;
+       break;
+
+    case CONF_NL:
+       unget_conftoken();
+       val = 2; /* no argument - most likely TRUE */
+       break;
+    default:
+       unget_conftoken();
+       val = 3; /* a bad argument - most likely TRUE */
+       conf_parserror("YES, NO, TRUE, FALSE, ON, OFF expected");
+       break;
+    }
+
+    keytable = save_kt;
+    return val;
+}
+
+void
+ckseen(
+    int *seen)
+{
+    if (*seen && !allow_overwrites && conf_line_num != -2) {
+       conf_parserror("duplicate parameter, prev def on line %d", *seen);
+    }
+    *seen = conf_line_num;
+}
+
+printf_arglist_function(void conf_parserror, const char *, format)
+{
+    va_list argp;
+
+    /* print error message */
+
+    if(conf_line)
+       fprintf(stderr, "argument \"%s\": ", conf_line);
+    else
+       fprintf(stderr, "\"%s\", line %d: ", conf_confname, conf_line_num);
+    arglist_start(argp, format);
+    vfprintf(stderr, format, argp);
+    arglist_end(argp);
+    fputc('\n', stderr);
+
+    got_parserror = 1;
+}
+
+tok_t
+lookup_keyword(
+    char *     str)
+{
+    keytab_t *kwp;
+
+    /* switch to binary search if performance warrants */
+
+    for(kwp = keytable; kwp->keyword != NULL; kwp++) {
+       if (strcmp(kwp->keyword, str) == 0) break;
+    }
+    return kwp->token;
+}
+
+char tkbuf[4096];
+
+/* push the last token back (can only unget ANY tokens) */
+void
+unget_conftoken(void)
+{
+    token_pushed = 1;
+    pushed_tok = tok;
+    tok = CONF_UNKNOWN;
+    return;
+}
+
+char
+conftoken_getc(void)
+{
+    if(conf_line == NULL)
+       return getc(conf_conf);
+    if(*conf_char == '\0')
+       return -1;
+    return(*conf_char++);
+}
+
+int
+conftoken_ungetc(
+    int c)
+{
+    if(conf_line == NULL)
+       return ungetc(c, conf_conf);
+    else if(conf_char > conf_line) {
+       if(c == -1)
+           return c;
+       conf_char--;
+       if(*conf_char != c) {
+           error("*conf_char != c   : %c %c", *conf_char, c);
+           /* NOTREACHED */
+       }
+    } else {
+       error("conf_char == conf_line");
+       /* NOTREACHED */
+    }
+    return c;
+}
+
+void
+get_conftoken(
+    tok_t      exp)
+{
+    int ch, d;
+    off_t am64;
+    char *buf;
+    char *tmps;
+    int token_overflow;
+    int inquote = 0;
+    int escape = 0;
+    int sign;
+
+    if (token_pushed) {
+       token_pushed = 0;
+       tok = pushed_tok;
+
+       /*
+       ** If it looked like a key word before then look it
+       ** up again in the current keyword table.
+       */
+       switch(tok) {
+       case CONF_LONG:    case CONF_AM64:    case CONF_SIZE:
+       case CONF_INT:     case CONF_REAL:    case CONF_STRING:
+       case CONF_LBRACE:  case CONF_RBRACE:  case CONF_COMMA:
+       case CONF_NL:      case CONF_END:     case CONF_UNKNOWN:
+       case CONF_TIME:
+           break;
+
+       default:
+           if (exp == CONF_IDENT)
+               tok = CONF_IDENT;
+           else
+               tok = lookup_keyword(tokenval.v.s);
+           break;
+       }
+    }
+    else {
+       ch = conftoken_getc();
+
+       while(ch != EOF && ch != '\n' && isspace(ch))
+           ch = conftoken_getc();
+       if (ch == '#') {        /* comment - eat everything but eol/eof */
+           while((ch = conftoken_getc()) != EOF && ch != '\n') {
+               (void)ch; /* Quiet empty loop complaints */     
+           }
+       }
+
+       if (isalpha(ch)) {              /* identifier */
+           buf = tkbuf;
+           token_overflow = 0;
+           do {
+               if (islower(ch)) ch = toupper(ch);
+               if (buf < tkbuf+sizeof(tkbuf)-1) {
+                   *buf++ = (char)ch;
+               } else {
+                   *buf = '\0';
+                   if (!token_overflow) {
+                       conf_parserror("token too long: %.20s...", tkbuf);
+                   }
+                   token_overflow = 1;
+               }
+               ch = conftoken_getc();
+           } while(isalnum(ch) || ch == '_' || ch == '-');
+
+           if (ch != EOF && conftoken_ungetc(ch) == EOF) {
+               if (ferror(conf_conf)) {
+                   conf_parserror("Pushback of '%c' failed: %s",
+                                  ch, strerror(ferror(conf_conf)));
+               } else {
+                   conf_parserror("Pushback of '%c' failed: EOF", ch);
+               }
+           }
+           *buf = '\0';
+
+           tokenval.v.s = tkbuf;
+
+           if (token_overflow) tok = CONF_UNKNOWN;
+           else if (exp == CONF_IDENT) tok = CONF_IDENT;
+           else tok = lookup_keyword(tokenval.v.s);
+       }
+       else if (isdigit(ch)) { /* integer */
+           sign = 1;
+
+negative_number: /* look for goto negative_number below sign is set there */
+           am64 = 0;
+           do {
+               am64 = am64 * 10 + (ch - '0');
+               ch = conftoken_getc();
+           } while (isdigit(ch));
+
+           if (ch != '.') {
+               if (exp == CONF_INT) {
+                   tok = CONF_INT;
+                   tokenval.v.i = sign * (int)am64;
+               } else if (exp == CONF_LONG) {
+                   tok = CONF_LONG;
+                   tokenval.v.l = (long)sign * (long)am64;
+               } else if (exp != CONF_REAL) {
+                   tok = CONF_AM64;
+                   tokenval.v.am64 = (off_t)sign * am64;
+               } else {
+                   /* automatically convert to real when expected */
+                   tokenval.v.r = (double)sign * (double)am64;
+                   tok = CONF_REAL;
+               }
+           } else {
+               /* got a real number, not an int */
+               tokenval.v.r = sign * (double) am64;
+               am64 = 0;
+               d = 1;
+               ch = conftoken_getc();
+               while (isdigit(ch)) {
+                   am64 = am64 * 10 + (ch - '0');
+                   d = d * 10;
+                   ch = conftoken_getc();
+               }
+               tokenval.v.r += sign * ((double)am64) / d;
+               tok = CONF_REAL;
+           }
+
+           if (ch != EOF &&  conftoken_ungetc(ch) == EOF) {
+               if (ferror(conf_conf)) {
+                   conf_parserror("Pushback of '%c' failed: %s",
+                                  ch, strerror(ferror(conf_conf)));
+               } else {
+                   conf_parserror("Pushback of '%c' failed: EOF", ch);
+               }
+           }
+       } else switch(ch) {
+       case '"':                       /* string */
+           buf = tkbuf;
+           token_overflow = 0;
+           inquote = 1;
+           *buf++ = (char)ch;
+           while (inquote && ((ch = conftoken_getc()) != EOF)) {
+               if (ch == '\n') {
+                   if (!escape)
+                       break;
+                   escape = 0;
+                   buf--; /* Consume escape in buffer */
+               } else if (ch == '\\') {
+                   escape = 1;
+               } else {
+                   if (ch == '"') {
+                       if (!escape)
+                           inquote = 0;
+                   }
+                   escape = 0;
+               }
+
+               if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
+                   if (!token_overflow) {
+                       conf_parserror("string too long: %.20s...", tkbuf);
+                   }
+                   token_overflow = 1;
+                   break;
+               }
+               *buf++ = (char)ch;
+           }
+           *buf = '\0';
+
+           /*
+            * A little manuver to leave a fully unquoted, unallocated  string
+            * in tokenval.v.s
+            */
+           tmps = unquote_string(tkbuf);
+           strncpy(tkbuf, tmps, sizeof(tkbuf));
+           amfree(tmps);
+           tokenval.v.s = tkbuf;
+
+           tok = (token_overflow) ? CONF_UNKNOWN :
+                       (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
+           break;
+
+       case '-':
+           ch = conftoken_getc();
+           if (isdigit(ch)) {
+               sign = -1;
+               goto negative_number;
+           }
+           else {
+               if (ch != EOF && conftoken_ungetc(ch) == EOF) {
+                   if (ferror(conf_conf)) {
+                       conf_parserror("Pushback of '%c' failed: %s",
+                                      ch, strerror(ferror(conf_conf)));
+                   } else {
+                       conf_parserror("Pushback of '%c' failed: EOF", ch);
+                   }
+               }
+               tok = CONF_UNKNOWN;
+           }
+           break;
+
+       case ',':
+           tok = CONF_COMMA;
+           break;
+
+       case '{':
+           tok = CONF_LBRACE;
+           break;
+
+       case '}':
+           tok = CONF_RBRACE;
+           break;
+
+       case '\n':
+           tok = CONF_NL;
+           break;
+
+       case EOF:
+           tok = CONF_END;
+           break;
+
+       default:
+           tok = CONF_UNKNOWN;
+           break;
+       }
+    }
+
+    if (exp != CONF_ANY && tok != exp) {
+       char *str;
+       keytab_t *kwp;
+
+       switch(exp) {
+       case CONF_LBRACE:
+           str = "\"{\"";
+           break;
+
+       case CONF_RBRACE:
+           str = "\"}\"";
+           break;
+
+       case CONF_COMMA:
+           str = "\",\"";
+           break;
+
+       case CONF_NL:
+           str = "end of line";
+           break;
+
+       case CONF_END:
+           str = "end of file";
+           break;
+
+       case CONF_INT:
+           str = "an integer";
+           break;
+
+       case CONF_REAL:
+           str = "a real number";
+           break;
+
+       case CONF_STRING:
+           str = "a quoted string";
+           break;
+
+       case CONF_IDENT:
+           str = "an identifier";
+           break;
+
+       default:
+           for(kwp = keytable; kwp->keyword != NULL; kwp++) {
+               if (exp == kwp->token)
+                   break;
+           }
+           if (kwp->keyword == NULL)
+               str = "token not";
+           else
+               str = kwp->keyword;
+           break;
+       }
+       conf_parserror("%s is expected", str);
+       tok = exp;
+       if (tok == CONF_INT)
+           tokenval.v.i = 0;
+       else
+           tokenval.v.s = "";
+    }
+}
+
+
+void
+read_string(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    get_conftoken(CONF_STRING);
+    val->v.s = newstralloc(val->v.s, tokenval.v.s);
+}
+
+void
+read_ident(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    get_conftoken(CONF_IDENT);
+    val->v.s = newstralloc(val->v.s, tokenval.v.s);
+}
+
+void
+read_int(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    val->v.i = get_int();
+}
+
+void
+read_long(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    val->v.l = get_long();
+}
+
+void
+read_size(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    val->v.size = get_size();
+}
+
+void
+read_am64(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    val->v.am64 = get_am64_t();
+}
+
+void
+read_bool(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    val->v.i = get_bool();
+}
+
+void
+read_real(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    get_conftoken(CONF_REAL);
+    val->v.r = tokenval.v.r;
+}
+
+void
+read_time(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+    val->v.t = get_time();
+}
+
+void
+copy_val_t(
+    val_t *valdst,
+    val_t *valsrc)
+{
+    if(valsrc->seen) {
+       valdst->type = valsrc->type;
+       valdst->seen = valsrc->seen;
+       switch(valsrc->type) {
+       case CONFTYPE_INT:
+       case CONFTYPE_BOOL:
+       case CONFTYPE_COMPRESS:
+       case CONFTYPE_ENCRYPT:
+       case CONFTYPE_HOLDING:
+       case CONFTYPE_ESTIMATE:
+       case CONFTYPE_STRATEGY:
+       case CONFTYPE_TAPERALGO:
+       case CONFTYPE_PRIORITY:
+           valdst->v.i = valsrc->v.i;
+           break;
+
+       case CONFTYPE_LONG:
+           valdst->v.l = valsrc->v.l;
+           break;
+
+       case CONFTYPE_SIZE:
+           valdst->v.size = valsrc->v.size;
+           break;
+
+       case CONFTYPE_AM64:
+           valdst->v.am64 = valsrc->v.am64;
+           break;
+
+       case CONFTYPE_REAL:
+           valdst->v.r = valsrc->v.r;
+           break;
+
+       case CONFTYPE_RATE:
+           valdst->v.rate[0] = valsrc->v.rate[0];
+           valdst->v.rate[1] = valsrc->v.rate[1];
+           break;
+
+       case CONFTYPE_IDENT:
+       case CONFTYPE_STRING:
+           valdst->v.s = stralloc(valsrc->v.s);
+           break;
+
+       case CONFTYPE_TIME:
+           valdst->v.t = valsrc->v.t;
+           break;
+
+       case CONFTYPE_SL:
+           valdst->v.sl = duplicate_sl(valsrc->v.sl);
+           break;
+
+       case CONFTYPE_EXINCLUDE:
+           valdst->v.exinclude.type = valsrc->v.exinclude.type;
+           valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
+           valdst->v.exinclude.sl = duplicate_sl(valsrc->v.exinclude.sl);
+           break;
+       }
+    }
+}
+
+void
+free_val_t(
+    val_t *val)
+{
+    switch(val->type) {
+       case CONFTYPE_INT:
+       case CONFTYPE_BOOL:
+       case CONFTYPE_COMPRESS:
+       case CONFTYPE_ENCRYPT:
+       case CONFTYPE_HOLDING:
+       case CONFTYPE_ESTIMATE:
+       case CONFTYPE_STRATEGY:
+       case CONFTYPE_SIZE:
+       case CONFTYPE_TAPERALGO:
+       case CONFTYPE_PRIORITY:
+       case CONFTYPE_LONG:
+       case CONFTYPE_AM64:
+       case CONFTYPE_REAL:
+       case CONFTYPE_RATE:
+           break;
+
+       case CONFTYPE_IDENT:
+       case CONFTYPE_STRING:
+           amfree(val->v.s);
+           break;
+
+       case CONFTYPE_TIME:
+           break;
+
+       case CONFTYPE_SL:
+           free_sl(val->v.sl);
+           break;
+
+       case CONFTYPE_EXINCLUDE:
+           free_sl(val->v.exinclude.sl);
+           break;
+    }
+    val->seen = 0;
+}
+
+char *
+taperalgo2str(
+    int taperalgo)
+{
+    if(taperalgo == ALGO_FIRST) return "FIRST";
+    if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
+    if(taperalgo == ALGO_LARGEST) return "LARGEST";
+    if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
+    if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
+    if(taperalgo == ALGO_LAST) return "LAST";
+    return "UNKNOWN";
+}
+
+static char buffer_conf_print[1025];
+
+char *
+conf_print(
+    val_t *val)
+{
+    struct tm *stm;
+    int pos;
+
+    buffer_conf_print[0] = '\0';
+    switch(val->type) {
+    case CONFTYPE_INT:
+       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%d", val->v.i);
+       break;
+
+    case CONFTYPE_LONG:
+       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%ld", val->v.l);
+       break;
+
+    case CONFTYPE_SIZE:
+       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), SSIZE_T_FMT,
+               (SSIZE_T_FMT_TYPE)val->v.size);
+       break;
+
+    case CONFTYPE_AM64:
+       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), OFF_T_FMT ,
+                (OFF_T_FMT_TYPE)val->v.am64);
+       break;
+
+    case CONFTYPE_REAL:
+       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%0.5f" , val->v.r);
+       break;
+
+    case CONFTYPE_RATE:
+       snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%0.5f %0.5f" , val->v.rate[0], val->v.rate[1]);
+       break;
+
+    case CONFTYPE_IDENT:
+       if(val->v.s) {
+           strncpy(buffer_conf_print, val->v.s, SIZEOF(buffer_conf_print));
+           buffer_conf_print[SIZEOF(buffer_conf_print) - 1] = '\0';
+       } else
+           buffer_conf_print[0] = '\0';
+       break;
+
+    case CONFTYPE_STRING:
+       buffer_conf_print[0] = '"';
+       if(val->v.s) {
+           strncpy(&buffer_conf_print[1], val->v.s,
+                       SIZEOF(buffer_conf_print) - 1);
+           buffer_conf_print[SIZEOF(buffer_conf_print) - 2] = '\0';
+           buffer_conf_print[strlen(buffer_conf_print)] = '"';
+       } else {
+           buffer_conf_print[1] = '"';
+           buffer_conf_print[2] = '\0';
+       }
+       break;
+
+    case CONFTYPE_TIME:
+       stm = localtime(&val->v.t);
+       if (stm) {
+           snprintf(buffer_conf_print, SIZEOF(buffer_conf_print),
+                    "%d%02d%02d", stm->tm_hour, stm->tm_min, stm->tm_sec);
+       } else {
+           strcpy(buffer_conf_print, "00000");
+       }
+       break;
+
+    case CONFTYPE_SL:
+       buffer_conf_print[0] = '\0';
+       break;
+
+    case CONFTYPE_EXINCLUDE:
+       buffer_conf_print[0] = '\0';
+       if(val->v.exinclude.type == 0)
+           strncpy(buffer_conf_print, "LIST ", SIZEOF(buffer_conf_print));
+       else
+           strncpy(buffer_conf_print, "FILE ", SIZEOF(buffer_conf_print));
+       pos = 5;
+       if(val->v.exinclude.optional == 1)
+           strncpy(&buffer_conf_print[pos], "OPTIONAL ", SIZEOF(buffer_conf_print));
+       pos += 9;
+       break;
+
+    case CONFTYPE_BOOL:
+       if(val->v.i)
+           strncpy(buffer_conf_print, "yes", SIZEOF(buffer_conf_print));
+       else
+           strncpy(buffer_conf_print, "no", SIZEOF(buffer_conf_print));
+       break;
+
+    case CONFTYPE_STRATEGY:
+       switch(val->v.i) {
+       case DS_SKIP:
+           strncpy(buffer_conf_print, "SKIP", SIZEOF(buffer_conf_print));
+           break;
+
+       case DS_STANDARD:
+           strncpy(buffer_conf_print, "STANDARD", SIZEOF(buffer_conf_print));
+           break;
+
+       case DS_NOFULL:
+           strncpy(buffer_conf_print, "NOFULL", SIZEOF(buffer_conf_print));
+           break;
+
+       case DS_NOINC:
+           strncpy(buffer_conf_print, "NOINC", SIZEOF(buffer_conf_print));
+           break;
+
+       case DS_HANOI:
+           strncpy(buffer_conf_print, "HANOI", SIZEOF(buffer_conf_print));
+           break;
+
+       case DS_INCRONLY:
+           strncpy(buffer_conf_print, "INCRONLY", SIZEOF(buffer_conf_print));
+           break;
+       }
+       break;
+
+    case CONFTYPE_COMPRESS:
+       switch(val->v.i) {
+       case COMP_NONE:
+           strncpy(buffer_conf_print, "NONE", SIZEOF(buffer_conf_print));
+           break;
+
+       case COMP_FAST:
+           strncpy(buffer_conf_print, "CLIENT FAST", SIZEOF(buffer_conf_print));
+           break;
+
+       case COMP_BEST:
+           strncpy(buffer_conf_print, "CLIENT BEST", SIZEOF(buffer_conf_print));
+           break;
+
+       case COMP_CUST:
+           strncpy(buffer_conf_print, "CLIENT CUSTOM", SIZEOF(buffer_conf_print));
+           break;
+
+       case COMP_SERV_FAST:
+           strncpy(buffer_conf_print, "SERVER FAST", SIZEOF(buffer_conf_print));
+           break;
+
+       case COMP_SERV_BEST:
+           strncpy(buffer_conf_print, "SERVER FAST", SIZEOF(buffer_conf_print));
+           break;
+
+       case COMP_SERV_CUST:
+           strncpy(buffer_conf_print, "SERVER CUSTOM", SIZEOF(buffer_conf_print));
+           break;
+       }
+       break;
+
+    case CONFTYPE_ESTIMATE:
+       switch(val->v.i) {
+       case ES_CLIENT:
+           strncpy(buffer_conf_print, "CLIENT", SIZEOF(buffer_conf_print));
+           break;
+
+       case ES_SERVER:
+           strncpy(buffer_conf_print, "SERVER", SIZEOF(buffer_conf_print));
+           break;
+
+       case ES_CALCSIZE:
+           strncpy(buffer_conf_print, "CALCSIZE", SIZEOF(buffer_conf_print));
+           break;
+       }
+       break;
+
+     case CONFTYPE_ENCRYPT:
+       switch(val->v.i) {
+       case ENCRYPT_NONE:
+           strncpy(buffer_conf_print, "NONE", SIZEOF(buffer_conf_print));
+           break;
+
+       case ENCRYPT_CUST:
+           strncpy(buffer_conf_print, "CLIENT", SIZEOF(buffer_conf_print));
+           break;
+
+       case ENCRYPT_SERV_CUST:
+           strncpy(buffer_conf_print, "SERVER", SIZEOF(buffer_conf_print));
+           break;
+       }
+       break;
+
+     case CONFTYPE_HOLDING:
+       switch(val->v.i) {
+       case HOLD_NEVER:
+           strncpy(buffer_conf_print, "NEVER", SIZEOF(buffer_conf_print));
+           break;
+
+       case HOLD_AUTO:
+           strncpy(buffer_conf_print, "AUTO", SIZEOF(buffer_conf_print));
+           break;
+
+       case HOLD_REQUIRED:
+           strncpy(buffer_conf_print, "REQUIRED", SIZEOF(buffer_conf_print));
+           break;
+       }
+       break;
+
+     case CONFTYPE_TAPERALGO:
+       strncpy(buffer_conf_print, taperalgo2str(val->v.i), SIZEOF(buffer_conf_print));
+       break;
+
+     case CONFTYPE_PRIORITY:
+       switch(val->v.i) {
+       case 0:
+           strncpy(buffer_conf_print, "LOW", SIZEOF(buffer_conf_print));
+           break;
+
+       case 1:
+           strncpy(buffer_conf_print, "MEDIUM", SIZEOF(buffer_conf_print));
+           break;
+
+       case 2:
+           strncpy(buffer_conf_print, "HIGH", SIZEOF(buffer_conf_print));
+           break;
+       }
+       break;
+    }
+    buffer_conf_print[SIZEOF(buffer_conf_print) - 1] = '\0';
+    return buffer_conf_print;
+}
+
+void
+conf_init_string(
+    val_t *val,
+    char  *s)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_STRING;
+    if(s)
+       val->v.s = stralloc(s);
+    else
+       val->v.s = NULL;
+}
+
+void
+conf_init_ident(
+    val_t *val,
+    char  *s)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_IDENT;
+    if(s)
+       val->v.s = stralloc(s);
+    else
+       val->v.s = NULL;
+}
+
+void
+conf_init_int(
+    val_t *val,
+    int    i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_INT;
+    val->v.i = i;
+}
+
+void
+conf_init_bool(
+    val_t *val,
+    int    i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_BOOL;
+    val->v.i = i;
+}
+
+void
+conf_init_strategy(
+    val_t *val,
+    int    i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_STRATEGY;
+    val->v.i = i;
+}
+
+void
+conf_init_estimate(
+    val_t *val,
+    int    i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_ESTIMATE;
+    val->v.i = i;
+}
+
+void
+conf_init_taperalgo(
+    val_t *val,
+    int    i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_TAPERALGO;
+    val->v.i = i;
+}
+
+void
+conf_init_priority(
+    val_t *val,
+    int    i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_PRIORITY;
+    val->v.i = i;
+}
+
+void
+conf_init_compress(
+    val_t *val,
+    comp_t    i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_COMPRESS;
+    val->v.i = (int)i;
+}
+
+void
+conf_init_encrypt(
+    val_t *val,
+    encrypt_t    i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_ENCRYPT;
+    val->v.i = (int)i;
+}
+
+void
+conf_init_holding(
+    val_t              *val,
+    dump_holdingdisk_t  i)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_HOLDING;
+    val->v.i = (int)i;
+}
+
+void
+conf_init_long(
+    val_t *val,
+    long   l)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_LONG;
+    val->v.l = l;
+}
+
+void
+conf_init_size(
+    val_t *val,
+    ssize_t   sz)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_SIZE;
+    val->v.size = sz;
+}
+
+void
+conf_init_am64(
+    val_t *val,
+    off_t   l)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_AM64;
+    val->v.am64 = l;
+}
+
+void
+conf_init_real(
+    val_t  *val,
+    double r)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_REAL;
+    val->v.r = r;
+}
+
+void
+conf_init_rate(
+    val_t  *val,
+    double r1,
+    double r2)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_RATE;
+    val->v.rate[0] = r1;
+    val->v.rate[1] = r2;
+}
+
+void
+conf_init_time(
+    val_t *val,
+    time_t   t)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_TIME;
+    val->v.t = t;
+}
+
+void
+conf_init_sl(
+    val_t *val,
+    sl_t  *sl)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_AM64;
+    val->v.sl = sl;
+}
+
+void
+conf_init_exinclude(
+    val_t *val)
+{
+    val->seen = 0;
+    val->type = CONFTYPE_EXINCLUDE;
+    val->v.exinclude.type = 0;
+    val->v.exinclude.optional = 0;
+    val->v.exinclude.sl = NULL;
+}
+
+void
+conf_set_string(
+    val_t *val,
+    char *s)
+{
+    val->seen = -1;
+    val->type = CONFTYPE_STRING;
+    amfree(val->v.s);
+    val->v.s = stralloc(s);
+}
+
+void
+conf_set_int(
+    val_t *val,
+    int    i)
+{
+    val->seen = -1;
+    val->type = CONFTYPE_INT;
+    val->v.i = i;
+}
+
+void
+conf_set_bool(
+    val_t *val,
+    int    i)
+{
+    val->seen = -1;
+    val->type = CONFTYPE_BOOL;
+    val->v.i = i;
+}
+
+void
+conf_set_compress(
+    val_t *val,
+    comp_t    i)
+{
+    val->seen = -1;
+    val->type = CONFTYPE_COMPRESS;
+    val->v.i = (int)i;
+}
+
+void
+conf_set_encrypt(
+    val_t *val,
+    encrypt_t    i)
+{
+    val->seen = -1;
+    val->type = CONFTYPE_COMPRESS;
+    val->v.i = (int)i;
+}
+
+void
+conf_set_holding(
+    val_t              *val,
+    dump_holdingdisk_t  i)
+{
+    val->seen = -1;
+    val->type = CONFTYPE_HOLDING;
+    val->v.i = (int)i;
+}
+
+void
+conf_set_strategy(
+    val_t *val,
+    int    i)
+{
+    val->seen = -1;
+    val->type = CONFTYPE_STRATEGY;
+    val->v.i = i;
+}
+
+
+int
+get_conftype_int(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_INT) {
+       error("get_conftype_int: val.type is not CONFTYPE_INT");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+long
+get_conftype_long(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_LONG) {
+       error("get_conftype_long: val.type is not CONFTYPE_LONG");
+       /*NOTREACHED*/
+    }
+    return val->v.l;
+}
+
+off_t
+get_conftype_am64(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_AM64) {
+       error("get_conftype_am64: val.type is not CONFTYPE_AM64");
+       /*NOTREACHED*/
+    }
+    return val->v.am64;
+}
+
+double
+get_conftype_real(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_REAL) {
+       error("get_conftype_real: val.type is not CONFTYPE_REAL");
+       /*NOTREACHED*/
+    }
+    return val->v.r;
+}
+
+char *
+get_conftype_string(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_STRING) {
+       error("get_conftype_string: val.type is not CONFTYPE_STRING");
+       /*NOTREACHED*/
+    }
+    return val->v.s;
+}
+
+char *
+get_conftype_ident(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_IDENT) {
+       error("get_conftype_ident: val.type is not CONFTYPE_IDENT");
+       /*NOTREACHED*/
+    }
+    return val->v.s;
+}
+
+time_t
+get_conftype_time(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_TIME) {
+       error("get_conftype_time: val.type is not CONFTYPE_TIME");
+       /*NOTREACHED*/
+    }
+    return val->v.t;
+}
+
+ssize_t
+get_conftype_size(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_SIZE) {
+       error("get_conftype_size: val.type is not CONFTYPE_SIZE");
+       /*NOTREACHED*/
+    }
+    return val->v.size;
+}
+
+sl_t *
+get_conftype_sl(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_SL) {
+       error("get_conftype_size: val.type is not CONFTYPE_SL");
+       /*NOTREACHED*/
+    }
+    return val->v.sl;
+}
+
+int
+get_conftype_bool(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_BOOL) {
+       error("get_conftype_bool: val.type is not CONFTYPE_BOOL");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+int
+get_conftype_hold(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_HOLDING) {
+       error("get_conftype_hold: val.type is not CONFTYPE_HOLDING");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+int
+get_conftype_compress(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_COMPRESS) {
+       error("get_conftype_compress: val.type is not CONFTYPE_COMPRESS");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+int
+get_conftype_encrypt(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_ENCRYPT) {
+       error("get_conftype_encrypt: val.type is not CONFTYPE_ENCRYPT");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+int
+get_conftype_estimate(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_ESTIMATE) {
+       error("get_conftype_extimate: val.type is not CONFTYPE_ESTIMATE");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+int
+get_conftype_strategy(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_STRATEGY) {
+       error("get_conftype_strategy: val.type is not CONFTYPE_STRATEGY");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+int
+get_conftype_taperalgo(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_TAPERALGO) {
+       error("get_conftype_taperalgo: val.type is not CONFTYPE_TAPERALGO");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+int
+get_conftype_priority(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_PRIORITY) {
+       error("get_conftype_priority: val.type is not CONFTYPE_PRIORITY");
+       /*NOTREACHED*/
+    }
+    return val->v.i;
+}
+
+exinclude_t
+get_conftype_exinclude(
+    val_t *val)
+{
+    if (val->type != CONFTYPE_EXINCLUDE) {
+       error("get_conftype_exinclude: val.type is not CONFTYPE_EXINCLUDE");
+       /*NOTREACHED*/
+    }
+    return val->v.exinclude;
+}
+
+
+void
+dump_sockaddr(
+       struct sockaddr_in *    sa)
+{
+       dbprintf(("%s: (sockaddr_in *)%p = { %d, %hd, %s }\n",
+               debug_prefix(NULL), sa, sa->sin_family, sa->sin_port,
+               inet_ntoa(sa->sin_addr)));
+}
+
+void
+read_block(
+    command_option_t *command_options,
+    t_conf_var    *read_var,
+    keytab_t *keytab,
+    val_t    *valarray,
+    char     *prefix,
+    char     *errormsg,
+    int       read_brace,
+    void      (*copy_function)(void))
+{
+    t_conf_var *np;
+    int    saved_conf_line_num;
+    int    done;
+
+    if(read_brace) {
+       get_conftoken(CONF_LBRACE);
+       get_conftoken(CONF_NL);
+    }
+
+    done = 0;
+    do {
+       conf_line_num += 1;
+       get_conftoken(CONF_ANY);
+       switch(tok) {
+       case CONF_RBRACE:
+           done = 1;
+           break;
+       case CONF_NL:   /* empty line */
+           break;
+       case CONF_END:  /* end of file */
+           done = 1;
+           break;
+        case CONF_IDENT:
+        case CONF_STRING:
+           if(copy_function) 
+               copy_function();
+           else
+               conf_parserror("ident not expected");
+           break;
+       default:
+           {
+               for(np = read_var; np->token != CONF_UNKNOWN; np++)
+                   if(np->token == tok) break;
+
+               if(np->token == CONF_UNKNOWN)
+                   conf_parserror(errormsg);
+               else {
+                   np->read_function(np, &valarray[np->parm]);
+                   if(np->validate)
+                       np->validate(np, &valarray[np->parm]);
+               }
+           }
+       }
+       if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
+           get_conftoken(CONF_NL);
+    } while(!done);
+
+    /* overwrite with command line option */
+    saved_conf_line_num = conf_line_num;
+    command_overwrite(command_options, read_var, keytab, valarray, prefix);
+    conf_line_num = saved_conf_line_num;
+}
+
+void
+command_overwrite(
+    command_option_t *command_options,
+    t_conf_var    *overwrite_var,
+    keytab_t *keytab,
+    val_t    *valarray,
+    char     *prefix)
+{
+    t_conf_var      *np;
+    keytab_t        *kt;
+    char            *myprefix;
+    command_option_t *command_option;
+
+    if(!command_options) return;
+
+    for(np = overwrite_var; np->token != CONF_UNKNOWN; np++) {
+       for(kt = keytab; kt->token != CONF_UNKNOWN; kt++)
+           if(kt->token == np->token) break;
+
+       if(kt->token == CONF_UNKNOWN) {
+           error("read_conf: invalid token");
+           /* NOTREACHED */
+       }
+
+        for(command_option = command_options; command_option->name != NULL;
+                                                           command_option++) {
+           myprefix = stralloc2(prefix, kt->keyword);
+           if(strcasecmp(myprefix, command_option->name) == 0) {
+               command_option->used = 1;
+               valarray[np->parm].seen = -2;
+               if(np->type == CONFTYPE_STRING &&
+                  command_option->value[0] != '"') {
+                   conf_line = vstralloc("\"", command_option->value, "\"",
+                                         NULL);
+               }
+               else {
+                   conf_line = stralloc(command_option->value);
+               }
+               conf_char = conf_line;
+               token_pushed = 0;
+               conf_line_num = -2;
+               np->read_function(np, &valarray[np->parm]);
+               amfree(conf_line);
+               conf_line = conf_char = NULL;
+
+               if(np->validate)
+                   np->validate(np, &valarray[np->parm]);
+           }
+           amfree(myprefix);
+       }
+    }
+}
+
+void
+free_new_argv(
+    int new_argc,
+    char **new_argv)
+{
+    int i;
+    for(i=0; i<new_argc; i++)
+       amfree(new_argv[i]);
+    amfree(new_argv);
+}
+
+
+#ifndef HAVE_LIBREADLINE
+/*
+ * simple readline() replacements
+ */
+
+char *
+readline(
+    const char *prompt)
+{
+    printf("%s", prompt);
+    fflush(stdout);
+    fflush(stderr);
+    return agets(stdin);
+}
+
+void 
+add_history(
+    const char *line)
+{
+    (void)line;        /* Quite unused parameter warning */
+}
+#endif
index 074066d645addf542b290ebc17d2c73b7e7852fd..4ebe39cab50bf78685ff25f4f5edbf21ca8ba2ad 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: util.h,v 1.5 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: util.h,v 1.17 2006/07/26 15:17:36 martinea Exp $
  */
 #ifndef UTIL_H
 #define        UTIL_H
 
+#include "amanda.h"
+#include "sl.h"
+
+/* */
+typedef enum {
+    CONFTYPE_INT,
+    CONFTYPE_LONG,
+    CONFTYPE_AM64,
+    CONFTYPE_REAL,
+    CONFTYPE_STRING,
+    CONFTYPE_IDENT,
+    CONFTYPE_TIME,
+    CONFTYPE_SIZE,
+    CONFTYPE_SL,
+    CONFTYPE_BOOL,
+    CONFTYPE_COMPRESS,
+    CONFTYPE_ENCRYPT,
+    CONFTYPE_HOLDING,
+    CONFTYPE_ESTIMATE,
+    CONFTYPE_STRATEGY,
+    CONFTYPE_TAPERALGO,
+    CONFTYPE_PRIORITY,
+    CONFTYPE_RATE,
+    CONFTYPE_EXINCLUDE,
+} conftype_t;
+
+/* Compression types */
+typedef enum {
+    COMP_NONE,          /* No compression */
+    COMP_FAST,          /* Fast compression on client */
+    COMP_BEST,          /* Best compression on client */
+    COMP_CUST,          /* Custom compression on client */
+    COMP_SERV_FAST,     /* Fast compression on server */
+    COMP_SERV_BEST,     /* Best compression on server */
+    COMP_SERV_CUST      /* Custom compression on server */
+} comp_t;
+
+/* Encryption types */
+typedef enum {
+    ENCRYPT_NONE,               /* No encryption */
+    ENCRYPT_CUST,               /* Custom encryption on client */
+    ENCRYPT_SERV_CUST,          /* Custom encryption on server */
+} encrypt_t;
+
+/* holdingdisk types */
+typedef enum {
+    HOLD_NEVER,                        /* Always direct to tape  */
+    HOLD_AUTO,                 /* If possible            */
+    HOLD_REQUIRED              /* Always to holding disk */
+} dump_holdingdisk_t;
+
+/* Dump strategies */
+#define DS_SKIP                0       /* Don't do any dumps at all */
+#define DS_STANDARD    1       /* Standard (0 1 1 1 1 2 2 2 ...) */
+#define DS_NOFULL      2       /* No full's (1 1 1 ...) */
+#define DS_NOINC       3       /* No inc's (0 0 0 ...) */
+#define DS_4           4       /* ? (0 1 2 3 4 5 6 7 8 9 10 11 ...) */
+#define DS_5           5       /* ? (0 1 1 1 1 1 1 1 1 1 1 1 ...) */
+#define DS_HANOI       6       /* Tower of Hanoi (? ? ? ? ? ...) */
+#define DS_INCRONLY    7       /* Forced fulls (0 1 1 2 2 FORCE0 1 1 ...) */
+
+/* Estimate strategies */
+#define ES_CLIENT      0       /* client estimate */
+#define ES_SERVER      1       /* server estimate */
+#define ES_CALCSIZE    2       /* calcsize estimate */
+
+#define ALGO_FIRST     0
+#define ALGO_FIRSTFIT  1
+#define ALGO_LARGEST   2
+#define ALGO_LARGESTFIT        3
+#define ALGO_SMALLEST  4
+#define ALGO_LAST      5
 
 #define BSTRNCMP(a,b)  strncmp(a, b, strlen(b)) 
-                                                  
                                                  
-ssize_t fullread P((int, void *, size_t));
-ssize_t fullwrite P((int, const void *, size_t));
+typedef enum {
+    CONF_UNKNOWN,              CONF_ANY,               CONF_COMMA,
+    CONF_LBRACE,               CONF_RBRACE,            CONF_NL,
+    CONF_END,                  CONF_IDENT,             CONF_INT,
+    CONF_LONG,                 CONF_AM64,              CONF_BOOL,
+    CONF_REAL,                 CONF_STRING,            CONF_TIME,
+    CONF_SIZE,
+
+    /* config parameters */
+    CONF_INCLUDEFILE,          CONF_ORG,               CONF_MAILTO,
+    CONF_DUMPUSER,             CONF_TAPECYCLE,         CONF_TAPEDEV,
+    CONF_CHNGRDEV,             CONF_CHNGRFILE,         CONF_LABELSTR,
+    CONF_BUMPPERCENT,          CONF_BUMPSIZE,          CONF_BUMPDAYS,
+    CONF_BUMPMULT,             CONF_ETIMEOUT,          CONF_DTIMEOUT,
+    CONF_CTIMEOUT,             CONF_TAPEBUFS,          CONF_TAPELIST,
+    CONF_DISKFILE,             CONF_INFOFILE,          CONF_LOGDIR,
+    CONF_LOGFILE,              CONF_DISKDIR,           CONF_DISKSIZE,
+    CONF_INDEXDIR,             CONF_NETUSAGE,          CONF_INPARALLEL,
+    CONF_DUMPORDER,            CONF_TIMEOUT,           CONF_TPCHANGER,
+    CONF_RUNTAPES,             CONF_DEFINE,            CONF_DUMPTYPE,
+    CONF_TAPETYPE,             CONF_INTERFACE,         CONF_PRINTER,
+    CONF_AUTOFLUSH,            CONF_RESERVE,           CONF_MAXDUMPSIZE,
+    CONF_COLUMNSPEC,           CONF_AMRECOVER_DO_FSF,  CONF_AMRECOVER_CHECK_LABEL,
+    CONF_AMRECOVER_CHANGER,    CONF_LABEL_NEW_TAPES,   CONF_USETIMESTAMPS,
+
+    CONF_TAPERALGO,            CONF_FIRST,             CONF_FIRSTFIT,
+    CONF_LARGEST,              CONF_LARGESTFIT,        CONF_SMALLEST,
+    CONF_LAST,                 CONF_DISPLAYUNIT,
+
+    /* kerberos 5 */
+    CONF_KRB5KEYTAB,           CONF_KRB5PRINCIPAL,
+
+    /* holding disk */
+    CONF_COMMENT,              CONF_DIRECTORY,         CONF_USE,
+    CONF_CHUNKSIZE,
+
+    /* dump type */
+    /*COMMENT,*/               CONF_PROGRAM,           CONF_DUMPCYCLE,
+    CONF_RUNSPERCYCLE,         CONF_MAXCYCLE,          CONF_MAXDUMPS,
+    CONF_OPTIONS,              CONF_PRIORITY,          CONF_FREQUENCY,
+    CONF_INDEX,                        CONF_MAXPROMOTEDAY,     CONF_STARTTIME,
+    CONF_COMPRESS,             CONF_ENCRYPT,           CONF_AUTH,
+    CONF_STRATEGY,             CONF_ESTIMATE,          CONF_SKIP_INCR,
+    CONF_SKIP_FULL,            CONF_RECORD,            CONF_HOLDING,
+    CONF_EXCLUDE,              CONF_INCLUDE,           CONF_KENCRYPT,
+    CONF_IGNORE,               CONF_COMPRATE,          CONF_TAPE_SPLITSIZE,
+    CONF_SPLIT_DISKBUFFER,     CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG,
+    CONF_CLNTCOMPPROG,         CONF_SRV_ENCRYPT,       CONF_CLNT_ENCRYPT,
+    CONF_SRV_DECRYPT_OPT,      CONF_CLNT_DECRYPT_OPT,  CONF_AMANDAD_PATH,
+    CONF_CLIENT_USERNAME,
+
+    /* tape type */
+    /*COMMENT,*/               CONF_BLOCKSIZE,         CONF_FILE_PAD,
+    CONF_LBL_TEMPL,            CONF_FILEMARK,          CONF_LENGTH,
+    CONF_SPEED,
+
+    /* client conf */
+    CONF_CONF,                 CONF_INDEX_SERVER,      CONF_TAPE_SERVER,
+    CONF_SSH_KEYS,             CONF_GNUTAR_LIST_DIR,   CONF_AMANDATES,
+
+    /* network interface */
+    /* COMMENT, */             /* USE, */
+
+    /* dump options (obsolete) */
+    CONF_EXCLUDE_FILE,         CONF_EXCLUDE_LIST,
+
+    /* compress, estimate, encryption */
+    CONF_NONE,                 CONF_FAST,              CONF_BEST,
+    CONF_SERVER,               CONF_CLIENT,            CONF_CALCSIZE,
+    CONF_CUSTOM,
+
+    /* holdingdisk */
+    CONF_NEVER,                        CONF_AUTO,              CONF_REQUIRED,
+
+    /* priority */
+    CONF_LOW,                  CONF_MEDIUM,            CONF_HIGH,
+
+    /* dump strategy */
+    CONF_SKIP,                 CONF_STANDARD,          CONF_NOFULL,
+    CONF_NOINC,                        CONF_HANOI,             CONF_INCRONLY,
+
+    /* exclude list */
+    CONF_LIST,                 CONF_EFILE,             CONF_APPEND,
+    CONF_OPTIONAL,
+
+    /* numbers */
+    CONF_AMINFINITY,           CONF_MULT1,             CONF_MULT7,
+    CONF_MULT1K,               CONF_MULT1M,            CONF_MULT1G,
+
+    /* boolean */
+    CONF_ATRUE,                        CONF_AFALSE,
+
+    CONF_RAWTAPEDEV
+} tok_t;
 
-int bind_portrange P((int, struct sockaddr_in *, int, int, char *));
+#define BIGINT  INT_MAX
+
+/* internal types and variables */
+
+typedef struct {        /* token table entry */
+    char *keyword;
+    tok_t token;
+} keytab_t;
+
+keytab_t *keytable;
+
+typedef struct {
+    char *name;
+    char *value;
+    int   used;
+} command_option_t;
+
+typedef struct exinclude_s {
+    int  type;  /* 0=list   1=file */
+    sl_t *sl;
+    int  optional;
+} exinclude_t;
+
+typedef struct val_s {
+    union {
+       int             i;
+       long            l;
+       off_t           am64;
+       double          r;
+       char            *s;
+       sl_t            *sl;
+       ssize_t         size;
+       time_t          t;
+       float           rate[2];
+       exinclude_t     exinclude;
+    } v;
+    int seen;
+    conftype_t type;
+} val_t;
+
+typedef struct s_conf_var {
+    tok_t      token;
+    conftype_t type;
+    void       (*read_function) (struct s_conf_var *, val_t*);
+    int                parm;
+    void       (*validate) (struct s_conf_var *, val_t *);
+} t_conf_var;
+
+extern int     allow_overwrites;
+extern int     token_pushed;
+
+extern tok_t   tok, pushed_tok;
+extern val_t   tokenval;
+
+extern int     conf_line_num, got_parserror;
+extern FILE    *conf_conf;
+extern char    *conf_confname;
+extern char    *conf_line;
+extern char    *conf_char;
+
+/* predeclare local functions */
+
+t_conf_var  *get_np(t_conf_var *get_var, int parm);
+void   get_simple(val_t *var, tok_t type);
+int    get_int(void);
+long   get_long(void);
+time_t get_time(void);
+ssize_t        get_size(void);
+off_t  get_am64_t(void);
+int    get_bool(void);
+void   ckseen(int *seen);
+void   conf_parserror(const char *format, ...)
+               __attribute__ ((format (printf, 1, 2)));
+tok_t  lookup_keyword(char *str);
+void   unget_conftoken(void);
+void   get_conftoken(tok_t exp);
+
+void read_string(t_conf_var *, val_t *);
+void read_ident(t_conf_var *, val_t *);
+void read_int(t_conf_var *, val_t *);
+void read_long(t_conf_var *, val_t *);
+void read_size(t_conf_var *, val_t *);
+void read_am64(t_conf_var *, val_t *);
+void read_bool(t_conf_var *, val_t *);
+void read_real(t_conf_var *, val_t *);
+void read_time(t_conf_var *, val_t *);
+void copy_val_t(val_t *, val_t *);
+void free_val_t(val_t *);
+char *conf_print(val_t *);
+void conf_init_string(val_t *, char *);
+void conf_init_ident(val_t *, char *);
+void conf_init_int(val_t *, int);
+void conf_init_bool(val_t *, int);
+void conf_init_strategy(val_t *, int);
+void conf_init_estimate(val_t *, int);
+void conf_init_taperalgo(val_t *, int);
+void conf_init_priority(val_t *, int);
+void conf_init_strategy(val_t *, int);
+void conf_init_compress(val_t *, comp_t);
+void conf_init_encrypt(val_t *, encrypt_t);
+void conf_init_holding(val_t *, dump_holdingdisk_t);
+void conf_init_long(val_t *, long);
+void conf_init_size(val_t *, ssize_t);
+void conf_init_am64(val_t *, off_t);
+void conf_init_real(val_t *, double);
+void conf_init_rate(val_t *, double, double);
+void conf_init_time(val_t *, time_t);
+void conf_init_sl(val_t *, sl_t *);
+void conf_init_exinclude(val_t *);
+void conf_set_string(val_t *, char *);
+void conf_set_int(val_t *, int);
+void conf_set_bool(val_t *, int);
+void conf_set_compress(val_t *, comp_t);
+void conf_set_encrypt(val_t *, encrypt_t);
+void conf_set_holding(val_t *, dump_holdingdisk_t);
+void conf_set_strategy(val_t *, int);
+int          get_conftype_int      (val_t *);
+long         get_conftype_long     (val_t *);
+off_t        get_conftype_am64     (val_t *);
+double       get_conftype_real     (val_t *);
+char        *get_conftype_string   (val_t *);
+char        *get_conftype_ident    (val_t *);
+time_t       get_conftype_time     (val_t *);
+ssize_t      get_conftype_size     (val_t *);
+sl_t        *get_conftype_sl       (val_t *);
+int          get_conftype_bool     (val_t *);
+int          get_conftype_hold     (val_t *);
+int          get_conftype_compress (val_t *);
+int          get_conftype_encrypt  (val_t *);
+int          get_conftype_estimate (val_t *);
+int          get_conftype_strategy (val_t *);
+int          get_conftype_taperalgo(val_t *);
+int          get_conftype_priority (val_t *);
+float       *get_conftype_rate     (val_t *);
+exinclude_t  get_conftype_exinclude(val_t *);
+
+void read_block(command_option_t *command_options, t_conf_var *read_var,
+               keytab_t *keytab, val_t *valarray, char *prefix, char *errormsg,
+               int read_brace, void (*copy_function)(void));
+void command_overwrite(command_option_t *command_options, t_conf_var *overwrite_var,
+                      keytab_t *keytab, val_t *valarray, char *prefix);
+
+
+
+ssize_t        fullread(int, void *, size_t);
+ssize_t        fullwrite(int, const void *, size_t);
+
+int    connect_portrange(struct sockaddr_in *, in_port_t, in_port_t, char *,
+                         struct sockaddr_in *, int);
+int    bind_portrange(int, struct sockaddr_in *, in_port_t, in_port_t,
+                      char *);
+
+char * construct_datestamp(time_t *t);
+char * construct_timestamp(time_t *t);
+
+/*@only@*//*@null@*/char *quote_string(const char *str);
+/*@only@*//*@null@*/char *unquote_string(const char *str);
+int    needs_quotes(const char * str);
+
+char * sanitize_string(const char *str);
+char * strquotedstr(void);
+ssize_t        hexdump(const char *buffer, size_t bytes);
+void   dump_sockaddr(struct sockaddr_in *      sa);
+
+/*
+ *   validate_email return 0 if the following characters are present
+ *   * ( ) < > [ ] , ; : ! $ \ / "
+ *   else returns 1
+ */
+int validate_mailto(const char *mailto);
 
-char *construct_datestamp P((time_t *t));
-char *construct_timestamp P((time_t *t));
+char *taperalgo2str(int taperalgo);
 
+void free_new_argv(int new_argc, char **new_argv);
 #endif /* UTIL_H */
index efb8414519d984629122a58024d6a514687043e4..525284a453ee274f6ea22bd410aa624ae4ad59a9 100644 (file)
@@ -1,8 +1,8 @@
 /* version.c - generated by genversion.c - DO NOT EDIT! */
 const char * const version_info[] = {
-  "build: VERSION=\"Amanda-2.5.0p2\"\n",
-  "       BUILT_DATE=\"Mon May 8 07:54:11 EDT 2006\"\n",
-  "       BUILT_MACH=\"Linux modemcable099.122-200-24.mc.videotron.ca 2.6.16-1.2111_FC5 #1 SMP Thu May 4 21:16:04 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux\"\n",
+  "build: VERSION=\"Amanda-2.5.1\"\n",
+  "       BUILT_DATE=\"Tue Sep 5 10:09:05 EDT 2006\"\n",
+  "       BUILT_MACH=\"Linux modemcable197.174-201-24.mc.videotron.ca 2.6.17-1.2174_FC5 #1 SMP Tue Aug 8 15:30:44 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux\"\n",
   "       CC=\"gcc\"\n",
   "       CONFIGURE_COMMAND=\"'./configure' '--prefix=/home/martinea/linux' '--with-configdir=/home/martinea/etc/amanda' '--with-gnutar-listdir=/var/gnutar-lists' '--with-bsd-security' '--with-ssh-security' '--with-rsh-security' '--with-krb4-security' '--without-krb5-security' '--with-user=martinea' '--with-group=martinea' '--mandir=/home/martinea/man'\"\n",
   "paths: bindir=\"/home/martinea/linux/bin\"\n",
@@ -18,14 +18,13 @@ const char * const version_info[] = {
   "       COMPRESS_PATH=\"/usr/bin/gzip\"\n",
   "       UNCOMPRESS_PATH=\"/usr/bin/gzip\" LPRCMD=\"/usr/bin/lpr\"\n",
   "       MAILER=\"/usr/bin/Mail\" listed_incr_dir=\"/var/gnutar-lists\"\n",
-  "defs:  DEFAULT_SERVER=\"modemcable099.122-200-24.mc.videotron.ca\"\n",
+  "defs:  DEFAULT_SERVER=\"modemcable197.174-201-24.mc.videotron.ca\"\n",
   "       DEFAULT_CONFIG=\"DailySet1\"\n",
-  "       DEFAULT_TAPE_SERVER=\"modemcable099.122-200-24.mc.videotron.ca\"\n",
-  "       DEFAULT_TAPE_DEVICE=\"null:\" HAVE_MMAP HAVE_SYSVSHM\n",
-  "       LOCKING=POSIX_FCNTL SETPGRP_VOID DEBUG_CODE\n",
-  "       AMANDA_DEBUG_DAYS=4 BSD_SECURITY RSH_SECURITY USE_AMANDAHOSTS\n",
-  "       CLIENT_LOGIN=\"martinea\" FORCE_USERID HAVE_GZIP\n",
-  "       COMPRESS_SUFFIX=\".gz\" COMPRESS_FAST_OPT=\"--fast\"\n",
+  "       DEFAULT_TAPE_SERVER=\"modemcable197.174-201-24.mc.videotron.ca\"\n",
+  "       HAVE_MMAP HAVE_SYSVSHM LOCKING=POSIX_FCNTL SETPGRP_VOID\n",
+  "       DEBUG_CODE AMANDA_DEBUG_DAYS=4 BSD_SECURITY RSH_SECURITY\n",
+  "       USE_AMANDAHOSTS CLIENT_LOGIN=\"martinea\" FORCE_USERID\n",
+  "       HAVE_GZIP COMPRESS_SUFFIX=\".gz\" COMPRESS_FAST_OPT=\"--fast\"\n",
   "       COMPRESS_BEST_OPT=\"--best\" UNCOMPRESS_OPT=\"-dc\"\n",
   0
 };
index f287767ac17681a165e21c168e6d047ea40edf2e..1ee7cf988f18d258b20770cf7e25200d7782388e 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: version.h,v 1.5 1999/04/16 04:58:58 kashmir Exp $
+ * $Id: version.h,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
  *
  * interface to obtain the current amanda version
  */
@@ -51,9 +51,9 @@ extern const char * const VERSION_COMMENT;
 extern const char * const version_info[];
 
 /* versionsuffix returns an empty string or a string like -2.3.0.4b1.  */
-extern const char *versionsuffix P((void));
+extern const char *versionsuffix(void);
 
 /* version returns a string representing the version of Amanda.  */
-extern const char *version P((void));
+extern const char *version(void);
 
 #endif
index b32588ae6f85f82b340c634222fdea476bbcb091..2cafbd6ddd83b05d2e6d8f389f451850b5dff2c0 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: versuff.c.in,v 1.11 2003/05/20 17:33:53 martinea Exp $
+ * $Id: versuff.c.in,v 1.12 2006/05/25 01:47:12 johnfranks Exp $
  *
  * provide amanda version number and suffix appended to program names
  */
 
 const int   VERSION_MAJOR   = 2;
 const int   VERSION_MINOR   = 5;
-const int   VERSION_PATCH   = 0;
-const char *const VERSION_COMMENT = "p2";
+const int   VERSION_PATCH   = 1;
+const char *const VERSION_COMMENT = "";
 
 const char *
-versionsuffix()
+versionsuffix(void)
 {
 #ifdef USE_VERSION_SUFFIXES
-    return "-2.5.0p2";
+    return "-2.5.1";
 #else
     return "";
 #endif
 }
 
 const char *
-version()
+version(void)
 {
-    return "2.5.0p2";
+    return "2.5.1";
 }
index 572333dbfaaf068d2cfdbad17fd2c35e18ecebaf..7996a2f3c3a8e284da55d21424cb5114b6e96687 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: versuff.c.in,v 1.11 2003/05/20 17:33:53 martinea Exp $
+ * $Id: versuff.c.in,v 1.12 2006/05/25 01:47:12 johnfranks Exp $
  *
  * provide amanda version number and suffix appended to program names
  */
@@ -37,7 +37,7 @@ const int   VERSION_PATCH   = @VERSION_PATCH@;
 const char *const VERSION_COMMENT = @VERSION_COMMENT@;
 
 const char *
-versionsuffix()
+versionsuffix(void)
 {
 #ifdef USE_VERSION_SUFFIXES
     return "-@VERSION_SUFFIX@";
@@ -47,7 +47,7 @@ versionsuffix()
 }
 
 const char *
-version()
+version(void)
 {
     return "@VERSION_SUFFIX@";
 }
index 0ca145e14623c4c5b93c6aeec626f505410e59cc..31f35774835def2e498aa266fa901de4403c7956 100644 (file)
@@ -58,11 +58,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -70,6 +73,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
index 490c6c9db73df885b483bbb6085574f391ba2c8f..7433932bdca5e4002a0fb73fd0ca9d50081f05a9 100644 (file)
 /* Define as the user who owns installed binaries. */
 #undef BINARY_OWNER
 
+/* Define if BSDTCP transport should be enabled. */
+#undef BSDTCP_SECURITY
+
+/* Define if BSDUDP transport should be enabled. */
+#undef BSDUDP_SECURITY
+
 /* Define to use BSD .rhosts/.amandahosts security. */
 #undef BSD_SECURITY
 
 /* Define if atof is declared. */
 #undef HAVE_ATOF_DECL
 
+/* Define to 1 if you have the `atoi' function. */
+#undef HAVE_ATOI
+
+/* Define if atoi is declared. */
+#undef HAVE_ATOI_DECL
+
+/* Define to 1 if you have the `atol' function. */
+#undef HAVE_ATOL
+
+/* Define to 1 if you have the `atoll' function. */
+#undef HAVE_ATOLL
+
+/* Define if atoll is declared. */
+#undef HAVE_ATOLL_DECL
+
+/* Define if atol is declared. */
+#undef HAVE_ATOL_DECL
+
 /* Define to 1 if you have the `basename' function. */
 #undef HAVE_BASENAME
 
 /* Define to 1 if you have the `isascii' function. */
 #undef HAVE_ISASCII
 
+/* Define to 1 if you have the `isnormal' function. */
+#undef HAVE_ISNORMAL
+
+/* Define if isnormal is declared. */
+#undef HAVE_ISNORMAL_DECL
+
 /* Define to 1 if you have the `c' library (-lc). */
 #undef HAVE_LIBC
 
 /* Define to 1 if you have the `dbm' library (-ldbm). */
 #undef HAVE_LIBDBM
 
+/* Define to 1 if you have the `dbmalloc' library (-ldbmalloc). */
+#undef HAVE_LIBDBMALLOC
+
 /* Define to 1 if you have the `gdbm' library (-lgdbm). */
 #undef HAVE_LIBGDBM
 
+/* Define to 1 if you have the <libgen.h> header file. */
+#undef HAVE_LIBGEN_H
+
 /* Define to 1 if you have the `intl' library (-lintl). */
 #undef HAVE_LIBINTL
 
+/* Define to 1 if you have the `krb5support' library (-lkrb5support). */
+#undef HAVE_LIBKRB5SUPPORT
+
 /* Define to 1 if you have the `m' library (-lm). */
 #undef HAVE_LIBM
 
 /* Define to 1 if you have the `nsl' library (-lnsl). */
 #undef HAVE_LIBNSL
 
+/* Define to 1 if you have the `readline' library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
 /* Define to 1 if you have the `resolv' library (-lresolv). */
 #undef HAVE_LIBRESOLV
 
 /* Define if malloc is declared. */
 #undef HAVE_MALLOC_DECL
 
+/* Define to 1 if you have the <math.h> header file. */
+#undef HAVE_MATH_H
+
 /* Define to 1 if you have the `memmove' function. */
 #undef HAVE_MEMMOVE
 
 /* Define to 1 if you have the `statvfs' function. */
 #undef HAVE_STATVFS
 
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
 /* Define if writev is declared. */
 #undef HAVE_WRITEV_DECL
 
+/* xslt is available to generate man pages */
+#undef HAVE_XSLTPROC
+
 /* Define if limits.h defines _POSIX2_RE_DUP_MAX. */
 #undef HAVE__POSIX2_RE_DUP_MAX
 
 /* Format for a long long printf. */
 #undef LL_FMT
 
+/* A comma-separated list of two integers, determining the minimum and maximum
+   reserved TCP port numbers sockets should be bound to. (mainly for
+   amrecover) */
+#undef LOW_TCPPORTRANGE
+
 /* Command for starting printing jobs. */
 #undef LPRCMD
 
 /* The size of a `short', as computed by sizeof. */
 #undef SIZEOF_SHORT
 
+/* The size of a `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The size of a `ssize_t', as computed by sizeof. */
+#undef SIZEOF_SSIZE_T
+
+/* The size of a `time_t', as computed by sizeof. */
+#undef SIZEOF_TIME_T
+
 /* The size of a `void*', as computed by sizeof. */
 #undef SIZEOF_VOIDP
 
 /* Define to use Posix fcntl for file locking. */
 #undef USE_POSIX_FCNTL
 
+/* Define to set SO_REUSEADDR on network connections. */
+#undef USE_REUSEADDR
+
 /* Define to invoke rundump (setuid-root) instead of DUMP program directly. */
 #undef USE_RUNDUMP
 
 /* Define to `int' if <sys/types.h> does not define. */
 #undef pid_t
 
+/* Define if sa_family_t is not a standard system type */
+#undef sa_family_t
+
 /* Directory in which administrator binaries should be installed. */
 #undef sbindir
 
index 387c18d1a135c2e33cb9f911c198efdf7b12b96c..fab0aa3556632a4aec253b77804270a096c11c3e 100755 (executable)
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
 #   Inc.
 
-timestamp='2006-07-02'
+timestamp='2006-09-20'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -276,6 +276,7 @@ case $basic_machine in
        | pdp10 | pdp11 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
        | pyramid \
+       | score \
        | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
        | sh64 | sh64le \
        | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
@@ -284,7 +285,7 @@ case $basic_machine in
        | tahoe | thumb | tic4x | tic80 | tron \
        | v850 | v850e \
        | we32k \
-       | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
        | z8k)
                basic_machine=$basic_machine-unknown
                ;;
@@ -367,7 +368,7 @@ case $basic_machine in
        | tron-* \
        | v850-* | v850e-* | vax-* \
        | we32k-* \
-       | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+       | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
        | xstormy16-* | xtensa-* \
        | ymp-* \
        | z8k-*)
@@ -909,6 +910,10 @@ case $basic_machine in
        sb1el)
                basic_machine=mipsisa64sb1el-unknown
                ;;
+       sde)
+               basic_machine=mipsisa32-sde
+               os=-elf
+               ;;
        sei)
                basic_machine=mips-sei
                os=-seiux
@@ -1366,6 +1371,9 @@ else
 # system, and we'll never get to this point.
 
 case $basic_machine in
+        score-*)
+               os=-elf
+               ;;
         spu-*)
                os=-elf
                ;;
index 4b65cf8ec01a5189fb9b2b25d7049cc6a9aeac16..a2cdb3164be4b4c7e2befb0cec1304f8a05891bd 100755 (executable)
--- a/configure
+++ b/configure
@@ -463,7 +463,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CONFIGURE_COMMAND INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar SNAPSHOT_STAMP VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_COMMENT VERSION_SUFFIX DUMPER_DIR CONFIG_DIR USE_VERSION_SUFFIXES CLIENT_SCRIPTS_OPT DEFAULT_SERVER CLIENT_LOGIN SETUID_GROUP BINARY_OWNER DEFAULT_CONFIG DEFAULT_TAPE_SERVER DEFAULT_TAPE_DEVICE DEFAULT_RAW_TAPE_DEVICE DEFAULT_CHANGER_DEVICE GNUTAR_LISTED_INCREMENTAL_DIRX GNUTAR_LISTED_INCREMENTAL_DIR MAXTAPEBLOCKSIZE AMANDA_TMPDIR AMANDA_DBGDIR AMANDA_DEBUG_DAYS SERVICE_SUFFIX CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE MT_FILE_FLAG CPP EGREP AR AWK_VAR_ASSIGNMENT_OPT YACC CAT COMPRESS DD GETCONF GNUPLOT GREP GNUTAR SAMBA_CLIENT GZIP MAILER MT CHIO CHS MTX MCUTIL PRINT PCAT PERL DUMP RESTORE XFSDUMP XFSRESTORE VXDUMP VXRESTORE VDUMP VRESTORE AMPLOT_COMPRESS AMPLOT_CAT_GZIP AMPLOT_CAT_COMPRESS AMPLOT_CAT_PACK LL_FMT LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBTOOL_DEPS LEX LEXLIB LEX_OUTPUT_ROOT READLINE_LIBS DB_EXT ALLOCA LIBOBJS ac_n ac_c WANT_CLIENT_TRUE WANT_CLIENT_FALSE WANT_SAMBA_TRUE WANT_SAMBA_FALSE WANT_RESTORE_TRUE WANT_RESTORE_FALSE WANT_SERVER_TRUE WANT_SERVER_FALSE WANT_RECOVER_TRUE WANT_RECOVER_FALSE WANT_TAPE_TRUE WANT_TAPE_FALSE WANT_AMPLOT_TRUE WANT_AMPLOT_FALSE WANT_CHG_SCSI_TRUE WANT_CHG_SCSI_FALSE WANT_CHIO_SCSI_TRUE WANT_CHIO_SCSI_FALSE WANT_RUNTIME_PSEUDO_RELOC_TRUE WANT_RUNTIME_PSEUDO_RELOC_FALSE WANT_SETUID_CLIENT_TRUE WANT_SETUID_CLIENT_FALSE WANT_SSH_SECURITY_TRUE WANT_SSH_SECURITY_FALSE LTLIBOBJS LTALLOCA DOC_BUILD_DATE XSLTPROC HAVE_XSLTPROC_TRUE HAVE_XSLTPROC_FALSE'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CONFIGURE_COMMAND INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar SNAPSHOT_STAMP VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_COMMENT VERSION_SUFFIX CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE GREP EGREP AMLINT AMLINTFLAGS DUMPER_DIR CONFIG_DIR USE_VERSION_SUFFIXES CLIENT_SCRIPTS_OPT DEFAULT_SERVER CLIENT_LOGIN SETUID_GROUP BINARY_OWNER DEFAULT_CONFIG DEFAULT_TAPE_SERVER DEFAULT_TAPE_DEVICE DEFAULT_RAW_TAPE_DEVICE DEFAULT_CHANGER_DEVICE GNUTAR_LISTED_INCREMENTAL_DIRX GNUTAR_LISTED_INCREMENTAL_DIR MAXTAPEBLOCKSIZE AMANDA_TMPDIR AMANDA_DBGDIR AMANDA_DEBUG_DAYS SERVICE_SUFFIX MT_FILE_FLAG CPP AR AWK_VAR_ASSIGNMENT_OPT YACC CAT COMPRESS DD GETCONF GNUPLOT GNUTAR SAMBA_CLIENT GZIP MAILER MT CHIO CHS MTX MCUTIL PRINT PCAT PERL DUMP RESTORE XFSDUMP XFSRESTORE VXDUMP VXRESTORE VDUMP VRESTORE AMPLOT_COMPRESS AMPLOT_CAT_GZIP AMPLOT_CAT_COMPRESS AMPLOT_CAT_PACK LL_FMT LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBTOOL_DEPS LEX LEXLIB LEX_OUTPUT_ROOT READLINE_LIBS DB_EXT ALLOCA LIBOBJS ac_n ac_c WANT_CLIENT_TRUE WANT_CLIENT_FALSE WANT_SAMBA_TRUE WANT_SAMBA_FALSE WANT_RESTORE_TRUE WANT_RESTORE_FALSE WANT_SERVER_TRUE WANT_SERVER_FALSE WANT_RECOVER_TRUE WANT_RECOVER_FALSE WANT_TAPE_TRUE WANT_TAPE_FALSE WANT_AMPLOT_TRUE WANT_AMPLOT_FALSE WANT_CHG_SCSI_TRUE WANT_CHG_SCSI_FALSE WANT_CHIO_SCSI_TRUE WANT_CHIO_SCSI_FALSE WANT_RUNTIME_PSEUDO_RELOC_TRUE WANT_RUNTIME_PSEUDO_RELOC_FALSE WANT_SETUID_CLIENT_TRUE WANT_SETUID_CLIENT_FALSE WANT_SSH_SECURITY_TRUE WANT_SSH_SECURITY_FALSE LTLIBOBJS LTALLOCA DOC_BUILD_DATE BUILD_MAN_PAGES_TRUE BUILD_MAN_PAGES_FALSE XSLTPROC HAVE_XSLTPROC_TRUE HAVE_XSLTPROC_FALSE AM_CFLAGS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -1026,6 +1026,7 @@ Optional Features:
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --disable-dependency-tracking  speeds up one-time build
   --enable-dependency-tracking   do not reject slow dependency extractors
+  --disable-largefile     omit support for large files
   --enable-shared[=PKGS]
                           build shared libraries [default=yes]
   --enable-static[=PKGS]
@@ -1033,7 +1034,6 @@ Optional Features:
   --enable-fast-install[=PKGS]
                           optimize for fast installation [default=yes]
   --disable-libtool-lock  avoid locking (might break parallel builds)
-  --disable-largefile     omit support for large files
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1068,6 +1068,7 @@ Optional Packages:
   --with-changer-device=ARG default tape changer device [/dev/ch0 if it exists]
   --with-fqdn            use FQDN's to backup multiple networks
   --with-broken-fsf      only enable if tape fsf calls fail mid-file
+  --without-reuseaddr    Don't closed network connections to be reused until full timeout period.
   --with-gnutar[=PROG]      use PROG as GNU tar executable [default: looks for one]
   --with-smbclient[=PROG]   use PROG as Samba's smbclient executable [default: looks for one]
   --with-samba-user was deprecated
@@ -1079,6 +1080,8 @@ Optional Packages:
   --with-krb4-security=DIR   Location of Kerberos software [/usr/kerberos /usr/cygnus /usr /opt/kerberos]
   --with-rsh-security use rsh as a transport
   --with-ssh-security use ssh as a transport
+  --with-bsdtcp-security use tcp as a transport
+  --with-bsdudp-security use tcp as a transport
     --with-server-principal=ARG    server host principal  ["amanda"]
     --with-server-instance=ARG     server host instance   ["amanda"]
     --with-server-keyfile=ARG      server host key file   ["/.amanda"]
@@ -1087,7 +1090,7 @@ Optional Packages:
     --with-client-keyfile=ARG      client host key file   [KEYFILE]
     --with-ticket-lifetime=ARG     ticket lifetime        [128]
   --with-krb5-security=DIR   Location of Kerberos V software [/usr/kerberos /usr/cygnus /usr /opt/kerberos]
-  --with-portrange=low,high     bind unreserved TCP server sockets to ports within this range [unlimited]
+  --with-low-tcpportrange=low,high     bind reserved TCP server sockets to ports within this range unlimited (mainly for amrecover)
   --with-tcpportrange=low,high  bind unreserved TCP server sockets to ports within this range [unlimited]
   --with-udpportrange=low,high  bind reserved UDP server sockets to ports within this range [unlimited]
   --with-maxtapeblocksize=kb            Maximum size of a tape block
@@ -1962,7 +1965,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=amanda
- VERSION=2.5.0p2
+ VERSION=2.5.1
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2127,7 +2130,7 @@ VERSION_SUFFIX="$VERSION"
 
 
 
-SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
+SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/opt/SUNWspro/bin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
 LOCPATH=`(
     test "x$prefix" = xNONE && prefix=$ac_default_prefix
     test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
@@ -2137,14 +2140,15 @@ SYSLOCPATH="$SYSPATH:$LOCPATH"
 LOCSYSPATH="$LOCPATH:$SYSPATH"
 
 
+
 # Check whether --with-cflags or --without-cflags was given.
 if test "${with_cflags+set}" = set; then
   withval="$with_cflags"
 
        case "$withval" in
        "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-includes option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-includes option." >&2;}
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-cflags option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-cflags option." >&2;}
    { (exit 1); exit 1; }; }
            ;;
        esac
@@ -2152,2506 +2156,2695 @@ echo "$as_me: error: *** You must supply an argument to the --with-includes opti
 
 fi;
 
+CFLAGS="-D_GNU_SOURCE $CFLAGS"
 
-# Check whether --with-includes or --without-includes was given.
-if test "${with_includes+set}" = set; then
-  withval="$with_includes"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-includes option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-includes option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       esac
-       INCLUDE_DIRS="$withval"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
-fi;
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-if test "$INCLUDE_DIRS"; then
-       for dir in $INCLUDE_DIRS; do
-           if test -d "$dir"; then
-               AMANDA_CPPFLAGS="$AMANDA_CPPFLAGS -I$dir"
-           else
-               { echo "$as_me:$LINENO: WARNING: *** Include directory $dir does not exist." >&5
-echo "$as_me: WARNING: *** Include directory $dir does not exist." >&2;}
-           fi
-       done
 fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-# Check whether --with-libraries or --without-libraries was given.
-if test "${with_libraries+set}" = set; then
-  withval="$with_libraries"
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
 
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-libraries option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-libraries option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       esac
-       LIBRARY_DIRS="$withval"
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
-fi;
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-if test "$LIBRARY_DIRS"; then
-       for dir in $LIBRARY_DIRS; do
-           if test -d "$dir"; then
-               case "$target" in
-                 *-solaris2*,*-netbsd*)
-                       AMANDA_LDFLAGS="$AMANDA_LDFLAGS -R$dir"
-                       ;;
-               esac
-               AMANDA_LDFLAGS="$AMANDA_LDFLAGS -L$dir"
-           else
-               { echo "$as_me:$LINENO: WARNING: *** Library directory $dir does not exist." >&5
-echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;}
-           fi
-       done
 fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-# Check whether --with-dumperdir or --without-dumperdir was given.
-if test "${with_dumperdir+set}" = set; then
-  withval="$with_dumperdir"
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
 
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-dumperdir option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-dumperdir option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       esac
-       DUMPER_DIR="$withval"
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-        test "x$prefix" = xNONE && prefix=$ac_default_prefix
-        test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
-        DUMPER_DIR=$exec_prefix/dumper
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-fi;
-DUMPER_DIR=`(
-    test "x$prefix" = xNONE && prefix=$ac_default_prefix
-    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
-    eval echo "$DUMPER_DIR"
-)`
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
-cat >>confdefs.h <<_ACEOF
-#define DUMPER_DIR "$DUMPER_DIR"
-_ACEOF
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
+  test -n "$ac_ct_CC" && break
+done
 
+  CC=$ac_ct_CC
+fi
 
+fi
 
-# Check whether --with-configdir or --without-configdir was given.
-if test "${with_configdir+set}" = set; then
-  withval="$with_configdir"
 
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-configdir option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-configdir option." >&2;}
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
-         ;;
-       *) CONFIG_DIR="$withval"
-         ;;
-       esac
-
-else
-  : ${CONFIG_DIR="$sysconfdir/amanda"}
 
-fi;
-CONFIG_DIR=`(
-    test "x$prefix" = xNONE && prefix=$ac_default_prefix
-    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
-    eval echo "$CONFIG_DIR"
-)`
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
 
-cat >>confdefs.h <<_ACEOF
-#define CONFIG_DIR "$CONFIG_DIR"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
+int
+main ()
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
 
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-# Check whether --with-indexdir or --without-indexdir was given.
-if test "${with_indexdir+set}" = set; then
-  withval="$with_indexdir"
-     { { echo "$as_me:$LINENO: error: *** --with-indexdir is deprecated, use indexdir in amanda.conf instead." >&5
-echo "$as_me: error: *** --with-indexdir is deprecated, use indexdir in amanda.conf instead." >&2;}
-   { (exit 1); exit 1; }; }
-
-fi;
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
 
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
 
-# Check whether --with-dbdir or --without-dbdir was given.
-if test "${with_dbdir+set}" = set; then
-  withval="$with_dbdir"
-     { { echo "$as_me:$LINENO: error: *** --with-dbdir is deprecated, use infofile in amanda.conf instead." >&5
-echo "$as_me: error: *** --with-dbdir is deprecated, use infofile in amanda.conf instead." >&2;}
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
 
-fi;
-
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
 
-# Check whether --with-logdir or --without-logdir was given.
-if test "${with_logdir+set}" = set; then
-  withval="$with_logdir"
-     { { echo "$as_me:$LINENO: error: *** --with-logdir is deprecated, use logdir in amanda.conf instead." >&5
-echo "$as_me: error: *** --with-logdir is deprecated, use logdir in amanda.conf instead." >&2;}
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
+fi
 
-fi;
-
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
 
-# Check whether --with-suffixes or --without-suffixes was given.
-if test "${with_suffixes+set}" = set; then
-  withval="$with_suffixes"
-  USE_VERSION_SUFFIXES=$withval
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  : ${USE_VERSION_SUFFIXES=no}
-
-fi;
-case "$USE_VERSION_SUFFIXES" in
-y | ye | yes)
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_VERSION_SUFFIXES 1
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
+int
+main ()
+{
 
-    program_suffix="-$VERSION"
-    # This is from the output of configure.in.
-    if test "x$program_transform_name" = xs,x,x,; then
-       program_transform_name=
-    else
-       # Double any \ or $.  echo might interpret backslashes.
-       cat <<\EOF_SED > conftestsed
-s,\\,\\\\,g; s,\$,$$,g
-EOF_SED
-       program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
-       rm -f conftestsed
-    fi
-    test "x$program_prefix" != xNONE &&
-       program_transform_name="s,^,${program_prefix},; $program_transform_name"
-    # Use a double $ so make ignores it.
-    test "x$program_suffix" != xNONE &&
-       program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-    # sed with no file args requires a program.
-    test "x$program_transform_name" = "" && program_transform_name="xs,x,x,"
-    # Remove empty command
-    cat <<\EOF_SED > conftestsed
-s,\;\;,\;,g; s,\; \$,,g; s,\;$,,g
-EOF_SED
-    program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
-    rm -f conftestsed
-  ;;
-n | no) USE_VERSION_SUFFIXES=no
-  ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-suffixes option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-suffixes option." >&2;}
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
-  ;;
-esac
-
-
-case "$target" in
-    *-hp-*)
-       CLIENT_SCRIPTS_OPT=amhpfixdevs
-       ;;
-    *-sni-sysv4)
-       CLIENT_SCRIPTS_OPT=amsinixfixdevs
-       ;;
-    *)
-       CLIENT_SCRIPTS_OPT=
-       ;;
-esac
-
+fi
 
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
 
-# Check whether --with-client-only or --without-client-only was given.
-if test "${with_client_only+set}" = set; then
-  withval="$with_client_only"
-     { { echo "$as_me:$LINENO: error: *** --with-client-only is deprecated, use --without-server instead." >&5
-echo "$as_me: error: *** --with-client-only is deprecated, use --without-server instead." >&2;}
-   { (exit 1); exit 1; }; }
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-fi;
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
-# Check whether --with-server-only or --without-server-only was given.
-if test "${with_server_only+set}" = set; then
-  withval="$with_server_only"
-     { { echo "$as_me:$LINENO: error: *** --with-server-only is deprecated, use --without-client instead." >&5
-echo "$as_me: error: *** --with-server-only is deprecated, use --without-client instead." >&2;}
-   { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
-fi;
+int
+main ()
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-# Check whether --with-client or --without-client was given.
-if test "${with_client+set}" = set; then
-  withval="$with_client"
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
 
-       case "$withval" in
-       y | ye | yes) NO_CLIENT_MODE=false;;
-       n | no) NO_CLIENT_MODE=true;;
-       *)
-           { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-client option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-client option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       esac
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
 
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-fi;
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
 
+fi
 
-# Check whether --with-server or --without-server was given.
-if test "${with_server+set}" = set; then
-  withval="$with_server"
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
 
-       case "$withval" in
-       y | ye | yes) NO_SERVER_MODE=false ;;
-       n | no) NO_SERVER_MODE=true;NO_RESTORE_MODE=true;;
-       *)
-           { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-server option.  Maybe you meant --with-index-server=$withval" >&5
-echo "$as_me: error: *** You must not supply an argument to --with-server option.  Maybe you meant --with-index-server=$withval" >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       esac
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-fi;
-if test "x${NO_SERVER_MODE+set}" != xset ; then
-   NO_SERVER_MODE=false
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
 fi
 
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-# Check whether --with-restore or --without-restore was given.
-if test "${with_restore+set}" = set; then
-  withval="$with_restore"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
 
-       case "$withval" in
-       y | ye | yes) NO_RESTORE_MODE=false;;
-       n | no) NO_RESTORE_MODE=true;;
-       *)
-           { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-restore option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-restore option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       esac
+          ac_config_commands="$ac_config_commands depfiles"
 
 
-fi;
-if test "x${NO_RESTORE_MODE+set}" != xset ; then
-   NO_RESTORE_MODE=${NO_SERVER_MODE-false}
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
 fi
-
-if ${NO_SERVER_MODE-false}; then
-   if ${NO_RESTORE_MODE-false}; then
-                        true
-   else
-      { { echo "$as_me:$LINENO: error: *** --without-server requires --without-restore" >&5
-echo "$as_me: error: *** --without-server requires --without-restore" >&2;}
-   { (exit 1); exit 1; }; }
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
    fi
 fi
 
 
-# Check whether --with-amrecover or --without-amrecover was given.
-if test "${with_amrecover+set}" = set; then
-  withval="$with_amrecover"
-
-       case "$withval" in
-       y | ye | yes)
-           if ${NO_CLIENT_MODE-false}; then
-               { { echo "$as_me:$LINENO: error: *** --without-client and --with-amrecover are incompatible" >&5
-echo "$as_me: error: *** --without-client and --with-amrecover are incompatible" >&2;}
-   { (exit 1); exit 1; }; }
-           fi
-           NO_RECOVER_MODE=false;;
-       n | no) NO_RECOVER_MODE=true;;
-       *)
-           { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-amrecover option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-amrecover option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       esac
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
 
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+  enableval="$enable_dependency_tracking"
 
 fi;
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
 
 
-# Check whether --with-index-server or --without-index-server was given.
-if test "${with_index_server+set}" = set; then
-  withval="$with_index_server"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-index-server option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-index-server option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *) DEFAULT_SERVER="$withval"
-         ;;
-       esac
-
+if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
 else
-  : ${DEFAULT_SERVER=`uname -n`}
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
 
-fi;
-
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_SERVER "$DEFAULT_SERVER"
-_ACEOF
 
 
 
+depcc="$CC"   am_compiler_list=
 
-# Check whether --with-force-uid or --without-force-uid was given.
-if test "${with_force_uid+set}" = set; then
-  withval="$with_force_uid"
-  FORCE_USERID="$withval"
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  : ${FORCE_USERID=yes}
-
-fi;
-case "$FORCE_USERID" in
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define FORCE_USERID 1
-_ACEOF
-
-  ;;
-n | no) :
-  ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-force-uid option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-force-uid option." >&2;}
-   { (exit 1); exit 1; }; }
-esac
-
-
-# Check whether --with-user or --without-user was given.
-if test "${with_user+set}" = set; then
-  withval="$with_user"
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
 
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-user option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-user option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *) CLIENT_LOGIN="$withval"
-         ;;
-       esac
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
 
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
 
-fi;
-if test "x${CLIENT_LOGIN+set}" != xset; then
-    { { echo "$as_me:$LINENO: error: *** --with-user=USER is missing" >&5
-echo "$as_me: error: *** --with-user=USER is missing" >&2;}
-   { (exit 1); exit 1; }; }
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
 fi
 
-cat >>confdefs.h <<_ACEOF
-#define CLIENT_LOGIN "$CLIENT_LOGIN"
-_ACEOF
-
-
-
-
-# Check whether --with-group or --without-group was given.
-if test "${with_group+set}" = set; then
-  withval="$with_group"
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
 
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-group option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-group option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *) SETUID_GROUP="$withval"
-         ;;
-       esac
 
 
-fi;
-if test "x${SETUID_GROUP+set}" != xset; then
-    { { echo "$as_me:$LINENO: error: *** --with-group=GROUP is missing" >&5
-echo "$as_me: error: *** --with-group=GROUP is missing" >&2;}
-   { (exit 1); exit 1; }; }
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
 fi
 
 
 
-# Check whether --with-owner or --without-owner was given.
-if test "${with_owner+set}" = set; then
-  withval="$with_owner"
 
-        case "$withval" in
-        "" | y | ye | yes | n | no)
-            { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-owner option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-owner option." >&2;}
-   { (exit 1); exit 1; }; }
-          ;;
-        *) BINARY_OWNER="$withval"
-          ;;
-        esac
 
+# Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+  enableval="$enable_largefile"
 
 fi;
-if test "x${BINARY_OWNER+set}" != xset ; then
-   BINARY_OWNER=$CLIENT_LOGIN
-fi
+if test "$enable_largefile" != no; then
 
-cat >>confdefs.h <<_ACEOF
-#define BINARY_OWNER "$BINARY_OWNER"
+  echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+        # IRIX 6.2 and later do not support large files by default,
+        # so use the C compiler's -n32 option if that helps.
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+        rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+fi
+rm -f conftest.err conftest.$ac_objext
+        CC="$CC -n32"
+        rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_largefile_CC=' -n32'; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+fi
+rm -f conftest.err conftest.$ac_objext
+        break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
 
-# Check whether --with-rundump or --without-rundump was given.
-if test "${with_rundump+set}" = set; then
-  withval="$with_rundump"
-
-    case "$withval" in
-       n | no | y | ye | yes) FORCE_USE_RUNDUMP="$withval";;
-       *) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-rundump option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-rundump option." >&2;}
-   { (exit 1); exit 1; }; };;
-    esac
-
-
-fi;
-
-
-# Check whether --with-config or --without-config was given.
-if test "${with_config+set}" = set; then
-  withval="$with_config"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-config option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-config option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *) DEFAULT_CONFIG="$withval"
-         ;;
-       esac
-
+  echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  : ${DEFAULT_CONFIG=DailySet1}
-
-fi;
-
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_CONFIG "$DEFAULT_CONFIG"
+  while :; do
+  ac_cv_sys_file_offset_bits=no
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
 
-
-# Check whether --with-tape-server or --without-tape-server was given.
-if test "${with_tape_server+set}" = set; then
-  withval="$with_tape_server"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-tape-server option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-tape-server option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *) DEFAULT_TAPE_SERVER="$withval"
-         ;;
-       esac
-
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_file_offset_bits=64; break
 else
-  : ${DEFAULT_TAPE_SERVER=$DEFAULT_SERVER}
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-fi;
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
+if test "$ac_cv_sys_file_offset_bits" != no; then
 
 cat >>confdefs.h <<_ACEOF
-#define DEFAULT_TAPE_SERVER "$DEFAULT_TAPE_SERVER"
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
 _ACEOF
 
-
-
-
-# Check whether --with-tape-device or --without-tape-device was given.
-if test "${with_tape_device+set}" = set; then
-  withval="$with_tape_device"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-tape-device option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-tape-device option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *) DEFAULT_TAPE_DEVICE="$withval"
-         ;;
-       esac
-
+fi
+rm -f conftest*
+  echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_large_files+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
+  while :; do
+  ac_cv_sys_large_files=no
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
 
-       if test -z "$DEFAULT_TAPE_DEVICE"; then
-           echo "$as_me:$LINENO: checking for non-rewinding tape device" >&5
-echo $ECHO_N "checking for non-rewinding tape device... $ECHO_C" >&6
-                                                                   tape_dev=null:
-           nr_tape_dev=null:
-           if test -d /dev/rmt; then
-
-
-               for num in 9 8 7 6 5 4 3 2 1 0; do
-                   td=/dev/rmt/${num}b
-                   ntd=/dev/rmt/${num}bn
-                   if test -r $td -a -r $ntd; then
-                       tape_dev=$td
-                       nr_tape_dev=$ntd
-                   fi
-               done
-           else
-                               for num in 9 8 7 6 5 4 3 2 1 0; do
-                   td=/dev/rst${num}
-                   ntd=/dev/nrst${num}
-                   if test -r $td -a -r $ntd; then
-                       tape_dev=$td
-                       nr_tape_dev=$ntd
-                   fi
-               done
-           fi
-           DEFAULT_TAPE_DEVICE=$nr_tape_dev
-           echo "$as_me:$LINENO: result: $DEFAULT_TAPE_DEVICE" >&5
-echo "${ECHO_T}$DEFAULT_TAPE_DEVICE" >&6
-       fi
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
 
-fi;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_large_files=1; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-if test -z "$DEFAULT_TAPE_DEVICE"; then
-    DEFAULT_TAPE_DEVICE=/dev/null
 fi
-
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6
+if test "$ac_cv_sys_large_files" != no; then
 
 cat >>confdefs.h <<_ACEOF
-#define DEFAULT_TAPE_DEVICE "$DEFAULT_TAPE_DEVICE"
+#define _LARGE_FILES $ac_cv_sys_large_files
 _ACEOF
 
+fi
+rm -f conftest*
+fi
 
 
-
-# Check whether --with-ftape-raw-device or --without-ftape-raw-device was given.
-if test "${with_ftape_raw_device+set}" = set; then
-  withval="$with_ftape_raw_device"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-ftape-rawdevice option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-ftape-rawdevice option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *) DEFAULT_RAW_TAPE_DEVICE="$withval"
-         ;;
-       esac
-
+for ac_prog in grep
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
+  case $GREP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GREP="$GREP" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
-       if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
-           echo "$as_me:$LINENO: checking for raw ftape device" >&5
-echo $ECHO_N "checking for raw ftape device... $ECHO_C" >&6
-                   raw_tape_dev=/dev/null
-                               for num in 3 2 1 0 ; do
-                   td=/dev/rawft${num}
-                   if test -r $td; then
-                       raw_tape_dev=$td
-                   fi
-               done
-           DEFAULT_RAW_TAPE_DEVICE=$raw_tape_dev
-           echo "$as_me:$LINENO: result: $DEFAULT_RAW_TAPE_DEVICE" >&5
-echo "${ECHO_T}$DEFAULT_RAW_TAPE_DEVICE" >&6
-       fi
+  ;;
+esac
+fi
+GREP=$ac_cv_path_GREP
 
+if test -n "$GREP"; then
+  echo "$as_me:$LINENO: result: $GREP" >&5
+echo "${ECHO_T}$GREP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-fi;
+  test -n "$GREP" && break
+done
 
-if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
-    DEFAULT_RAW_TAPE_DEVICE=/dev/null
+if test -z "$GREP"; then
+    GREP=grep
 fi
 
-
 cat >>confdefs.h <<_ACEOF
-#define DEFAULT_RAW_TAPE_DEVICE "$DEFAULT_RAW_TAPE_DEVICE"
+#define GREP "$GREP"
 _ACEOF
 
-
-
-
-# Check whether --with-rew-tape or --without-rew-tape was given.
-if test "${with_rew_tape+set}" = set; then
-  withval="$with_rew_tape"
-     { { echo "$as_me:$LINENO: error: *** --with-rew-tape is deprecated, use --with-tape-device instead." >&5
-echo "$as_me: error: *** --with-rew-tape is deprecated, use --with-tape-device instead." >&2;}
-   { (exit 1); exit 1; }; }
-
-fi;
-
-
-# Check whether --with-norew-tape or --without-norew-tape was given.
-if test "${with_norew_tape+set}" = set; then
-  withval="$with_norew_tape"
-     { { echo "$as_me:$LINENO: error: *** --with-norew-tape is deprecated, use --with-tape-device instead." >&5
-echo "$as_me: error: *** --with-norew-tape is deprecated, use --with-tape-device instead." >&2;}
-   { (exit 1); exit 1; }; }
-
-fi;
-
-
-# Check whether --with-changer-device or --without-changer-device was given.
-if test "${with_changer_device+set}" = set; then
-  withval="$with_changer_device"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-changer-device option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-changer-device option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *) DEFAULT_CHANGER_DEVICE="$withval"
-         ;;
-       esac
-
+for ac_prog in egrep
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
+  case $EGREP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_EGREP="$EGREP" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_EGREP="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
-       if test -z "$DEFAULT_CHANGER_DEVICE" &&
-          test -f /dev/ch0; then
-           DEFAULT_CHANGER_DEVICE=/dev/ch0
-       fi
-
-
-fi;
-
-if test -z "$DEFAULT_CHANGER_DEVICE"; then
-    DEFAULT_CHANGER_DEVICE=/dev/null
+  ;;
+esac
 fi
+EGREP=$ac_cv_path_EGREP
 
+if test -n "$EGREP"; then
+  echo "$as_me:$LINENO: result: $EGREP" >&5
+echo "${ECHO_T}$EGREP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_CHANGER_DEVICE "$DEFAULT_CHANGER_DEVICE"
-_ACEOF
+  test -n "$EGREP" && break
+done
 
 
+for ac_prog in lint
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AMLINT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $AMLINT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_AMLINT="$AMLINT" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="/opt/SUNWspro/bin:$SYSLOCPATH"
+for as_dir in $as_dummy
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_AMLINT="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
+  ;;
+esac
+fi
+AMLINT=$ac_cv_path_AMLINT
 
-# Check whether --with-fqdn or --without-fqdn was given.
-if test "${with_fqdn+set}" = set; then
-  withval="$with_fqdn"
-  USE_FQDN=$withval
+if test -n "$AMLINT"; then
+  echo "$as_me:$LINENO: result: $AMLINT" >&5
+echo "${ECHO_T}$AMLINT" >&6
 else
-  : ${USE_FQDN=no}
-
-fi;
-case "$USE_FQDN" in
-n | no) : ;;
-y |  ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define USE_FQDN 1
-_ACEOF
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
+  test -n "$AMLINT" && break
+done
+
+if test ! -z "$AMLINT"; then
+  $AMLINT -flags | $GREP -- '-errfmt=' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AMLINTFLAGS="-n -s -u -m -x"
+    AMLINTFLAGS="$AMLINTFLAGS -errchk=%all"
+    AMLINTFLAGS="$AMLINTFLAGS -errfmt=macro"
+    AMLINTFLAGS="$AMLINTFLAGS -errhdr=no%/usr/include"
+    AMLINTFLAGS="$AMLINTFLAGS -errhdr=%user"
+    AMLINTFLAGS="$AMLINTFLAGS -errsecurity=extended"
+    AMLINTFLAGS="$AMLINTFLAGS -errtags=yes"
+    AMLINTFLAGS="$AMLINTFLAGS -Ncheck=%all"
+    AMLINTFLAGS="$AMLINTFLAGS -Nlevel=2"
+    AMLINTFLAGS="$AMLINTFLAGS -erroff=E_ASGN_NEVER_USED"
+    AMLINTFLAGS="$AMLINTFLAGS,E_ASGN_RESET"
+    AMLINTFLAGS="$AMLINTFLAGS,E_CAST_INT_CONST_TO_SMALL_INT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_CAST_INT_TO_SMALL_INT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_CAST_UINT_TO_SIGNED_INT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_CONSTANT_CONDITION"
+    AMLINTFLAGS="$AMLINTFLAGS,E_ENUM_UNUSE"
+    AMLINTFLAGS="$AMLINTFLAGS,E_EXPR_NULL_EFFECT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_FUNC_RET_ALWAYS_IGNOR"
+    AMLINTFLAGS="$AMLINTFLAGS,E_FUNC_RET_MAYBE_IGNORED"
+    AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK0"
+    AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK1"
+    AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK2"
+    AMLINTFLAGS="$AMLINTFLAGS,E_INCL_MNUSD"
+    AMLINTFLAGS="$AMLINTFLAGS,E_INCL_NUSD"
+    AMLINTFLAGS="$AMLINTFLAGS,E_MCR_NODIFF"
+    AMLINTFLAGS="$AMLINTFLAGS,E_NAME_MULTIPLY_DEF"
+    AMLINTFLAGS="$AMLINTFLAGS,E_P_REF_NULL_PSBL"
+    AMLINTFLAGS="$AMLINTFLAGS,E_P_REF_SUSP"
+    AMLINTFLAGS="$AMLINTFLAGS,E_PTRDIFF_OVERFLOW"
+    AMLINTFLAGS="$AMLINTFLAGS,E_P_USE_NULL_PSBL"
+    AMLINTFLAGS="$AMLINTFLAGS,E_P_USE_SUSP"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_ACCESS_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CHDIR_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CHMOD_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CREAT_WITHOUT_EXCL"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_EXEC_PATH"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_EXEC_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_FOPEN_MODE"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_GETENV_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_MKDIR_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_PRINTF_VAR_FMT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_RAND_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SCANF_VAR_FMT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SELECT_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SHELL_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_STRNCPY_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_UMASK_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_USE_AFTER_STAT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SIGN_EXTENSION_PSBL"
+    AMLINTFLAGS="$AMLINTFLAGS,E_TYPEDEF_UNUSE"
+    AMLINTFLAGS="$AMLINTFLAGS,E_UNCAL_F"
+  else
+    AMLINTFLAGS=""
+  fi
+else
+  for ac_prog in splint
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AMLINT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $AMLINT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_AMLINT="$AMLINT" # Let the user override the test with a path.
   ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-fqdn option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-fqdn option." >&2;}
-   { (exit 1); exit 1; }; }
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $SYSLOCPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_AMLINT="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
   ;;
 esac
+fi
+AMLINT=$ac_cv_path_AMLINT
 
-
-# Check whether --with-broken-fsf or --without-broken-fsf was given.
-if test "${with_broken_fsf+set}" = set; then
-  withval="$with_broken_fsf"
-  HAVE_BROKEN_FSF=$withval
+if test -n "$AMLINT"; then
+  echo "$as_me:$LINENO: result: $AMLINT" >&5
+echo "${ECHO_T}$AMLINT" >&6
 else
-  : ${HAVE_BROKEN_FSF=no}
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-fi;
-case "$HAVE_BROKEN_FSF" in
-n | no) : ;;
-y |  ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_BROKEN_FSF 1
-_ACEOF
+  test -n "$AMLINT" && break
+done
 
-  ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-broken-fsf option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-broken-fsf option." >&2;}
-   { (exit 1); exit 1; }; }
-  ;;
-esac
+  if test ! -z "$AMLINT"; then
+    AMLINT="splint"
+  fi
+  AMLINTFLAGS='+show-scan +unixlib -weak -globs +usedef +usereleased +impouts -paramimptemp -varuse -warnposix -redef -preproc -fixedformalarray -retval -unrecog -usevarargs -formatcode'
+fi
 
 
-# Check whether --with-gnutar or --without-gnutar was given.
-if test "${with_gnutar+set}" = set; then
-  withval="$with_gnutar"
+
+# Check whether --with-includes or --without-includes was given.
+if test "${with_includes+set}" = set; then
+  withval="$with_includes"
 
        case "$withval" in
-           /*) GNUTAR="$withval";;
-           y|ye|yes) :;;
-           n|no) GNUTAR=;;
-           *)  { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-gnutar" >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-gnutar" >&2;}
-   { (exit 1); exit 1; }; };;
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-includes option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-includes option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
        esac
-
+       INCLUDE_DIRS="$withval"
 
 fi;
 
+if test "$INCLUDE_DIRS"; then
+       for dir in $INCLUDE_DIRS; do
+           if test -d "$dir"; then
+               AMANDA_CPPFLAGS="$AMANDA_CPPFLAGS -I$dir"
+           else
+               { echo "$as_me:$LINENO: WARNING: *** Include directory $dir does not exist." >&5
+echo "$as_me: WARNING: *** Include directory $dir does not exist." >&2;}
+           fi
+       done
+fi
+
 
-# Check whether --with-smbclient or --without-smbclient was given.
-if test "${with_smbclient+set}" = set; then
-  withval="$with_smbclient"
+# Check whether --with-libraries or --without-libraries was given.
+if test "${with_libraries+set}" = set; then
+  withval="$with_libraries"
 
        case "$withval" in
-           /*) SAMBA_CLIENT="$withval";;
-           y|ye|yes) :;;
-           n|no) SAMBA_CLIENT=;;
-           *)  { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-smbclient" >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-smbclient" >&2;}
-   { (exit 1); exit 1; }; };;
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-libraries option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-libraries option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
        esac
-
+       LIBRARY_DIRS="$withval"
 
 fi;
 
+if test "$LIBRARY_DIRS"; then
+       for dir in $LIBRARY_DIRS; do
+           if test -d "$dir"; then
+               case "$target" in
+                 *-solaris2*,*-netbsd*)
+                       AMANDA_LDFLAGS="$AMANDA_LDFLAGS -R$dir"
+                       ;;
+               esac
+               AMANDA_LDFLAGS="$AMANDA_LDFLAGS -L$dir"
+           else
+               { echo "$as_me:$LINENO: WARNING: *** Library directory $dir does not exist." >&5
+echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;}
+           fi
+       done
+fi
 
-# Check whether --with-samba-user or --without-samba-user was given.
-if test "${with_samba_user+set}" = set; then
-  withval="$with_samba_user"
-      { { echo "$as_me:$LINENO: error: *** The samba-user option was deprecated, the username go in the amandapass" >&5
-echo "$as_me: error: *** The samba-user option was deprecated, the username go in the amandapass" >&2;}
-   { (exit 1); exit 1; }; }
-
-
-fi;
 
 
-# Check whether --with-gnutar-listdir or --without-gnutar-listdir was given.
-if test "${with_gnutar_listdir+set}" = set; then
-  withval="$with_gnutar_listdir"
+# Check whether --with-dumperdir or --without-dumperdir was given.
+if test "${with_dumperdir+set}" = set; then
+  withval="$with_dumperdir"
 
        case "$withval" in
-           n | no)             unset GNUTAR_LISTDIR ;;
-           y | ye | yes)       : ${GNUTAR_LISTDIR=$localstatedir/amanda/gnutar-lists} ;;
-           /*)                 GNUTAR_LISTDIR="$withval" ;;
-           *)                  { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-gnutar-listdir" >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-gnutar-listdir" >&2;}
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-dumperdir option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-dumperdir option." >&2;}
    { (exit 1); exit 1; }; }
+         ;;
        esac
+       DUMPER_DIR="$withval"
 
 else
-  : ${GNUTAR_LISTDIR="$localstatedir/amanda/gnutar-lists"}
 
-fi;
-if test "$GNUTAR_LISTDIR"; then
-    GNUTAR_LISTDIR=`(
         test "x$prefix" = xNONE && prefix=$ac_default_prefix
-        eval echo "$GNUTAR_LISTDIR"
-    )`
-
-cat >>confdefs.h <<_ACEOF
-#define GNUTAR_LISTED_INCREMENTAL_DIR "$GNUTAR_LISTDIR"
-_ACEOF
+        test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+        DUMPER_DIR=$exec_prefix/dumper
 
-    GNUTAR_LISTED_INCREMENTAL_DIRX=$GNUTAR_LISTDIR
-else
-    GNUTAR_LISTED_INCREMENTAL_DIRX=
-fi
 
+fi;
+DUMPER_DIR=`(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+    eval echo "$DUMPER_DIR"
+)`
 
+cat >>confdefs.h <<_ACEOF
+#define DUMPER_DIR "$DUMPER_DIR"
+_ACEOF
 
-# Check whether --with-gnutar-listed-incremental or --without-gnutar-listed-incremental was given.
-if test "${with_gnutar_listed_incremental+set}" = set; then
-  withval="$with_gnutar_listed_incremental"
-      { { echo "$as_me:$LINENO: error: *** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead" >&5
-echo "$as_me: error: *** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead" >&2;}
-   { (exit 1); exit 1; }; }
 
 
-fi;
-GNUTAR_LISTED_INCREMENTAL_DIR=$GNUTAR_LISTDIR
 
+# Check whether --with-configdir or --without-configdir was given.
+if test "${with_configdir+set}" = set; then
+  withval="$with_configdir"
 
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-configdir option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-configdir option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) CONFIG_DIR="$withval"
+         ;;
+       esac
 
-# Check whether --with-bsd-security or --without-bsd-security was given.
-if test "${with_bsd_security+set}" = set; then
-  withval="$with_bsd_security"
-  BSD_SECURITY=$withval
 else
-  : ${BSD_SECURITY=yes}
+  : ${CONFIG_DIR="$sysconfdir/amanda"}
 
 fi;
-case "$BSD_SECURITY" in
-n | no) : ;;
-y |  ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define BSD_SECURITY 1
-_ACEOF
+CONFIG_DIR=`(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+    eval echo "$CONFIG_DIR"
+)`
 
-  ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-bsd-security option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-bsd-security option." >&2;}
-   { (exit 1); exit 1; }; }
-  ;;
-esac
+cat >>confdefs.h <<_ACEOF
+#define CONFIG_DIR "$CONFIG_DIR"
+_ACEOF
 
 
-# Check whether --with-amandahosts or --without-amandahosts was given.
-if test "${with_amandahosts+set}" = set; then
-  withval="$with_amandahosts"
-  USE_AMANDAHOSTS=$withval
-else
-  : ${USE_AMANDAHOSTS=yes}
 
-fi;
-case "$USE_AMANDAHOSTS" in
-n | no) : ;;
-y |  ye | yes) :
-  case "$BSD_SECURITY" in
-  y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define USE_AMANDAHOSTS 1
-_ACEOF
 
-    ;;
-  esac
-  ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-amandahosts option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-amandahosts option." >&2;}
+# Check whether --with-indexdir or --without-indexdir was given.
+if test "${with_indexdir+set}" = set; then
+  withval="$with_indexdir"
+     { { echo "$as_me:$LINENO: error: *** --with-indexdir is deprecated, use indexdir in amanda.conf instead." >&5
+echo "$as_me: error: *** --with-indexdir is deprecated, use indexdir in amanda.conf instead." >&2;}
    { (exit 1); exit 1; }; }
-  ;;
-esac
 
+fi;
 
 
-# Check whether --with-dbmalloc or --without-dbmalloc was given.
-if test "${with_dbmalloc+set}" = set; then
-  withval="$with_dbmalloc"
-  DBMALLOC="$withval"
-else
-  : ${DBMALLOC=no}
+# Check whether --with-dbdir or --without-dbdir was given.
+if test "${with_dbdir+set}" = set; then
+  withval="$with_dbdir"
+     { { echo "$as_me:$LINENO: error: *** --with-dbdir is deprecated, use infofile in amanda.conf instead." >&5
+echo "$as_me: error: *** --with-dbdir is deprecated, use infofile in amanda.conf instead." >&2;}
+   { (exit 1); exit 1; }; }
 
 fi;
 
-case "$DBMALLOC" in
-n | no)
-    DBMALLOCCFLAGS=""
-    DBMALLOCLIBS=""
-    ;;
-*)
-    DBMALLOCCFLAGS="-I$DBMALLOC -DUSE_DBMALLOC"
-    DBMALLOCLIBS="-L$DBMALLOC -ldbmalloc"
-    ;;
-esac
 
+# Check whether --with-logdir or --without-logdir was given.
+if test "${with_logdir+set}" = set; then
+  withval="$with_logdir"
+     { { echo "$as_me:$LINENO: error: *** --with-logdir is deprecated, use logdir in amanda.conf instead." >&5
+echo "$as_me: error: *** --with-logdir is deprecated, use logdir in amanda.conf instead." >&2;}
+   { (exit 1); exit 1; }; }
 
-: ${KRB4_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
+fi;
 
 
-# Check whether --with-krb4-security or --without-krb4-security was given.
-if test "${with_krb4_security+set}" = set; then
-  withval="$with_krb4_security"
-  KRB4_SECURITY="$withval"
+# Check whether --with-suffixes or --without-suffixes was given.
+if test "${with_suffixes+set}" = set; then
+  withval="$with_suffixes"
+  USE_VERSION_SUFFIXES=$withval
 else
-  : ${KRB4_SECURITY=no}
+  : ${USE_VERSION_SUFFIXES=no}
 
 fi;
-
-case "$KRB4_SECURITY" in
-n | no) KRB4_SECURITY=no ;;
-y | ye | yes) : ;;
-*) KRB4_SPOTS="$KRB4_SECURITY"
-   KRB4_SECURITY=yes
-   ;;
-esac
-
-echo "$as_me:$LINENO: checking for Kerberos and Amanda kerberos4 bits" >&5
-echo $ECHO_N "checking for Kerberos and Amanda kerberos4 bits... $ECHO_C" >&6
-if test "x${KRB4_SECURITY}" = xyes -a -f  ${srcdir-.}/common-src/krb4-security.c ; then
-    for dir in $KRB4_SPOTS; do
-       if test -f ${dir}/lib/libkrb.a -a -f ${dir}/lib/libdes.a ; then
-           #
-           # This is the original Kerberos 4.
-           #
-           echo "$as_me:$LINENO: result: found in $dir" >&5
-echo "${ECHO_T}found in $dir" >&6
-           KRB4_SECURITY=yes
-
-cat >>confdefs.h <<\_ACEOF
-#define KRB4_SECURITY 1
-_ACEOF
-
-           if test -d $dir/include/kerberosIV ; then
-               #
-               # This handles BSD/OS.
-               #
-               KRB4INCLUDES=-I$dir/include/kerberosIV
-           else
-               KRB4INCLUDES=-I$dir/include
-           fi
-           KRB4LDFLAGS=-L$dir/lib
-           KRB4LIBS="-lkrb -ldes"
-           if test -f ${dir}/lib/libcom_err.a; then
-               KRB4LIBS="$KRB4LIBS -lcom_err"
-           fi
-           break
-       elif test -f ${dir}/lib/libkrb4.a &&
-            test -f ${dir}/lib/libcrypto.a &&
-            test -f ${dir}/lib/libdes425.a ; then
-           #
-           # This is Kerberos 5 with Kerberos 4 back-support.
-           #
-           echo "$as_me:$LINENO: result: found in $dir" >&5
-echo "${ECHO_T}found in $dir" >&6
-           KRB4_SECURITY=yes
+case "$USE_VERSION_SUFFIXES" in
+y | ye | yes)
 
 cat >>confdefs.h <<\_ACEOF
-#define KRB4_SECURITY 1
+#define USE_VERSION_SUFFIXES 1
 _ACEOF
 
-           KRB4INCLUDES="-I$dir/include -I$dir/include/kerberosIV"
-           KRB4LDFLAGS=-L$dir/lib
-           if test -f ${dir}/lib/libkrb5.a &&
-               test -f ${dir}/lib/libcom_err.a; then
-               KRB4LIBS="-lkrb4 -lkrb5 -lcrypto -ldes425 -lcom_err"
-           else
-               KRB4LIBS="-lkrb4 -lcrypto -ldes425"
-           fi
-           break
-       fi
-    done
 
-    if test "x$KRB4LDFLAGS" = "x" ; then
-       echo "$as_me:$LINENO: result: no libraries found" >&5
-echo "${ECHO_T}no libraries found" >&6
+    program_suffix="-$VERSION"
+    # This is from the output of configure.in.
+    if test "x$program_transform_name" = xs,x,x,; then
+       program_transform_name=
+    else
+       # Double any \ or $.  echo might interpret backslashes.
+       cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+       program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+       rm -f conftestsed
     fi
-else
-    echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-
-# Check whether --with-rsh-security or --without-rsh-security was given.
-if test "${with_rsh_security+set}" = set; then
-  withval="$with_rsh_security"
-  RSH_SECURITY=$withval
-else
-  : ${RSH_SECURITY=yes}
-
-fi;
-case "$RSH_SECURITY" in
-n | no) : ;;
-y |  ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define RSH_SECURITY 1
-_ACEOF
+    test "x$program_prefix" != xNONE &&
+       program_transform_name="s,^,${program_prefix},; $program_transform_name"
+    # Use a double $ so make ignores it.
+    test "x$program_suffix" != xNONE &&
+       program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
 
+    # sed with no file args requires a program.
+    test "x$program_transform_name" = "" && program_transform_name="xs,x,x,"
+    # Remove empty command
+    cat <<\EOF_SED > conftestsed
+s,\;\;,\;,g; s,\; \$,,g; s,\;$,,g
+EOF_SED
+    program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+    rm -f conftestsed
   ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-rsh-security option." >&5
-echo "$as_me: error: *** You must not supply an argument the to --with-rsh-security option." >&2;}
-   { (exit 1); exit 1; }; }
-  ;;
-esac
-
-
-# Check whether --with-ssh-security or --without-ssh-security was given.
-if test "${with_ssh_security+set}" = set; then
-  withval="$with_ssh_security"
-  SSH_SECURITY=$withval
-else
-  : ${SSH_SECURITY=no}
-
-fi;
-case "$SSH_SECURITY" in
-n | no) : ;;
-y |  ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define SSH_SECURITY 1
-_ACEOF
-
-              SSH_SECURITY_SET=true
+n | no) USE_VERSION_SUFFIXES=no
   ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-ssh-security option." >&5
-echo "$as_me: error: *** You must not supply an argument the to --with-ssh-security option." >&2;}
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-suffixes option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-suffixes option." >&2;}
    { (exit 1); exit 1; }; }
   ;;
 esac
 
 
-# Check whether --with-server-principal or --without-server-principal was given.
-if test "${with_server_principal+set}" = set; then
-  withval="$with_server_principal"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-principal option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-server-principal option." >&2;}
-   { (exit 1); exit 1; }; }
-         ;;
-       *)
-           SERVER_HOST_PRINCIPLE="$withval"
-         ;;
-       esac
-
-else
-  : ${SERVER_HOST_PRINCIPLE="amanda"}
-
-fi;
-
-cat >>confdefs.h <<_ACEOF
-#define SERVER_HOST_PRINCIPLE "$SERVER_HOST_PRINCIPLE"
-_ACEOF
+case "$target" in
+    *-hp-*)
+       CLIENT_SCRIPTS_OPT=amhpfixdevs
+       ;;
+    *-sni-sysv4)
+       CLIENT_SCRIPTS_OPT=amsinixfixdevs
+       ;;
+    *)
+       CLIENT_SCRIPTS_OPT=
+       ;;
+esac
 
 
 
-# Check whether --with-server-instance or --without-server-instance was given.
-if test "${with_server_instance+set}" = set; then
-  withval="$with_server_instance"
 
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-instance option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-server-instance option." >&2;}
+# Check whether --with-client-only or --without-client-only was given.
+if test "${with_client_only+set}" = set; then
+  withval="$with_client_only"
+     { { echo "$as_me:$LINENO: error: *** --with-client-only is deprecated, use --without-server instead." >&5
+echo "$as_me: error: *** --with-client-only is deprecated, use --without-server instead." >&2;}
    { (exit 1); exit 1; }; }
-         ;;
-       *) SERVER_HOST_INSTANCE="$withval"
-         ;;
-       esac
-
-else
-  : ${SERVER_HOST_INSTANCE="amanda"}
 
 fi;
 
-cat >>confdefs.h <<_ACEOF
-#define SERVER_HOST_INSTANCE "$SERVER_HOST_INSTANCE"
-_ACEOF
-
-
-
-# Check whether --with-server-keyfile or --without-server-keyfile was given.
-if test "${with_server_keyfile+set}" = set; then
-  withval="$with_server_keyfile"
-
-       case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-keyfile option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-server-keyfile option." >&2;}
+# Check whether --with-server-only or --without-server-only was given.
+if test "${with_server_only+set}" = set; then
+  withval="$with_server_only"
+     { { echo "$as_me:$LINENO: error: *** --with-server-only is deprecated, use --without-client instead." >&5
+echo "$as_me: error: *** --with-server-only is deprecated, use --without-client instead." >&2;}
    { (exit 1); exit 1; }; }
-         ;;
-       *) SERVER_HOST_KEY_FILE="$withval"
-         ;;
-       esac
-
-else
-  : ${SERVER_HOST_KEY_FILE="/.amanda"}
 
 fi;
 
-cat >>confdefs.h <<_ACEOF
-#define SERVER_HOST_KEY_FILE "$SERVER_HOST_KEY_FILE"
-_ACEOF
-
-
 
-# Check whether --with-client-principal or --without-client-principal was given.
-if test "${with_client_principal+set}" = set; then
-  withval="$with_client_principal"
+# Check whether --with-client or --without-client was given.
+if test "${with_client+set}" = set; then
+  withval="$with_client"
 
        case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-principal option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-client-principal option." >&2;}
+       y | ye | yes) NO_CLIENT_MODE=false;;
+       n | no) NO_CLIENT_MODE=true;;
+       *)
+           { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-client option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-client option." >&2;}
    { (exit 1); exit 1; }; }
          ;;
-       *) CLIENT_HOST_PRINCIPLE="$withval"
-         ;;
        esac
 
-else
-  : ${CLIENT_HOST_PRINCIPLE="rcmd"}
 
 fi;
 
-cat >>confdefs.h <<_ACEOF
-#define CLIENT_HOST_PRINCIPLE "$CLIENT_HOST_PRINCIPLE"
-_ACEOF
-
 
-
-# Check whether --with-client-instance or --without-client-instance was given.
-if test "${with_client_instance+set}" = set; then
-  withval="$with_client_instance"
+# Check whether --with-server or --without-server was given.
+if test "${with_server+set}" = set; then
+  withval="$with_server"
 
        case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-instance option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-client-instance option." >&2;}
+       y | ye | yes) NO_SERVER_MODE=false ;;
+       n | no) NO_SERVER_MODE=true;NO_RESTORE_MODE=true;;
+       *)
+           { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-server option.  Maybe you meant --with-index-server=$withval" >&5
+echo "$as_me: error: *** You must not supply an argument to --with-server option.  Maybe you meant --with-index-server=$withval" >&2;}
    { (exit 1); exit 1; }; }
          ;;
-       *) CLIENT_HOST_INSTANCE="$withval"
-         ;;
        esac
 
-else
-  : ${CLIENT_HOST_INSTANCE=HOSTNAME_INSTANCE}
 
 fi;
-
-cat >>confdefs.h <<_ACEOF
-#define CLIENT_HOST_INSTANCE $CLIENT_HOST_INSTANCE
-_ACEOF
-
+if test "x${NO_SERVER_MODE+set}" != xset ; then
+   NO_SERVER_MODE=false
+fi
 
 
-# Check whether --with-client-keyfile or --without-client-keyfile was given.
-if test "${with_client_keyfile+set}" = set; then
-  withval="$with_client_keyfile"
+# Check whether --with-restore or --without-restore was given.
+if test "${with_restore+set}" = set; then
+  withval="$with_restore"
 
        case "$withval" in
-       "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-keyfile option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-client-keyfile option." >&2;}
+       y | ye | yes) NO_RESTORE_MODE=false;;
+       n | no) NO_RESTORE_MODE=true;;
+       *)
+           { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-restore option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-restore option." >&2;}
    { (exit 1); exit 1; }; }
          ;;
-       *) CLIENT_HOST_KEY_FILE="$withval"
-         ;;
        esac
 
-else
-  : ${CLIENT_HOST_KEY_FILE=KEYFILE}
 
 fi;
+if test "x${NO_RESTORE_MODE+set}" != xset ; then
+   NO_RESTORE_MODE=${NO_SERVER_MODE-false}
+fi
 
-# Assume it's either KEYFILE (defined in krb.h), or a string filename...
-if test "x$CLIENT_HOST_KEY_FILE" != "xKEYFILE"; then
-  CLIENT_HOST_KEY_FILE="\"$CLIENT_HOST_KEY_FILE\""
+if ${NO_SERVER_MODE-false}; then
+   if ${NO_RESTORE_MODE-false}; then
+                        true
+   else
+      { { echo "$as_me:$LINENO: error: *** --without-server requires --without-restore" >&5
+echo "$as_me: error: *** --without-server requires --without-restore" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
 fi
 
 
-cat >>confdefs.h <<_ACEOF
-#define CLIENT_HOST_KEY_FILE $CLIENT_HOST_KEY_FILE
-_ACEOF
+# Check whether --with-amrecover or --without-amrecover was given.
+if test "${with_amrecover+set}" = set; then
+  withval="$with_amrecover"
 
+       case "$withval" in
+       y | ye | yes)
+           if ${NO_CLIENT_MODE-false}; then
+               { { echo "$as_me:$LINENO: error: *** --without-client and --with-amrecover are incompatible" >&5
+echo "$as_me: error: *** --without-client and --with-amrecover are incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+           fi
+           NO_RECOVER_MODE=false;;
+       n | no) NO_RECOVER_MODE=true;;
+       *)
+           { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-amrecover option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-amrecover option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       esac
 
 
-# Check whether --with-ticket-lifetime or --without-ticket-lifetime was given.
-if test "${with_ticket_lifetime+set}" = set; then
-  withval="$with_ticket_lifetime"
+fi;
+
+
+# Check whether --with-index-server or --without-index-server was given.
+if test "${with_index_server+set}" = set; then
+  withval="$with_index_server"
 
        case "$withval" in
        "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-ticket-lifetime option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-ticket-lifetime option." >&2;}
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-index-server option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-index-server option." >&2;}
    { (exit 1); exit 1; }; }
          ;;
-       *) TICKET_LIFETIME="$withval"
+       *) DEFAULT_SERVER="$withval"
          ;;
        esac
 
 else
-  : ${TICKET_LIFETIME=128}
+  : ${DEFAULT_SERVER=`uname -n`}
 
 fi;
 
 cat >>confdefs.h <<_ACEOF
-#define TICKET_LIFETIME $TICKET_LIFETIME
+#define DEFAULT_SERVER "$DEFAULT_SERVER"
 _ACEOF
 
 
 
-: ${KRB5_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
-
 
-# Check whether --with-krb5-security or --without-krb5-security was given.
-if test "${with_krb5_security+set}" = set; then
-  withval="$with_krb5_security"
-  KRB5_SECURITY="$withval"
+# Check whether --with-force-uid or --without-force-uid was given.
+if test "${with_force_uid+set}" = set; then
+  withval="$with_force_uid"
+  FORCE_USERID="$withval"
 else
-  : ${KRB5_SECURITY=no}
+  : ${FORCE_USERID=yes}
 
 fi;
+case "$FORCE_USERID" in
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define FORCE_USERID 1
+_ACEOF
 
-case "$KRB5_SECURITY" in
-n | no) KRB5_SECURITY=no
-        KRB5_SPOTS=""
-       ;;
-y | ye | yes) : ;;
-*) KRB5_SPOTS="$KRB5_SECURITY"
-   KRB5_SECURITY=yes
-   ;;
+  ;;
+n | no) :
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-force-uid option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-force-uid option." >&2;}
+   { (exit 1); exit 1; }; }
 esac
 
-# if found, force the static versions of these libs (.a) by linking directly
-# with the .a files.  I don't know how to get -R dependancies checked
-# in autoconf at this time. -kashmir
-echo "$as_me:$LINENO: checking for Kerberos V" >&5
-echo $ECHO_N "checking for Kerberos V... $ECHO_C" >&6
-KRB5_DIR_FOUND=""
-KRB5_CFLAGS=""
-for dir in $KRB5_SPOTS; do
-    k5libdir=${dir}/lib
-    if test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libgssapi_krb5.a -a -f ${k5libdir}/libcom_err.a; then
-       if test -f ${k5libdir}/libcrypto.a; then
-           K5CRYPTO=${k5libdir}/libcrypto.a
-       elif test -f ${k5libdir}/libk5crypto.a; then
-           K5CRYPTO=${k5libdir}/libk5crypto.a
-       else
-           K5CRYPTO=""
-       fi
-       KRB5_DIR_FOUND=$dir
-       KRB5LIBS="${k5libdir}/libgssapi_krb5.a ${k5libdir}/libkrb5.a $K5CRYPTO ${k5libdir}/libcom_err.a"
-       KRB5CFLAGS=""
-       break
-    elif test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libasn1.a -a -f ${k5libdir}/libgssapi.a; then
-       KRB5_DIR_FOUND=$dir
-       KRB5LIBS="${k5libdir}/libgssapi.a ${k5libdir}/libkrb5.a ${k5libdir}/libasn1.a"
-       KRB5_CFLAGS="-DKRB5_HEIMDAL_INCLUDES"
-       break
-    fi
-done
 
-if test "$KRB5_DIR_FOUND"; then
-       echo "$as_me:$LINENO: result: found in $KRB5_DIR_FOUND" >&5
-echo "${ECHO_T}found in $KRB5_DIR_FOUND" >&6
-       KRB5_SECURITY=yes
+# Check whether --with-user or --without-user was given.
+if test "${with_user+set}" = set; then
+  withval="$with_user"
 
-cat >>confdefs.h <<\_ACEOF
-#define KRB5_SECURITY 1
-_ACEOF
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-user option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-user option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) CLIENT_LOGIN="$withval"
+         ;;
+       esac
 
-       #
-       # some OS's, such as NetBSD, stick krb5 includes out of the way...
-       # should probably just use autoconf to look for various include
-       # options and set them, but don't quite want to do that until I've
-       # dug into it a bit more.
-       #
-       if test -d "$KRB5_DIR_FOUND/krb5" ; then
-               KRB5INCLUDES="-I$KRB5_DIR_FOUND/include/krb5"
-       else
-               KRB5INCLUDES="-I$KRB5_DIR_FOUND/include"
-       fi
-       if test "$KRB5_CFLAGS" ; then
-               KRB5INCLUDES="$KRB5INCLUDES $KRB5_CFLAGS"
-       fi
-       KRB5LDFLAGS=-L$k5libdir
-       break
-fi
 
-if test "x$KRB5LDFLAGS" = "x" ; then
-    echo "$as_me:$LINENO: result: no krb5 system libraries found" >&5
-echo "${ECHO_T}no krb5 system libraries found" >&6
+fi;
+if test "x${CLIENT_LOGIN+set}" != xset; then
+    { { echo "$as_me:$LINENO: error: *** --with-user=USER is missing" >&5
+echo "$as_me: error: *** --with-user=USER is missing" >&2;}
+   { (exit 1); exit 1; }; }
 fi
 
+cat >>confdefs.h <<_ACEOF
+#define CLIENT_LOGIN "$CLIENT_LOGIN"
+_ACEOF
 
 
-# Check whether --with-portrange or --without-portrange was given.
-if test "${with_portrange+set}" = set; then
-  withval="$with_portrange"
-
-       TCPPORTRANGE="$withval"
-
 
-fi;
 
-# Check whether --with-tcpportrange or --without-tcpportrange was given.
-if test "${with_tcpportrange+set}" = set; then
-  withval="$with_tcpportrange"
+# Check whether --with-group or --without-group was given.
+if test "${with_group+set}" = set; then
+  withval="$with_group"
 
-       TCPPORTRANGE="$withval"
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-group option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-group option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) SETUID_GROUP="$withval"
+         ;;
+       esac
 
 
 fi;
-if test x"${TCPPORTRANGE+set}" = x"set"; then
-    if test x`echo "$TCPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
-       { { echo "$as_me:$LINENO: error: *** --with-tcpportrange requires two comma-separated positive numbers" >&5
-echo "$as_me: error: *** --with-tcpportrange requires two comma-separated positive numbers" >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-    min_tcp_port=`echo "$TCPPORTRANGE" | sed 's/,.*//'`
-    max_tcp_port=`echo "$TCPPORTRANGE" | sed 's/.*,//'`
-    if test $min_tcp_port -gt $max_tcp_port; then
-       { { echo "$as_me:$LINENO: error: *** the second TCP port number must be greater than the first in --with-tcpportrange" >&5
-echo "$as_me: error: *** the second TCP port number must be greater than the first in --with-tcpportrange" >&2;}
+if test "x${SETUID_GROUP+set}" != xset; then
+    { { echo "$as_me:$LINENO: error: *** --with-group=GROUP is missing" >&5
+echo "$as_me: error: *** --with-group=GROUP is missing" >&2;}
    { (exit 1); exit 1; }; }
-    fi
-    if test $min_tcp_port -lt 1024; then
-       { echo "$as_me:$LINENO: WARNING: *** the TCP port range should be 1024 or greater in --with-tcpportrange" >&5
-echo "$as_me: WARNING: *** the TCP port range should be 1024 or greater in --with-tcpportrange" >&2;}
-    fi
-    if test $max_tcp_port -ge 65536; then
-       { echo "$as_me:$LINENO: WARNING: *** the TCP port range should be less than 65536 in --with-tcpportrange" >&5
-echo "$as_me: WARNING: *** the TCP port range should be less than 65536 in --with-tcpportrange" >&2;}
-    fi
-
-cat >>confdefs.h <<_ACEOF
-#define TCPPORTRANGE $TCPPORTRANGE
-_ACEOF
-
 fi
 
 
-# Check whether --with-udpportrange or --without-udpportrange was given.
-if test "${with_udpportrange+set}" = set; then
-  withval="$with_udpportrange"
-
-       UDPPORTRANGE="$withval"
 
+# Check whether --with-owner or --without-owner was given.
+if test "${with_owner+set}" = set; then
+  withval="$with_owner"
 
-fi;
-if test x"${UDPPORTRANGE+set}" = x"set"; then
-    if test x`echo "$UDPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
-       { { echo "$as_me:$LINENO: error: *** --with-udpportrange requires two comma-separated positive numbers" >&5
-echo "$as_me: error: *** --with-udpportrange requires two comma-separated positive numbers" >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-    min_udp_port=`echo "$UDPPORTRANGE" | sed 's/,.*//'`
-    max_udp_port=`echo "$UDPPORTRANGE" | sed 's/.*,//'`
-    if test $min_udp_port -gt $max_udp_port; then
-       { { echo "$as_me:$LINENO: error: *** the second UDP port number must be greater than the first in --with-udpportrange" >&5
-echo "$as_me: error: *** the second UDP port number must be greater than the first in --with-udpportrange" >&2;}
+        case "$withval" in
+        "" | y | ye | yes | n | no)
+            { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-owner option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-owner option." >&2;}
    { (exit 1); exit 1; }; }
-    fi
-    if test $max_udp_port -ge 1024; then
-       { echo "$as_me:$LINENO: WARNING: *** the UDP port range should be less than 1024 in --with-udpportrange" >&5
-echo "$as_me: WARNING: *** the UDP port range should be less than 1024 in --with-udpportrange" >&2;}
-    fi
-    if test $min_udp_port -le 0; then
-       { echo "$as_me:$LINENO: WARNING: *** the UDP port range should be greater than 0 in --with-udpportrange" >&5
-echo "$as_me: WARNING: *** the UDP port range should be greater than 0 in --with-udpportrange" >&2;}
-    fi
+          ;;
+        *) BINARY_OWNER="$withval"
+          ;;
+        esac
 
-cat >>confdefs.h <<_ACEOF
-#define UDPPORTRANGE $UDPPORTRANGE
-_ACEOF
 
+fi;
+if test "x${BINARY_OWNER+set}" != xset ; then
+   BINARY_OWNER=$CLIENT_LOGIN
 fi
 
+cat >>confdefs.h <<_ACEOF
+#define BINARY_OWNER "$BINARY_OWNER"
+_ACEOF
 
-# Check whether --with-maxtapeblocksize or --without-maxtapeblocksize was given.
-if test "${with_maxtapeblocksize+set}" = set; then
-  withval="$with_maxtapeblocksize"
-
-       MAXTAPEBLOCKSIZE="$withval"
 
-else
-  : ${MAXTAPEBLOCKSIZE=32}
 
-fi;
 
+# Check whether --with-rundump or --without-rundump was given.
+if test "${with_rundump+set}" = set; then
+  withval="$with_rundump"
 
-cat >>confdefs.h <<_ACEOF
-#define MAX_TAPE_BLOCK_KB ($MAXTAPEBLOCKSIZE)
-_ACEOF
+    case "$withval" in
+       n | no | y | ye | yes) FORCE_USE_RUNDUMP="$withval";;
+       *) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-rundump option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-rundump option." >&2;}
+   { (exit 1); exit 1; }; };;
+    esac
 
 
+fi;
 
 
-# Check whether --with-db or --without-db was given.
-if test "${with_db+set}" = set; then
-  withval="$with_db"
+# Check whether --with-config or --without-config was given.
+if test "${with_config+set}" = set; then
+  withval="$with_config"
 
        case "$withval" in
        "" | y | ye | yes | n | no)
-           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-db option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-db option." >&2;}
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-config option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-config option." >&2;}
    { (exit 1); exit 1; }; }
          ;;
-       *) DB_STYLE="$withval"
+       *) DEFAULT_CONFIG="$withval"
          ;;
        esac
 
-
-fi;
-if test "$DB_STYLE"; then
-    case "$DB_STYLE" in
-       db | dbm | gdbm | ndbm | text)  ;;
-       *)
-           { { echo "$as_me:$LINENO: error: *** Unknown argument $DB_STYLE given to --with-db.  Choose from db, dbm, gdbm, ndbm, text." >&5
-echo "$as_me: error: *** Unknown argument $DB_STYLE given to --with-db.  Choose from db, dbm, gdbm, ndbm, text." >&2;}
-   { (exit 1); exit 1; }; }
-           DB_STYLE=
-           ;;
-    esac
-fi
-
-
-# Check whether --with-mmap or --without-mmap was given.
-if test "${with_mmap+set}" = set; then
-  withval="$with_mmap"
-  FORCE_MMAP=$withval
 else
-  : ${FORCE_MMAP=no}
+  : ${DEFAULT_CONFIG=DailySet1}
 
 fi;
-case "$FORCE_MMAP" in
-y | ye | yes | n | no) : ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-mmap." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-mmap." >&2;}
-   { (exit 1); exit 1; }; }
-  ;;
-esac
 
-
-# Check whether --with-buffered-dump or --without-buffered-dump was given.
-if test "${with_buffered_dump+set}" = set; then
-  withval="$with_buffered_dump"
-  DUMPER_SOCKET_BUFFERING=$withval
-else
-  : ${DUMPER_SOCKET_BUFFERING=no}
-
-fi;
-case "$DUMPER_SOCKET_BUFFERING" in
-n | no) :
-  ;;
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define DUMPER_SOCKET_BUFFERING 1
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_CONFIG "$DEFAULT_CONFIG"
 _ACEOF
 
-  ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-buffered-dump." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-buffered-dump." >&2;}
-   { (exit 1); exit 1; }; }
-  ;;
-esac
 
 
-# Check whether --with-assertions or --without-assertions was given.
-if test "${with_assertions+set}" = set; then
-  withval="$with_assertions"
-  ASSERTIONS="$withval"
-else
-  : ${ASSERTIONS=no}
 
-fi;
-case "$ASSERTIONS" in
-n | no) : ;;
-y |  ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define ASSERTIONS 1
-_ACEOF
+# Check whether --with-tape-server or --without-tape-server was given.
+if test "${with_tape_server+set}" = set; then
+  withval="$with_tape_server"
 
-  ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-assertions option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-assertions option." >&2;}
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-tape-server option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-tape-server option." >&2;}
    { (exit 1); exit 1; }; }
-  ;;
-esac
-
+         ;;
+       *) DEFAULT_TAPE_SERVER="$withval"
+         ;;
+       esac
 
-# Check whether --with-tmpdir or --without-tmpdir was given.
-if test "${with_tmpdir+set}" = set; then
-  withval="$with_tmpdir"
-  tmpdir="$withval"
 else
-  : ${tmpdir=yes}
+  : ${DEFAULT_TAPE_SERVER=$DEFAULT_SERVER}
 
 fi;
-tmpdir=`(
-    test "x$prefix" = xNONE && prefix=$ac_default_prefix
-    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
-    eval echo "$tmpdir"
-)`
-case "$tmpdir" in
-n | no) { { echo "$as_me:$LINENO: error: *** --without-tmpdir is not allowed." >&5
-echo "$as_me: error: *** --without-tmpdir is not allowed." >&2;}
-   { (exit 1); exit 1; }; };;
-y |  ye | yes)
-       AMANDA_TMPDIR="/tmp/amanda";;
-/*)
-       AMANDA_TMPDIR="$tmpdir";;
-*) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-tmpdir option." >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-tmpdir option." >&2;}
-   { (exit 1); exit 1; }; };;
-esac
 
 cat >>confdefs.h <<_ACEOF
-#define AMANDA_TMPDIR "$AMANDA_TMPDIR"
+#define DEFAULT_TAPE_SERVER "$DEFAULT_TAPE_SERVER"
 _ACEOF
 
 
 
 
-# Check whether --with-debugging or --without-debugging was given.
-if test "${with_debugging+set}" = set; then
-  withval="$with_debugging"
-  debugging="$withval"
-else
-  : ${debugging=yes}
+# Check whether --with-tape-device or --without-tape-device was given.
+if test "${with_tape_device+set}" = set; then
+  withval="$with_tape_device"
 
-fi;
-debugging=`(
-    test "x$prefix" = xNONE && prefix=$ac_default_prefix
-    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
-    eval echo "$debugging"
-)`
-case "$debugging" in
-n | no) AMANDA_DBGDIR="";;
-y |  ye | yes) AMANDA_DBGDIR="$AMANDA_TMPDIR";;
-/*) AMANDA_DBGDIR="$debugging";;
-*) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-debugging option." >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-debugging option." >&2;}
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-tape-device option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-tape-device option." >&2;}
    { (exit 1); exit 1; }; }
-  ;;
-esac
-case "$AMANDA_DBGDIR" in
-"") :;;
-*)
-cat >>confdefs.h <<\_ACEOF
-#define DEBUG_CODE 1
-_ACEOF
+         ;;
+       *) DEFAULT_TAPE_DEVICE="$withval"
+         ;;
+       esac
 
+else
 
-cat >>confdefs.h <<_ACEOF
-#define AMANDA_DBGDIR "$AMANDA_DBGDIR"
-_ACEOF
+       if test -z "$DEFAULT_TAPE_DEVICE"; then
+           echo "$as_me:$LINENO: checking for non-rewinding tape device" >&5
+echo $ECHO_N "checking for non-rewinding tape device... $ECHO_C" >&6
+                                                                   tape_dev=
+           nr_tape_dev=
+           if test -d /dev/rmt; then
 
-   ;;
-esac
 
+               for num in 9 8 7 6 5 4 3 2 1 0; do
+                   td=/dev/rmt/${num}b
+                   ntd=/dev/rmt/${num}bn
+                   if test -r $td -a -r $ntd; then
+                       tape_dev=$td
+                       nr_tape_dev=$ntd
+                   fi
+               done
+           else
+                               for num in 9 8 7 6 5 4 3 2 1 0; do
+                   td=/dev/rst${num}
+                   ntd=/dev/nrst${num}
+                   if test -r $td -a -r $ntd; then
+                       tape_dev=$td
+                       nr_tape_dev=$ntd
+                   fi
+               done
+           fi
+           DEFAULT_TAPE_DEVICE=$nr_tape_dev
+           echo "$as_me:$LINENO: result: $DEFAULT_TAPE_DEVICE" >&5
+echo "${ECHO_T}$DEFAULT_TAPE_DEVICE" >&6
+       fi
 
-# Check whether --with-debug_days or --without-debug_days was given.
-if test "${with_debug_days+set}" = set; then
-  withval="$with_debug_days"
-  debug_days="$withval"
-else
-  : ${debug_days=4}
 
 fi;
-case "$debug_days" in
-n | no) AMANDA_DEBUG_DAYS=0 ;;
-y |  ye | yes) AMANDA_DEBUG_DAYS=4 ;;
-[0-9] | [0-9][0-9] | [0-9][0-9][0-9]) AMANDA_DEBUG_DAYS="$debug_days" ;;
-*) { { echo "$as_me:$LINENO: error: *** --with-debug-days value not numeric or out of range." >&5
-echo "$as_me: error: *** --with-debug-days value not numeric or out of range." >&2;}
-   { (exit 1); exit 1; }; }
-  ;;
-esac
+
+if test ! -z "$DEFAULT_TAPE_DEVICE"; then
 
 cat >>confdefs.h <<_ACEOF
-#define AMANDA_DEBUG_DAYS $AMANDA_DEBUG_DAYS
+#define DEFAULT_TAPE_DEVICE "$DEFAULT_TAPE_DEVICE"
 _ACEOF
 
 
+fi
 
 
-# Check whether --with-testing or --without-testing was given.
-if test "${with_testing+set}" = set; then
-  withval="$with_testing"
-  TESTING="$withval"
-else
-  : ${TESTING=no}
+# Check whether --with-ftape-raw-device or --without-ftape-raw-device was given.
+if test "${with_ftape_raw_device+set}" = set; then
+  withval="$with_ftape_raw_device"
 
-fi;
-case "$TESTING" in
-n | no) SERVICE_SUFFIX="";;
-y |  ye | yes) SERVICE_SUFFIX="-test";;
-*) SERVICE_SUFFIX="-$TESTING";;
-esac
-AMANDA_SERVICE_NAME="amanda$SERVICE_SUFFIX"
-KAMANDA_SERVICE_NAME="kamanda$SERVICE_SUFFIX"
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-ftape-rawdevice option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-ftape-rawdevice option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) DEFAULT_RAW_TAPE_DEVICE="$withval"
+         ;;
+       esac
 
+else
 
-cat >>confdefs.h <<_ACEOF
-#define SERVICE_SUFFIX "$SERVICE_SUFFIX"
-_ACEOF
+       if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
+           echo "$as_me:$LINENO: checking for raw ftape device" >&5
+echo $ECHO_N "checking for raw ftape device... $ECHO_C" >&6
+                   raw_tape_dev=/dev/null
+                               for num in 3 2 1 0 ; do
+                   td=/dev/rawft${num}
+                   if test -r $td; then
+                       raw_tape_dev=$td
+                   fi
+               done
+           DEFAULT_RAW_TAPE_DEVICE=$raw_tape_dev
+           echo "$as_me:$LINENO: result: $DEFAULT_RAW_TAPE_DEVICE" >&5
+echo "${ECHO_T}$DEFAULT_RAW_TAPE_DEVICE" >&6
+       fi
 
 
-cat >>confdefs.h <<_ACEOF
-#define AMANDA_SERVICE_NAME "$AMANDA_SERVICE_NAME"
-_ACEOF
+fi;
+
+if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
+    DEFAULT_RAW_TAPE_DEVICE=/dev/null
+fi
 
 
 cat >>confdefs.h <<_ACEOF
-#define KAMANDA_SERVICE_NAME "$KAMANDA_SERVICE_NAME"
+#define DEFAULT_RAW_TAPE_DEVICE "$DEFAULT_RAW_TAPE_DEVICE"
 _ACEOF
 
 
-(
-    test "x$prefix" = xNONE && prefix=$ac_default_prefix
-    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
 
-    tmp=`eval echo "$bindir"`
 
-cat >>confdefs.h <<_ACEOF
-#define bindir "$tmp"
-_ACEOF
+# Check whether --with-rew-tape or --without-rew-tape was given.
+if test "${with_rew_tape+set}" = set; then
+  withval="$with_rew_tape"
+     { { echo "$as_me:$LINENO: error: *** --with-rew-tape is deprecated, use --with-tape-device instead." >&5
+echo "$as_me: error: *** --with-rew-tape is deprecated, use --with-tape-device instead." >&2;}
+   { (exit 1); exit 1; }; }
 
+fi;
 
-    tmp=`eval echo "$sbindir"`
 
-cat >>confdefs.h <<_ACEOF
-#define sbindir "$tmp"
-_ACEOF
+# Check whether --with-norew-tape or --without-norew-tape was given.
+if test "${with_norew_tape+set}" = set; then
+  withval="$with_norew_tape"
+     { { echo "$as_me:$LINENO: error: *** --with-norew-tape is deprecated, use --with-tape-device instead." >&5
+echo "$as_me: error: *** --with-norew-tape is deprecated, use --with-tape-device instead." >&2;}
+   { (exit 1); exit 1; }; }
 
+fi;
 
-    tmp=`eval echo "$libexecdir"`
 
-cat >>confdefs.h <<_ACEOF
-#define libexecdir "$tmp"
-_ACEOF
+# Check whether --with-changer-device or --without-changer-device was given.
+if test "${with_changer_device+set}" = set; then
+  withval="$with_changer_device"
 
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-changer-device option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-changer-device option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) DEFAULT_CHANGER_DEVICE="$withval"
+         ;;
+       esac
 
-    tmp=`eval echo $mandir`
+else
 
-cat >>confdefs.h <<_ACEOF
-#define mandir "$tmp"
-_ACEOF
+       if test -z "$DEFAULT_CHANGER_DEVICE" &&
+          test -f /dev/ch0; then
+           DEFAULT_CHANGER_DEVICE=/dev/ch0
+       fi
 
-)
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+fi;
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+if test -z "$DEFAULT_CHANGER_DEVICE"; then
+    DEFAULT_CHANGER_DEVICE=/dev/null
 fi
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
 
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_CHANGER_DEVICE "$DEFAULT_CHANGER_DEVICE"
+_ACEOF
 
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
 
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+# Check whether --with-fqdn or --without-fqdn was given.
+if test "${with_fqdn+set}" = set; then
+  withval="$with_fqdn"
+  USE_FQDN=$withval
 else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+  : ${USE_FQDN=no}
 
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+fi;
+case "$USE_FQDN" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define USE_FQDN 1
+_ACEOF
 
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-fqdn option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-fqdn option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
 
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
 
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+# Check whether --with-broken-fsf or --without-broken-fsf was given.
+if test "${with_broken_fsf+set}" = set; then
+  withval="$with_broken_fsf"
+  HAVE_BROKEN_FSF=$withval
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+  : ${HAVE_BROKEN_FSF=no}
 
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+fi;
+case "$HAVE_BROKEN_FSF" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_BROKEN_FSF 1
+_ACEOF
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-broken-fsf option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-broken-fsf option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
 
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
 
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+# Check whether --with-reuseports or --without-reuseports was given.
+if test "${with_reuseports+set}" = set; then
+  withval="$with_reuseports"
+   case "$withval" in
+        y | ye | yes)
+          REUSEADDR=no;;
+        n | no)
+          REUSEADDR=yes;;
+        *)
+          REUSEADDR=no;;
+      esac
+
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+   REUSEADDR=yes;
+fi;
+case "$REUSEADDR" in
+n | no) :
+    ;;
+y |  ye | yes)
 
-  test -n "$ac_ct_CC" && break
-done
+cat >>confdefs.h <<\_ACEOF
+#define USE_REUSEADDR 1
+_ACEOF
 
-  CC=$ac_ct_CC
-fi
+    ;;
+*)
+    { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-reuseports option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-reuseports option." >&2;}
+   { (exit 1); exit 1; }; }
+    ;;
+esac
 
-fi
 
+# Check whether --with-gnutar or --without-gnutar was given.
+if test "${with_gnutar+set}" = set; then
+  withval="$with_gnutar"
 
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+       case "$withval" in
+           /*) GNUTAR="$withval";;
+           y|ye|yes) :;;
+           n|no) GNUTAR=;;
+           *)  { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-gnutar" >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-gnutar" >&2;}
+   { (exit 1); exit 1; }; };;
+       esac
 
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
-     "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-  (eval $ac_compiler --version </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
-  (eval $ac_compiler -v </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
-  (eval $ac_compiler -V </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
 
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
+fi;
 
-int
-main ()
-{
 
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
-  (eval $ac_link_default) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # Find the output, starting from the most likely.  This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
+# Check whether --with-smbclient or --without-smbclient was given.
+if test "${with_smbclient+set}" = set; then
+  withval="$with_smbclient"
 
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
-       ;;
-    conftest.$ac_ext )
-       # This is the source file.
-       ;;
-    [ab].out )
-       # We found the default executable, but exeext='' is most
-       # certainly right.
-       break;;
-    *.* )
-       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-       # FIXME: I believe we export ac_cv_exeext for Libtool,
-       # but it would be cool to find out if it's true.  Does anybody
-       # maintain Libtool? --akim.
-       export ac_cv_exeext
-       break;;
-    * )
-       break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+       case "$withval" in
+           /*) SAMBA_CLIENT="$withval";;
+           y|ye|yes) :;;
+           n|no) SAMBA_CLIENT=;;
+           *)  { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-smbclient" >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-smbclient" >&2;}
+   { (exit 1); exit 1; }; };;
+       esac
 
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-fi
 
-ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
+fi;
 
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-       cross_compiling=yes
-    else
-       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
+
+# Check whether --with-samba-user or --without-samba-user was given.
+if test "${with_samba_user+set}" = set; then
+  withval="$with_samba_user"
+      { { echo "$as_me:$LINENO: error: *** The samba-user option was deprecated, the username go in the amandapass" >&5
+echo "$as_me: error: *** The samba-user option was deprecated, the username go in the amandapass" >&2;}
    { (exit 1); exit 1; }; }
-    fi
-  fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
 
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
 
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-         export ac_cv_exeext
-         break;;
-    * ) break;;
-  esac
-done
-else
-  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
+fi;
 
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
 
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check whether --with-gnutar-listdir or --without-gnutar-listdir was given.
+if test "${with_gnutar_listdir+set}" = set; then
+  withval="$with_gnutar_listdir"
+
+       case "$withval" in
+           n | no)             unset GNUTAR_LISTDIR ;;
+           y | ye | yes)       : ${GNUTAR_LISTDIR=$localstatedir/amanda/gnutar-lists} ;;
+           /*)                 GNUTAR_LISTDIR="$withval" ;;
+           *)                  { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-gnutar-listdir" >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-gnutar-listdir" >&2;}
+   { (exit 1); exit 1; }; }
+       esac
+
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
+  : ${GNUTAR_LISTDIR="$localstatedir/amanda/gnutar-lists"}
 
-int
-main ()
-{
+fi;
+if test "$GNUTAR_LISTDIR"; then
+    GNUTAR_LISTDIR=`(
+        test "x$prefix" = xNONE && prefix=$ac_default_prefix
+        eval echo "$GNUTAR_LISTDIR"
+    )`
 
-  ;
-  return 0;
-}
+cat >>confdefs.h <<_ACEOF
+#define GNUTAR_LISTED_INCREMENTAL_DIR "$GNUTAR_LISTDIR"
 _ACEOF
-rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
+
+    GNUTAR_LISTED_INCREMENTAL_DIRX=$GNUTAR_LISTDIR
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+    GNUTAR_LISTED_INCREMENTAL_DIRX=
+fi
 
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
+
+
+# Check whether --with-gnutar-listed-incremental or --without-gnutar-listed-incremental was given.
+if test "${with_gnutar_listed_incremental+set}" = set; then
+  withval="$with_gnutar_listed_incremental"
+      { { echo "$as_me:$LINENO: error: *** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead" >&5
+echo "$as_me: error: *** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead" >&2;}
    { (exit 1); exit 1; }; }
-fi
 
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
 
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
+fi;
+GNUTAR_LISTED_INCREMENTAL_DIR=$GNUTAR_LISTDIR
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_compiler_gnu=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_compiler_gnu=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check whether --with-bsd-security or --without-bsd-security was given.
+if test "${with_bsd_security+set}" = set; then
+  withval="$with_bsd_security"
+  BSD_SECURITY=$withval
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+  : ${BSD_SECURITY=yes}
+
+fi;
+case "$BSD_SECURITY" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define BSD_SECURITY 1
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
 
-int
-main ()
-{
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-bsd-security option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-bsd-security option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_prog_cc_g=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check whether --with-amandahosts or --without-amandahosts was given.
+if test "${with_amandahosts+set}" = set; then
+  withval="$with_amandahosts"
+  USE_AMANDAHOSTS=$withval
 else
-  ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+  : ${USE_AMANDAHOSTS=yes}
+
+fi;
+case "$USE_AMANDAHOSTS" in
+n | no) : ;;
+y |  ye | yes) :
+  case "$BSD_SECURITY" in
+  y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define USE_AMANDAHOSTS 1
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
 
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std1 is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std1.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+    ;;
+  esac
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-amandahosts option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-amandahosts option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
 
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX                  -qlanglvl=ansi
-# Ultrix and OSF/1     -std1
-# HP-UX 10.20 and later        -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4                 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_stdc=$ac_arg
-break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-fi
-rm -f conftest.err conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
 
-fi
+# Check whether --with-dbmalloc or --without-dbmalloc was given.
+if test "${with_dbmalloc+set}" = set; then
+  withval="$with_dbmalloc"
+  DBMALLOC="$withval"
+else
+  : ${DBMALLOC=no}
 
-case "x$ac_cv_prog_cc_stdc" in
-  x|xno)
-    echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
-  *)
-    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
-    CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
+fi;
+
+case "$DBMALLOC" in
+n | no)
+    DBMALLOCCFLAGS=""
+    DBMALLOCLIBS=""
+    ;;
+*)
 
-# Some people use a C++ compiler to compile C.  Since we use `exit',
-# in C++ we need to declare it.  In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
+echo "$as_me:$LINENO: checking for malloc in -ldbmalloc" >&5
+echo $ECHO_N "checking for malloc in -ldbmalloc... $ECHO_C" >&6
+if test "${ac_cv_lib_dbmalloc_malloc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldbmalloc  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
-  choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  for ac_declaration in \
-   '' \
-   'extern "C" void std::exit (int) throw (); using std::exit;' \
-   'extern "C" void std::exit (int); using std::exit;' \
-   'extern "C" void exit (int) throw ();' \
-   'extern "C" void exit (int);' \
-   'void exit (int);'
-do
-  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_declaration
-#include <stdlib.h>
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char malloc ();
 int
 main ()
 {
-exit (42);
+malloc ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -4665,38 +4858,518 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
+        { ac_try='test -s conftest$ac_exeext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  :
+  ac_cv_lib_dbmalloc_malloc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-continue
+ac_cv_lib_dbmalloc_malloc=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dbmalloc_malloc" >&5
+echo "${ECHO_T}$ac_cv_lib_dbmalloc_malloc" >&6
+if test $ac_cv_lib_dbmalloc_malloc = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDBMALLOC 1
+_ACEOF
+
+  LIBS="-ldbmalloc $LIBS"
+
+fi
+
+    if test "x$ac_cv_lib_dbmalloc_malloc" != "xyes"; then
+      { echo "$as_me:$LINENO: WARNING: *** dbmalloc library not found - no malloc debugging support!" >&5
+echo "$as_me: WARNING: *** dbmalloc library not found - no malloc debugging support!" >&2;}
+      DBMALLOCCFLAGS=""
+      DBMALLOCLIBS=""
+    else
+      DBMALLOCCFLAGS="-I$DBMALLOC -DUSE_DBMALLOC"
+      DBMALLOCLIBS="-L$DBMALLOC -ldbmalloc"
+    fi
+    ;;
+esac
+
+
+: ${KRB4_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
+
+
+# Check whether --with-krb4-security or --without-krb4-security was given.
+if test "${with_krb4_security+set}" = set; then
+  withval="$with_krb4_security"
+  KRB4_SECURITY="$withval"
+else
+  : ${KRB4_SECURITY=no}
+
+fi;
+
+case "$KRB4_SECURITY" in
+n | no) KRB4_SECURITY=no ;;
+y | ye | yes) : ;;
+*) KRB4_SPOTS="$KRB4_SECURITY"
+   KRB4_SECURITY=yes
+   ;;
+esac
+
+echo "$as_me:$LINENO: checking for Kerberos and Amanda kerberos4 bits" >&5
+echo $ECHO_N "checking for Kerberos and Amanda kerberos4 bits... $ECHO_C" >&6
+if test "x${KRB4_SECURITY}" = xyes -a -f  ${srcdir-.}/common-src/krb4-security.c ; then
+    for dir in $KRB4_SPOTS; do
+       if test -f ${dir}/lib/libkrb.a -a -f ${dir}/lib/libdes.a ; then
+           #
+           # This is the original Kerberos 4.
+           #
+           echo "$as_me:$LINENO: result: found in $dir" >&5
+echo "${ECHO_T}found in $dir" >&6
+           KRB4_SECURITY=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define KRB4_SECURITY 1
+_ACEOF
+
+           if test -d $dir/include/kerberosIV ; then
+               #
+               # This handles BSD/OS.
+               #
+               KRB4INCLUDES=-I$dir/include/kerberosIV
+           else
+               KRB4INCLUDES=-I$dir/include
+           fi
+           KRB4LDFLAGS=-L$dir/lib
+           KRB4LIBS="-lkrb -ldes"
+           if test -f ${dir}/lib/libcom_err.a; then
+               KRB4LIBS="$KRB4LIBS -lcom_err"
+           fi
+           break
+       elif test -f ${dir}/lib/libkrb4.a &&
+            test -f ${dir}/lib/libcrypto.a &&
+            test -f ${dir}/lib/libdes425.a ; then
+           #
+           # This is Kerberos 5 with Kerberos 4 back-support.
+           #
+           echo "$as_me:$LINENO: result: found in $dir" >&5
+echo "${ECHO_T}found in $dir" >&6
+           KRB4_SECURITY=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define KRB4_SECURITY 1
+_ACEOF
+
+           KRB4INCLUDES="-I$dir/include -I$dir/include/kerberosIV"
+           KRB4LDFLAGS=-L$dir/lib
+           if test -f ${dir}/lib/libkrb5.a &&
+               test -f ${dir}/lib/libcom_err.a; then
+               KRB4LIBS="-lkrb4 -lkrb5 -lcrypto -ldes425 -lcom_err"
+           else
+               KRB4LIBS="-lkrb4 -lcrypto -ldes425"
+           fi
+           break
+       fi
+    done
+
+    if test "x$KRB4LDFLAGS" = "x" ; then
+       echo "$as_me:$LINENO: result: no libraries found" >&5
+echo "${ECHO_T}no libraries found" >&6
+    fi
+else
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+# Check whether --with-rsh-security or --without-rsh-security was given.
+if test "${with_rsh_security+set}" = set; then
+  withval="$with_rsh_security"
+  RSH_SECURITY=$withval
+else
+  : ${RSH_SECURITY=yes}
+
+fi;
+case "$RSH_SECURITY" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define RSH_SECURITY 1
+_ACEOF
+
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-rsh-security option." >&5
+echo "$as_me: error: *** You must not supply an argument the to --with-rsh-security option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
+
+
+# Check whether --with-ssh-security or --without-ssh-security was given.
+if test "${with_ssh_security+set}" = set; then
+  withval="$with_ssh_security"
+  SSH_SECURITY=$withval
+else
+  : ${SSH_SECURITY=no}
+
+fi;
+case "$SSH_SECURITY" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define SSH_SECURITY 1
+_ACEOF
+
+              SSH_SECURITY_SET=true
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-ssh-security option." >&5
+echo "$as_me: error: *** You must not supply an argument the to --with-ssh-security option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
+
+
+# Check whether --with-bsdtcp-security or --without-bsdtcp-security was given.
+if test "${with_bsdtcp_security+set}" = set; then
+  withval="$with_bsdtcp_security"
+  BSDTCP_SECURITY=$withval
+else
+  : ${BSDTCP_SECURITY=yes}
+
+fi;
+case "$BSDTCP_SECURITY" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define BSDTCP_SECURITY 1
+_ACEOF
+
+              BSDTCP_SECURITY_SET=true
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-bsdtcp-security option." >&5
+echo "$as_me: error: *** You must not supply an argument the to --with-bsdtcp-security option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
+
+
+# Check whether --with-bsdudp-security or --without-bsdudp-security was given.
+if test "${with_bsdudp_security+set}" = set; then
+  withval="$with_bsdudp_security"
+  BSDUDP_SECURITY=$withval
+else
+  : ${BSDUDP_SECURITY=yes}
+
+fi;
+case "$BSDUDP_SECURITY" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define BSDUDP_SECURITY 1
+_ACEOF
+
+              BSDUDP_SECURITY_SET=true
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-bsdudp-security option." >&5
+echo "$as_me: error: *** You must not supply an argument the to --with-bsdudp-security option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
+
+
+# Check whether --with-server-principal or --without-server-principal was given.
+if test "${with_server_principal+set}" = set; then
+  withval="$with_server_principal"
+
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-principal option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-server-principal option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *)
+           SERVER_HOST_PRINCIPLE="$withval"
+         ;;
+       esac
+
+else
+  : ${SERVER_HOST_PRINCIPLE="amanda"}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define SERVER_HOST_PRINCIPLE "$SERVER_HOST_PRINCIPLE"
+_ACEOF
+
+
+
+# Check whether --with-server-instance or --without-server-instance was given.
+if test "${with_server_instance+set}" = set; then
+  withval="$with_server_instance"
+
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-instance option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-server-instance option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) SERVER_HOST_INSTANCE="$withval"
+         ;;
+       esac
+
+else
+  : ${SERVER_HOST_INSTANCE="amanda"}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define SERVER_HOST_INSTANCE "$SERVER_HOST_INSTANCE"
+_ACEOF
+
+
+
+# Check whether --with-server-keyfile or --without-server-keyfile was given.
+if test "${with_server_keyfile+set}" = set; then
+  withval="$with_server_keyfile"
+
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-keyfile option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-server-keyfile option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) SERVER_HOST_KEY_FILE="$withval"
+         ;;
+       esac
+
+else
+  : ${SERVER_HOST_KEY_FILE="/.amanda"}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define SERVER_HOST_KEY_FILE "$SERVER_HOST_KEY_FILE"
+_ACEOF
+
+
+
+# Check whether --with-client-principal or --without-client-principal was given.
+if test "${with_client_principal+set}" = set; then
+  withval="$with_client_principal"
+
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-principal option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-client-principal option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) CLIENT_HOST_PRINCIPLE="$withval"
+         ;;
+       esac
+
+else
+  : ${CLIENT_HOST_PRINCIPLE="rcmd"}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define CLIENT_HOST_PRINCIPLE "$CLIENT_HOST_PRINCIPLE"
+_ACEOF
+
+
+
+# Check whether --with-client-instance or --without-client-instance was given.
+if test "${with_client_instance+set}" = set; then
+  withval="$with_client_instance"
+
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-instance option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-client-instance option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) CLIENT_HOST_INSTANCE="$withval"
+         ;;
+       esac
+
+else
+  : ${CLIENT_HOST_INSTANCE=HOSTNAME_INSTANCE}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define CLIENT_HOST_INSTANCE $CLIENT_HOST_INSTANCE
+_ACEOF
+
+
+
+# Check whether --with-client-keyfile or --without-client-keyfile was given.
+if test "${with_client_keyfile+set}" = set; then
+  withval="$with_client_keyfile"
+
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-keyfile option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-client-keyfile option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) CLIENT_HOST_KEY_FILE="$withval"
+         ;;
+       esac
+
+else
+  : ${CLIENT_HOST_KEY_FILE=KEYFILE}
+
+fi;
+
+# Assume it's either KEYFILE (defined in krb.h), or a string filename...
+if test "x$CLIENT_HOST_KEY_FILE" != "xKEYFILE"; then
+  CLIENT_HOST_KEY_FILE="\"$CLIENT_HOST_KEY_FILE\""
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define CLIENT_HOST_KEY_FILE $CLIENT_HOST_KEY_FILE
+_ACEOF
+
+
+
+# Check whether --with-ticket-lifetime or --without-ticket-lifetime was given.
+if test "${with_ticket_lifetime+set}" = set; then
+  withval="$with_ticket_lifetime"
+
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-ticket-lifetime option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-ticket-lifetime option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) TICKET_LIFETIME="$withval"
+         ;;
+       esac
+
+else
+  : ${TICKET_LIFETIME=128}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define TICKET_LIFETIME $TICKET_LIFETIME
+_ACEOF
+
+
+
+: ${KRB5_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
+
+
+# Check whether --with-krb5-security or --without-krb5-security was given.
+if test "${with_krb5_security+set}" = set; then
+  withval="$with_krb5_security"
+  KRB5_SECURITY="$withval"
+else
+  : ${KRB5_SECURITY=no}
+
+fi;
+
+case "$KRB5_SECURITY" in
+n | no) KRB5_SECURITY=no
+        KRB5_SPOTS=""
+       ;;
+y | ye | yes) : ;;
+*) KRB5_SPOTS="$KRB5_SECURITY"
+   KRB5_SECURITY=yes
+   ;;
+esac
+
+# if found, force the static versions of these libs (.a) by linking directly
+# with the .a files.  I don't know how to get -R dependancies checked
+# in autoconf at this time. -kashmir
+echo "$as_me:$LINENO: checking for Kerberos V" >&5
+echo $ECHO_N "checking for Kerberos V... $ECHO_C" >&6
+KRB5_DIR_FOUND=""
+KRB5_CFLAGS=""
+for dir in $KRB5_SPOTS; do
+  for lib in lib lib64; do
+    k5libdir=${dir}/${lib}
+    if test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libgssapi_krb5.a -a -f ${k5libdir}/libcom_err.a; then
+       if test -f ${k5libdir}/libk5crypto.a; then
+           K5CRYPTO=${k5libdir}/libk5crypto.a
+       elif test -f ${k5libdir}/libcrypto.a; then
+           K5CRYPTO=${k5libdir}/libcrypto.a
+       else
+           K5CRYPTO=""
+       fi
+       if test -f ${k5libdir}/libkrb5support.a; then
+           K5SUPPORT=${k5libdir}/libkrb5support.a
+       else
+           K5SUPPORT=""
+       fi
+       KRB5_DIR_FOUND=$dir
+       KRB5LIBS="${k5libdir}/libgssapi_krb5.a ${k5libdir}/libkrb5.a $K5CRYPTO $K5SUPPORT ${k5libdir}/libcom_err.a"
+       KRB5CFLAGS=""
+       break
+    elif test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libasn1.a -a -f ${k5libdir}/libgssapi.a; then
+       KRB5_DIR_FOUND=$dir
+       KRB5LIBS="${k5libdir}/libgssapi.a ${k5libdir}/libkrb5.a ${k5libdir}/libasn1.a"
+       KRB5_CFLAGS="-DKRB5_HEIMDAL_INCLUDES"
+       break
+    fi
+  done
+done
+
+if test "$KRB5_DIR_FOUND"; then
+       echo "$as_me:$LINENO: result: found in $KRB5_DIR_FOUND" >&5
+echo "${ECHO_T}found in $KRB5_DIR_FOUND" >&6
+       KRB5_SECURITY=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define KRB5_SECURITY 1
+_ACEOF
+
+       #
+       # some OS's, such as NetBSD, stick krb5 includes out of the way...
+       # should probably just use autoconf to look for various include
+       # options and set them, but don't quite want to do that until I've
+       # dug into it a bit more.
+       #
+       if test -d "$KRB5_DIR_FOUND/krb5" ; then
+               KRB5INCLUDES="-I$KRB5_DIR_FOUND/include/krb5"
+       else
+               KRB5INCLUDES="-I$KRB5_DIR_FOUND/include"
+       fi
+       if test "$KRB5_CFLAGS" ; then
+               KRB5INCLUDES="$KRB5INCLUDES $KRB5_CFLAGS"
+       fi
+
+echo "$as_me:$LINENO: checking for main in -lkrb5support" >&5
+echo $ECHO_N "checking for main in -lkrb5support... $ECHO_C" >&6
+if test "${ac_cv_lib_krb5support_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_declaration
+
+
 int
 main ()
 {
-exit (42);
+main ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -4710,215 +5383,429 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
+        { ac_try='test -s conftest$ac_exeext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  break
+  ac_cv_lib_krb5support_main=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+ac_cv_lib_krb5support_main=no
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
-  echo '#ifdef __cplusplus' >>confdefs.h
-  echo $ac_declaration      >>confdefs.h
-  echo '#endif'             >>confdefs.h
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb5support_main" >&5
+echo "${ECHO_T}$ac_cv_lib_krb5support_main" >&6
+if test $ac_cv_lib_krb5support_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBKRB5SUPPORT 1
+_ACEOF
 
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  LIBS="-lkrb5support $LIBS"
 
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-DEPDIR="${am__leading_dot}deps"
 
-          ac_config_commands="$ac_config_commands depfiles"
+       KRB5LDFLAGS=-L$k5libdir
+       break
+fi
+
+if test "x$KRB5LDFLAGS" = "x" ; then
+    echo "$as_me:$LINENO: result: no krb5 system libraries found" >&5
+echo "${ECHO_T}no krb5 system libraries found" >&6
+fi
 
 
-am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
-       @echo done
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
-echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# We grep out `Entering directory' and `Leaving directory'
-# messages which can occur if `w' ends up in MAKEFLAGS.
-# In particular we don't look at `^make:' because GNU make might
-# be invoked under some other name (usually "gmake"), in which
-# case it prints its new name instead of `make'.
-if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
-   am__include=include
-   am__quote=
-   _am_result=GNU
+
+# Check whether --with-low-tcpportrange or --without-low-tcpportrange was given.
+if test "${with_low_tcpportrange+set}" = set; then
+  withval="$with_low_tcpportrange"
+
+       LOW_TCPPORTRANGE="$withval"
+
+
+fi;
+
+if test x"${LOW_TCPPORTRANGE+set}" = x"set"; then
+    if test x`echo "$LOW_TCPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
+       { { echo "$as_me:$LINENO: error: *** --with-low-tcpportrange requires two comma-separated positive numbers" >&5
+echo "$as_me: error: *** --with-low-tcpportrange requires two comma-separated positive numbers" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    min_low_tcp_port=`echo "$LOW_TCPPORTRANGE" | sed 's/,.*//'`
+    max_low_tcp_port=`echo "$LOW_TCPPORTRANGE" | sed 's/.*,//'`
+    if test $min_low_tcp_port -gt $max_low_tcp_port; then
+       { { echo "$as_me:$LINENO: error: *** the second TCP port number must be greater than the first in --with-low-tcpportrange" >&5
+echo "$as_me: error: *** the second TCP port number must be greater than the first in --with-low-tcpportrange" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test $min_low_tcp_port -lt 512; then
+       { echo "$as_me:$LINENO: WARNING: *** the low TCP port range should be 512 or greater in --with-low-tcpportrange" >&5
+echo "$as_me: WARNING: *** the low TCP port range should be 512 or greater in --with-low-tcpportrange" >&2;}
+    fi
+    if test $max_low_tcp_port -ge 1024; then
+       { echo "$as_me:$LINENO: WARNING: *** the low TCP port range should be less than 1024 in --with-low-tcpportrange" >&5
+echo "$as_me: WARNING: *** the low TCP port range should be less than 1024 in --with-low-tcpportrange" >&2;}
+    fi
+
+cat >>confdefs.h <<_ACEOF
+#define LOW_TCPPORTRANGE $LOW_TCPPORTRANGE
+_ACEOF
+
 fi
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
-      am__include=.include
-      am__quote="\""
-      _am_result=BSD
-   fi
+
+
+# Check whether --with-tcpportrange or --without-tcpportrange was given.
+if test "${with_tcpportrange+set}" = set; then
+  withval="$with_tcpportrange"
+
+       TCPPORTRANGE="$withval"
+
+
+fi;
+if test x"${TCPPORTRANGE+set}" = x"set"; then
+    if test x`echo "$TCPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
+       { { echo "$as_me:$LINENO: error: *** --with-tcpportrange requires two comma-separated positive numbers" >&5
+echo "$as_me: error: *** --with-tcpportrange requires two comma-separated positive numbers" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    min_tcp_port=`echo "$TCPPORTRANGE" | sed 's/,.*//'`
+    max_tcp_port=`echo "$TCPPORTRANGE" | sed 's/.*,//'`
+    if test $min_tcp_port -gt $max_tcp_port; then
+       { { echo "$as_me:$LINENO: error: *** the second TCP port number must be greater than the first in --with-tcpportrange" >&5
+echo "$as_me: error: *** the second TCP port number must be greater than the first in --with-tcpportrange" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test $min_tcp_port -lt 1024; then
+       { echo "$as_me:$LINENO: WARNING: *** the TCP port range should be 1024 or greater in --with-tcpportrange" >&5
+echo "$as_me: WARNING: *** the TCP port range should be 1024 or greater in --with-tcpportrange" >&2;}
+    fi
+    if test $max_tcp_port -ge 65536; then
+       { echo "$as_me:$LINENO: WARNING: *** the TCP port range should be less than 65536 in --with-tcpportrange" >&5
+echo "$as_me: WARNING: *** the TCP port range should be less than 65536 in --with-tcpportrange" >&2;}
+    fi
+
+cat >>confdefs.h <<_ACEOF
+#define TCPPORTRANGE $TCPPORTRANGE
+_ACEOF
+
 fi
 
 
-echo "$as_me:$LINENO: result: $_am_result" >&5
-echo "${ECHO_T}$_am_result" >&6
-rm -f confinc confmf
+# Check whether --with-udpportrange or --without-udpportrange was given.
+if test "${with_udpportrange+set}" = set; then
+  withval="$with_udpportrange"
+
+       UDPPORTRANGE="$withval"
 
-# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then
-  enableval="$enable_dependency_tracking"
 
 fi;
-if test "x$enable_dependency_tracking" != xno; then
-  am_depcomp="$ac_aux_dir/depcomp"
-  AMDEPBACKSLASH='\'
+if test x"${UDPPORTRANGE+set}" = x"set"; then
+    if test x`echo "$UDPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
+       { { echo "$as_me:$LINENO: error: *** --with-udpportrange requires two comma-separated positive numbers" >&5
+echo "$as_me: error: *** --with-udpportrange requires two comma-separated positive numbers" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    min_udp_port=`echo "$UDPPORTRANGE" | sed 's/,.*//'`
+    max_udp_port=`echo "$UDPPORTRANGE" | sed 's/.*,//'`
+    if test $min_udp_port -gt $max_udp_port; then
+       { { echo "$as_me:$LINENO: error: *** the second UDP port number must be greater than the first in --with-udpportrange" >&5
+echo "$as_me: error: *** the second UDP port number must be greater than the first in --with-udpportrange" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    if test $max_udp_port -ge 1024; then
+       { echo "$as_me:$LINENO: WARNING: *** the UDP port range should be less than 1024 in --with-udpportrange" >&5
+echo "$as_me: WARNING: *** the UDP port range should be less than 1024 in --with-udpportrange" >&2;}
+    fi
+    if test $min_udp_port -le 0; then
+       { echo "$as_me:$LINENO: WARNING: *** the UDP port range should be greater than 0 in --with-udpportrange" >&5
+echo "$as_me: WARNING: *** the UDP port range should be greater than 0 in --with-udpportrange" >&2;}
+    fi
+
+cat >>confdefs.h <<_ACEOF
+#define UDPPORTRANGE $UDPPORTRANGE
+_ACEOF
+
 fi
 
 
-if test "x$enable_dependency_tracking" != xno; then
-  AMDEP_TRUE=
-  AMDEP_FALSE='#'
+# Check whether --with-maxtapeblocksize or --without-maxtapeblocksize was given.
+if test "${with_maxtapeblocksize+set}" = set; then
+  withval="$with_maxtapeblocksize"
+
+       MAXTAPEBLOCKSIZE="$withval"
+
 else
-  AMDEP_TRUE='#'
-  AMDEP_FALSE=
+  : ${MAXTAPEBLOCKSIZE=32}
+
+fi;
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAX_TAPE_BLOCK_KB ($MAXTAPEBLOCKSIZE)
+_ACEOF
+
+
+
+
+# Check whether --with-db or --without-db was given.
+if test "${with_db+set}" = set; then
+  withval="$with_db"
+
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-db option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-db option." >&2;}
+   { (exit 1); exit 1; }; }
+         ;;
+       *) DB_STYLE="$withval"
+         ;;
+       esac
+
+
+fi;
+if test "$DB_STYLE"; then
+    case "$DB_STYLE" in
+       db | dbm | gdbm | ndbm | text)  ;;
+       *)
+           { { echo "$as_me:$LINENO: error: *** Unknown argument $DB_STYLE given to --with-db.  Choose from db, dbm, gdbm, ndbm, text." >&5
+echo "$as_me: error: *** Unknown argument $DB_STYLE given to --with-db.  Choose from db, dbm, gdbm, ndbm, text." >&2;}
+   { (exit 1); exit 1; }; }
+           DB_STYLE=
+           ;;
+    esac
 fi
 
 
+# Check whether --with-mmap or --without-mmap was given.
+if test "${with_mmap+set}" = set; then
+  withval="$with_mmap"
+  FORCE_MMAP=$withval
+else
+  : ${FORCE_MMAP=no}
 
+fi;
+case "$FORCE_MMAP" in
+y | ye | yes | n | no) : ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-mmap." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-mmap." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
 
-depcc="$CC"   am_compiler_list=
 
-echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
-echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
-if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check whether --with-buffered-dump or --without-buffered-dump was given.
+if test "${with_buffered_dump+set}" = set; then
+  withval="$with_buffered_dump"
+  DUMPER_SOCKET_BUFFERING=$withval
 else
-  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
-  # We make a subdir and do the tests there.  Otherwise we can end up
-  # making bogus files that we don't know about and never remove.  For
-  # instance it was reported that on HP-UX the gcc test will end up
-  # making a dummy file named `D' -- because `-MD' means `put the output
-  # in D'.
-  mkdir conftest.dir
-  # Copy depcomp to subdir because otherwise we won't find it if we're
-  # using a relative directory.
-  cp "$am_depcomp" conftest.dir
-  cd conftest.dir
-  # We will build objects and dependencies in a subdirectory because
-  # it helps to detect inapplicable dependency modes.  For instance
-  # both Tru64's cc and ICC support -MD to output dependencies as a
-  # side effect of compilation, but ICC will put the dependencies in
-  # the current directory while Tru64 will put them in the object
-  # directory.
-  mkdir sub
+  : ${DUMPER_SOCKET_BUFFERING=no}
 
-  am_cv_CC_dependencies_compiler_type=none
-  if test "$am_compiler_list" = ""; then
-     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
-  fi
-  for depmode in $am_compiler_list; do
-    # Setup a source with many dependencies, because some compilers
-    # like to wrap large dependency lists on column 80 (with \), and
-    # we should not choose a depcomp mode which is confused by this.
-    #
-    # We need to recreate these files for each test, as the compiler may
-    # overwrite some of them when testing with obscure command lines.
-    # This happens at least with the AIX C compiler.
-    : > sub/conftest.c
-    for i in 1 2 3 4 5 6; do
-      echo '#include "conftst'$i'.h"' >> sub/conftest.c
-      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
-      # Solaris 8's {/usr,}/bin/sh.
-      touch sub/conftst$i.h
-    done
-    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+fi;
+case "$DUMPER_SOCKET_BUFFERING" in
+n | no) :
+  ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define DUMPER_SOCKET_BUFFERING 1
+_ACEOF
 
-    case $depmode in
-    nosideeffect)
-      # after this tag, mechanisms are not by side-effect, so they'll
-      # only be used when explicitly requested
-      if test "x$enable_dependency_tracking" = xyes; then
-       continue
-      else
-       break
-      fi
-      ;;
-    none) break ;;
-    esac
-    # We check with `-c' and `-o' for the sake of the "dashmstdout"
-    # mode.  It turns out that the SunPro C++ compiler does not properly
-    # handle `-M -o', and we need to detect this.
-    if depmode=$depmode \
-       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
-       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
-       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
-         >/dev/null 2>conftest.err &&
-       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
-       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
-       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
-      # icc doesn't choke on unknown options, it will just issue warnings
-      # or remarks (even with -Werror).  So we grep stderr for any message
-      # that says an option was ignored or not supported.
-      # When given -MP, icc 7.0 and 7.1 complain thusly:
-      #   icc: Command line warning: ignoring option '-M'; no argument required
-      # The diagnosis changed in icc 8.0:
-      #   icc: Command line remark: option '-MP' not supported
-      if (grep 'ignoring option' conftest.err ||
-          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
-        am_cv_CC_dependencies_compiler_type=$depmode
-        break
-      fi
-    fi
-  done
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-buffered-dump." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-buffered-dump." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
 
-  cd ..
-  rm -rf conftest.dir
+
+# Check whether --with-assertions or --without-assertions was given.
+if test "${with_assertions+set}" = set; then
+  withval="$with_assertions"
+  ASSERTIONS="$withval"
 else
-  am_cv_CC_dependencies_compiler_type=none
-fi
+  : ${ASSERTIONS=no}
 
-fi
-echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
-echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+fi;
+case "$ASSERTIONS" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define ASSERTIONS 1
+_ACEOF
 
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-assertions option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-assertions option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
 
 
-if
-  test "x$enable_dependency_tracking" != xno \
-  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
-  am__fastdepCC_TRUE=
-  am__fastdepCC_FALSE='#'
+# Check whether --with-tmpdir or --without-tmpdir was given.
+if test "${with_tmpdir+set}" = set; then
+  withval="$with_tmpdir"
+  tmpdir="$withval"
 else
-  am__fastdepCC_TRUE='#'
-  am__fastdepCC_FALSE=
-fi
+  : ${tmpdir=yes}
+
+fi;
+tmpdir=`(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+    eval echo "$tmpdir"
+)`
+case "$tmpdir" in
+n | no) { { echo "$as_me:$LINENO: error: *** --without-tmpdir is not allowed." >&5
+echo "$as_me: error: *** --without-tmpdir is not allowed." >&2;}
+   { (exit 1); exit 1; }; };;
+y |  ye | yes)
+       AMANDA_TMPDIR="/tmp/amanda";;
+/*)
+       AMANDA_TMPDIR="$tmpdir";;
+*) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-tmpdir option." >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-tmpdir option." >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define AMANDA_TMPDIR "$AMANDA_TMPDIR"
+_ACEOF
+
 
 
 
+# Check whether --with-debugging or --without-debugging was given.
+if test "${with_debugging+set}" = set; then
+  withval="$with_debugging"
+  debugging="$withval"
+else
+  : ${debugging=yes}
+
+fi;
+debugging=`(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+    eval echo "$debugging"
+)`
+case "$debugging" in
+n | no) AMANDA_DBGDIR="";;
+y |  ye | yes) AMANDA_DBGDIR="$AMANDA_TMPDIR";;
+/*) AMANDA_DBGDIR="$debugging";;
+*) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-debugging option." >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-debugging option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
+case "$AMANDA_DBGDIR" in
+"") :;;
+*)
+cat >>confdefs.h <<\_ACEOF
+#define DEBUG_CODE 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define AMANDA_DBGDIR "$AMANDA_DBGDIR"
+_ACEOF
+
+   ;;
+esac
+
+
+# Check whether --with-debug_days or --without-debug_days was given.
+if test "${with_debug_days+set}" = set; then
+  withval="$with_debug_days"
+  debug_days="$withval"
+else
+  : ${debug_days=4}
+
+fi;
+case "$debug_days" in
+n | no) AMANDA_DEBUG_DAYS=0 ;;
+y |  ye | yes) AMANDA_DEBUG_DAYS=4 ;;
+[0-9] | [0-9][0-9] | [0-9][0-9][0-9]) AMANDA_DEBUG_DAYS="$debug_days" ;;
+*) { { echo "$as_me:$LINENO: error: *** --with-debug-days value not numeric or out of range." >&5
+echo "$as_me: error: *** --with-debug-days value not numeric or out of range." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define AMANDA_DEBUG_DAYS $AMANDA_DEBUG_DAYS
+_ACEOF
+
+
+
+
+# Check whether --with-testing or --without-testing was given.
+if test "${with_testing+set}" = set; then
+  withval="$with_testing"
+  TESTING="$withval"
+else
+  : ${TESTING=no}
+
+fi;
+case "$TESTING" in
+n | no) SERVICE_SUFFIX="";;
+y |  ye | yes) SERVICE_SUFFIX="-test";;
+*) SERVICE_SUFFIX="-$TESTING";;
+esac
+AMANDA_SERVICE_NAME="amanda$SERVICE_SUFFIX"
+KAMANDA_SERVICE_NAME="kamanda$SERVICE_SUFFIX"
+
+
+cat >>confdefs.h <<_ACEOF
+#define SERVICE_SUFFIX "$SERVICE_SUFFIX"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define AMANDA_SERVICE_NAME "$AMANDA_SERVICE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define KAMANDA_SERVICE_NAME "$KAMANDA_SERVICE_NAME"
+_ACEOF
+
+
+(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+
+    tmp=`eval echo "$bindir"`
+
+cat >>confdefs.h <<_ACEOF
+#define bindir "$tmp"
+_ACEOF
+
+
+    tmp=`eval echo "$sbindir"`
+
+cat >>confdefs.h <<_ACEOF
+#define sbindir "$tmp"
+_ACEOF
+
 
+    tmp=`eval echo "$libexecdir"`
+
+cat >>confdefs.h <<_ACEOF
+#define libexecdir "$tmp"
+_ACEOF
+
+
+    tmp=`eval echo $mandir`
+
+cat >>confdefs.h <<_ACEOF
+#define mandir "$tmp"
+_ACEOF
+
+)
 
 DUMP_PROGRAMS="ufsdump dump backup"
 GETCONF_LFS="LFS"
@@ -4978,6 +5865,8 @@ _ACEOF
                        ;;
   *-pc-linux-*)
                        ;;
+  *-redhat-linux-*)
+                       ;;
   x86_64-*-linux-*)
                        ;;
   alpha*-*-linux-*)
@@ -5112,7 +6001,6 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -7974,19 +8862,323 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-cat >conftest.$ac_ext <<_ACEOF
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_voidp=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (void*)); }
+unsigned long ulongval () { return (long) (sizeof (void*)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (void*))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (void*))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (void*))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_voidp=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_voidp=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_voidp" >&5
+echo "${ECHO_T}$ac_cv_sizeof_voidp" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
+_ACEOF
+
+
+   ac_cv_char_data_model=""
+   ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char"
+   ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short"
+   ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int"
+   ac_cv_long_data_model=""
+   ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int"
+   ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long"
+   ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp"
+   echo "$as_me:$LINENO: checking data model" >&5
+echo $ECHO_N "checking data model... $ECHO_C" >&6
+   case "$ac_cv_char_data_model/$ac_cv_long_data_model" in
+    122/242)     ac_cv_data_model="IP16"  ; n="standard 16bit machine" ;;
+    122/244)     ac_cv_data_model="LP32"  ; n="standard 32bit machine" ;;
+    122/*)       ac_cv_data_model="i16"   ; n="unusual int16 model" ;;
+    124/444)     ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;;
+    124/488)     ac_cv_data_model="LP64"  ; n="standard 64bit unixish" ;;
+    124/448)     ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;;
+    124/*)       ac_cv_data_model="i32"   ; n="unusual int32 model" ;;
+    128/888)     ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;;
+    128/*)       ac_cv_data_model="i64"   ; n="unusual int64 model" ;;
+    222/*2)      ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;;
+    333/*3)      ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;;
+    444/*4)      ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;;
+    666/*6)      ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;;
+    888/*8)      ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;;
+    222/*|333/*|444/*|666/*|888/*) :
+                 ac_cv_data_model="iDSP"  ; n="unusual dsptype" ;;
+     *)          ac_cv_data_model="none"  ; n="very unusual model" ;;
+   esac
+   echo "$as_me:$LINENO: result: $ac_cv_data_model ($ac_cv_long_data_model, $n)" >&5
+echo "${ECHO_T}$ac_cv_data_model ($ac_cv_long_data_model, $n)" >&6
+
+fi
+
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_x"
+elif  test "_$ac_cv_header_stdint_o" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_o"
+elif  test "_$ac_cv_header_stdint_u" != "_" ; then
+   ac_cv_header_stdint="$ac_cv_header_stdint_u"
+else
+   ac_cv_header_stdint="stddef.h"
+fi
+
+echo "$as_me:$LINENO: checking for extra inttypes in chosen header" >&5
+echo $ECHO_N "checking for extra inttypes in chosen header... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: ($ac_cv_header_stdint)" >&5
+echo "${ECHO_T}($ac_cv_header_stdint)" >&6
+unset ac_cv_type_int_least32_t
+unset ac_cv_type_int_fast32_t
+echo "$as_me:$LINENO: checking for int_least32_t" >&5
+echo $ECHO_N "checking for int_least32_t... $ECHO_C" >&6
+if test "${ac_cv_type_int_least32_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
+#include <$ac_cv_header_stdint>
+
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (void*))) < 0)];
-test_array [0] = 0
-
+if ((int_least32_t *) 0)
+  return 0;
+if (sizeof (int_least32_t))
+  return 0;
   ;
   return 0;
 }
@@ -8013,21 +9205,38 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_hi=-1 ac_mid=-1
-  while :; do
-    cat >conftest.$ac_ext <<_ACEOF
+  ac_cv_type_int_least32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int_least32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int_least32_t" >&5
+echo "${ECHO_T}$ac_cv_type_int_least32_t" >&6
+
+echo "$as_me:$LINENO: checking for int_fast32_t" >&5
+echo $ECHO_N "checking for int_fast32_t... $ECHO_C" >&6
+if test "${ac_cv_type_int_fast32_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
+#include<$ac_cv_header_stdint>
+
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (void*))) >= $ac_mid)];
-test_array [0] = 0
-
+if ((int_fast32_t *) 0)
+  return 0;
+if (sizeof (int_fast32_t))
+  return 0;
   ;
   return 0;
 }
@@ -8054,45 +9263,38 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_lo=$ac_mid; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_hi=`expr '(' $ac_mid ')' - 1`
-                      if test $ac_mid -le $ac_hi; then
-                        ac_lo= ac_hi=
-                        break
-                      fi
-                      ac_mid=`expr 2 '*' $ac_mid`
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
+  ac_cv_type_int_fast32_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_lo= ac_hi=
+ac_cv_type_int_fast32_t=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
-  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+echo "$as_me:$LINENO: result: $ac_cv_type_int_fast32_t" >&5
+echo "${ECHO_T}$ac_cv_type_int_fast32_t" >&6
+
+echo "$as_me:$LINENO: checking for intmax_t" >&5
+echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6
+if test "${ac_cv_type_intmax_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
+#include <$ac_cv_header_stdint>
+
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (void*))) <= $ac_mid)];
-test_array [0] = 0
-
+if ((intmax_t *) 0)
+  return 0;
+if (sizeof (intmax_t))
+  return 0;
   ;
   return 0;
 }
@@ -8119,361 +9321,751 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_hi=$ac_mid
+  ac_cv_type_intmax_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_intmax_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5
+echo "${ECHO_T}$ac_cv_type_intmax_t" >&6
+
+
+fi # shortcircut to system "stdint.h"
+# ------------------ PREPARE VARIABLES ------------------------------
+if test "$GCC" = "yes" ; then
+ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1`
+else
+ac_cv_stdint_message="using $CC"
+fi
+
+echo "$as_me:$LINENO: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5
+echo "${ECHO_T}make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&6
+
+# ----------------- DONE inttypes.h checks START header -------------
+          ac_config_commands="$ac_config_commands $ac_stdint_h"
+
+
+
+for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $AR in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_AR="$AR" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+AR=$ac_cv_path_AR
+
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AR" && break
+done
+
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+
+
+       echo "$as_me:$LINENO: checking for $AWK command line variable assignment" >&5
+echo $ECHO_N "checking for $AWK command line variable assignment... $ECHO_C" >&6
+if test "${amanda_cv_awk_var_assignment+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               echo 'BEGIN{print i; exit}' > conftest.awk
+               result=`$AWK -f conftest.awk i=xx | wc -c`
+               if test "$result" -le 1; then
+                   result=`$AWK -f conftest.awk -v i=xx | wc -c`
+                   if test "$result" -le 1; then
+                       amanda_cv_awk_var_assignment=no
+                   else
+                       amanda_cv_awk_var_assignment="yes with -v"
+                   fi
+               else
+                   amanda_cv_awk_var_assignment="yes"
+               fi
+               rm -fr conftest.awk
+
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_awk_var_assignment" >&5
+echo "${ECHO_T}$amanda_cv_awk_var_assignment" >&6
+       AWK_VAR_ASSIGNMENT_OPT=
+       case "$amanda_cv_awk_var_assignment" in
+           no)
+               HAVE_AWK_WITH_VAR=no
+               ;;
+           yes)
+               HAVE_AWK_WITH_VAR=yes
+               ;;
+           "yes with -v")
+               HAVE_AWK_WITH_VAR=yes
+               AWK_VAR_ASSIGNMENT_OPT=-v
+               ;;
+       esac
+
+
+
+if test "x$amanda_cv_awk_var_assignment" = xno; then
+    NO_AMPLOT_MODE=true
+    { echo "$as_me:$LINENO: WARNING: *** Your $awk cannot do command line variable assignment.  Amplot will not be installed." >&5
+echo "$as_me: WARNING: *** Your $awk cannot do command line variable assignment.  Amplot will not be installed." >&2;}
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_YACC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+for ac_prog in cat
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_CAT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $CAT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_CAT="$CAT" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+CAT=$ac_cv_path_CAT
+
+if test -n "$CAT"; then
+  echo "$as_me:$LINENO: result: $CAT" >&5
+echo "${ECHO_T}$CAT" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$CAT" && break
+done
+
+if test -z "$CAT"; then
+    CAT=cat
+fi
+for ac_prog in compress
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_COMPRESS+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $COMPRESS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_COMPRESS="$COMPRESS" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_COMPRESS="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+COMPRESS=$ac_cv_path_COMPRESS
+
+if test -n "$COMPRESS"; then
+  echo "$as_me:$LINENO: result: $COMPRESS" >&5
+echo "${ECHO_T}$COMPRESS" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$COMPRESS" && break
+done
+
+for ac_prog in dd
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_DD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $DD in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DD="$DD" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DD="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+DD=$ac_cv_path_DD
+
+if test -n "$DD"; then
+  echo "$as_me:$LINENO: result: $DD" >&5
+echo "${ECHO_T}$DD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$DD" && break
+done
+
+for ac_prog in getconf
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GETCONF+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GETCONF in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $SYSPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GETCONF="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+GETCONF=$ac_cv_path_GETCONF
+
+if test -n "$GETCONF"; then
+  echo "$as_me:$LINENO: result: $GETCONF" >&5
+echo "${ECHO_T}$GETCONF" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$GETCONF" && break
+done
+
+
+for ac_prog in gnuplot
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GNUPLOT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GNUPLOT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GNUPLOT="$GNUPLOT" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GNUPLOT="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+GNUPLOT=$ac_cv_path_GNUPLOT
+
+if test -n "$GNUPLOT"; then
+  echo "$as_me:$LINENO: result: $GNUPLOT" >&5
+echo "${ECHO_T}$GNUPLOT" >&6
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-ac_lo=`expr '(' $ac_mid ')' + 1`
+  test -n "$GNUPLOT" && break
+done
+
+if test -z "$GNUPLOT"; then
+    NO_AMPLOT_MODE=true
+    { echo "$as_me:$LINENO: WARNING: *** You do not have gnuplot.  Amplot will not be installed." >&5
+echo "$as_me: WARNING: *** You do not have gnuplot.  Amplot will not be installed." >&2;}
 fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_prog in gtar gnutar tar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GNUTAR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GNUTAR in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GNUTAR="$GNUTAR" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GNUTAR="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
 done
-case $ac_lo in
-?*) ac_cv_sizeof_voidp=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (void*), 77
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; } ;;
+done
+
+  ;;
 esac
+fi
+GNUTAR=$ac_cv_path_GNUTAR
+
+if test -n "$GNUTAR"; then
+  echo "$as_me:$LINENO: result: $GNUTAR" >&5
+echo "${ECHO_T}$GNUTAR" >&6
 else
-  if test "$cross_compiling" = yes; then
-  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-long longval () { return (long) (sizeof (void*)); }
-unsigned long ulongval () { return (long) (sizeof (void*)); }
-#include <stdio.h>
-#include <stdlib.h>
-int
-main ()
-{
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-  FILE *f = fopen ("conftest.val", "w");
-  if (! f)
-    exit (1);
-  if (((long) (sizeof (void*))) < 0)
-    {
-      long i = longval ();
-      if (i != ((long) (sizeof (void*))))
-       exit (1);
-      fprintf (f, "%ld\n", i);
-    }
-  else
-    {
-      unsigned long i = ulongval ();
-      if (i != ((long) (sizeof (void*))))
-       exit (1);
-      fprintf (f, "%lu\n", i);
-    }
-  exit (ferror (f) || fclose (f) != 0);
+  test -n "$GNUTAR" && break
+done
 
-  ;
-  return 0;
-}
+if test ! -z "$GNUTAR"; then
+  case "`\"$GNUTAR\" --version 2>&1`" in
+   *GNU*tar* | *Free*paxutils* )
+
+cat >>confdefs.h <<_ACEOF
+#define GNUTAR "$GNUTAR"
 _ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_sizeof_voidp=`cat conftest.val`
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (void*), 77
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
+               ;;
+   *)
+               { echo "$as_me:$LINENO: WARNING: *** $GNUTAR is not GNU tar, so it will not be used." >&5
+echo "$as_me: WARNING: *** $GNUTAR is not GNU tar, so it will not be used." >&2;}
+               GNUTAR=
+               ;;
+  esac
 fi
-rm -f conftest.val
+
+for ac_prog in smbclient
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_SAMBA_CLIENT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_sizeof_voidp=0
+  case $SAMBA_CLIENT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_SAMBA_CLIENT="$SAMBA_CLIENT" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_SAMBA_CLIENT="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
 fi
+SAMBA_CLIENT=$ac_cv_path_SAMBA_CLIENT
+
+if test -n "$SAMBA_CLIENT"; then
+  echo "$as_me:$LINENO: result: $SAMBA_CLIENT" >&5
+echo "${ECHO_T}$SAMBA_CLIENT" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_voidp" >&5
-echo "${ECHO_T}$ac_cv_sizeof_voidp" >&6
+
+  test -n "$SAMBA_CLIENT" && break
+done
+
+if test ! -z "$SAMBA_CLIENT"; then
+  case "`\"$SAMBA_CLIENT\" '\\\\not.a.host.name\\notashare' -U nosuchuser -N -Tx /dev/null 2>&1`" in
+  *"Unknown host"*)
+               smbversion=1
+               ;;
+  *"Connection to not.a.host.name failed"*)
+               smbversion=2
+               ;;
+  *)
+               { echo "$as_me:$LINENO: WARNING: *** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used." >&5
+echo "$as_me: WARNING: *** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used." >&2;}
+               SAMBA_CLIENT=
+               ;;
+  esac
+  if test -n "$SAMBA_CLIENT"; then
+
 cat >>confdefs.h <<_ACEOF
-#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
+#define SAMBA_CLIENT "$SAMBA_CLIENT"
 _ACEOF
 
 
-   ac_cv_char_data_model=""
-   ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char"
-   ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short"
-   ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int"
-   ac_cv_long_data_model=""
-   ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int"
-   ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long"
-   ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp"
-   echo "$as_me:$LINENO: checking data model" >&5
-echo $ECHO_N "checking data model... $ECHO_C" >&6
-   case "$ac_cv_char_data_model/$ac_cv_long_data_model" in
-    122/242)     ac_cv_data_model="IP16"  ; n="standard 16bit machine" ;;
-    122/244)     ac_cv_data_model="LP32"  ; n="standard 32bit machine" ;;
-    122/*)       ac_cv_data_model="i16"   ; n="unusual int16 model" ;;
-    124/444)     ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;;
-    124/488)     ac_cv_data_model="LP64"  ; n="standard 64bit unixish" ;;
-    124/448)     ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;;
-    124/*)       ac_cv_data_model="i32"   ; n="unusual int32 model" ;;
-    128/888)     ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;;
-    128/*)       ac_cv_data_model="i64"   ; n="unusual int64 model" ;;
-    222/*2)      ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;;
-    333/*3)      ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;;
-    444/*4)      ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;;
-    666/*6)      ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;;
-    888/*8)      ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;;
-    222/*|333/*|444/*|666/*|888/*) :
-                 ac_cv_data_model="iDSP"  ; n="unusual dsptype" ;;
-     *)          ac_cv_data_model="none"  ; n="very unusual model" ;;
-   esac
-   echo "$as_me:$LINENO: result: $ac_cv_data_model ($ac_cv_long_data_model, $n)" >&5
-echo "${ECHO_T}$ac_cv_data_model ($ac_cv_long_data_model, $n)" >&6
+cat >>confdefs.h <<_ACEOF
+#define SAMBA_VERSION $smbversion
+_ACEOF
 
+  fi
 fi
 
-if test "_$ac_cv_header_stdint_x" != "_" ; then
-   ac_cv_header_stdint="$ac_cv_header_stdint_x"
-elif  test "_$ac_cv_header_stdint_o" != "_" ; then
-   ac_cv_header_stdint="$ac_cv_header_stdint_o"
-elif  test "_$ac_cv_header_stdint_u" != "_" ; then
-   ac_cv_header_stdint="$ac_cv_header_stdint_u"
+for ac_prog in gzip
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GZIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-   ac_cv_header_stdint="stddef.h"
+  case $GZIP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GZIP="$GZIP" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
 fi
+GZIP=$ac_cv_path_GZIP
 
-echo "$as_me:$LINENO: checking for extra inttypes in chosen header" >&5
-echo $ECHO_N "checking for extra inttypes in chosen header... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: ($ac_cv_header_stdint)" >&5
-echo "${ECHO_T}($ac_cv_header_stdint)" >&6
-unset ac_cv_type_int_least32_t
-unset ac_cv_type_int_fast32_t
-echo "$as_me:$LINENO: checking for int_least32_t" >&5
-echo $ECHO_N "checking for int_least32_t... $ECHO_C" >&6
-if test "${ac_cv_type_int_least32_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+if test -n "$GZIP"; then
+  echo "$as_me:$LINENO: result: $GZIP" >&5
+echo "${ECHO_T}$GZIP" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_cv_header_stdint>
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
 
-int
-main ()
-{
-if ((int_least32_t *) 0)
-  return 0;
-if (sizeof (int_least32_t))
-  return 0;
-  ;
-  return 0;
-}
+  test -n "$GZIP" && break
+done
+
+if test "$GZIP"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GZIP 1
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_type_int_least32_t=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_type_int_least32_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    COMPRESS_PATH="$GZIP"
+    COMPRESS_SUFFIX=".gz"
+    COMPRESS_FAST_OPT="--fast"
+    COMPRESS_BEST_OPT="--best"
+    UNCOMPRESS_PATH="$GZIP"
+    UNCOMPRESS_OPT="-dc"
+else
+    if test "$COMPRESS"; then
+       COMPRESS_PATH="$COMPRESS"
+       COMPRESS_SUFFIX=".Z"
+       COMPRESS_FAST_OPT="-f"
+       COMPRESS_BEST_OPT="-f"
+       UNCOMPRESS_PATH="$COMPRESS"
+       UNCOMPRESS_OPT="-dc"
+    else
+                               { echo "$as_me:$LINENO: WARNING: *** Cannot find either gzip or compress.  Using cat. ***" >&5
+echo "$as_me: WARNING: *** Cannot find either gzip or compress.  Using cat. ***" >&2;}
+       COMPRESS_PATH="$CAT"
+       COMPRESS_SUFFIX=""
+       COMPRESS_FAST_OPT=""
+       COMPRESS_BEST_OPT=""
+       UNCOMPRESS_PATH="$CAT"
+       UNCOMPRESS_OPT=""
+    fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_type_int_least32_t" >&5
-echo "${ECHO_T}$ac_cv_type_int_least32_t" >&6
 
-echo "$as_me:$LINENO: checking for int_fast32_t" >&5
-echo $ECHO_N "checking for int_fast32_t... $ECHO_C" >&6
-if test "${ac_cv_type_int_fast32_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+cat >>confdefs.h <<_ACEOF
+#define COMPRESS_PATH "$COMPRESS_PATH"
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include<$ac_cv_header_stdint>
 
-int
-main ()
-{
-if ((int_fast32_t *) 0)
-  return 0;
-if (sizeof (int_fast32_t))
-  return 0;
-  ;
-  return 0;
-}
+
+cat >>confdefs.h <<_ACEOF
+#define COMPRESS_SUFFIX "$COMPRESS_SUFFIX"
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_type_int_fast32_t=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_type_int_fast32_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_int_fast32_t" >&5
-echo "${ECHO_T}$ac_cv_type_int_fast32_t" >&6
 
-echo "$as_me:$LINENO: checking for intmax_t" >&5
-echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6
-if test "${ac_cv_type_intmax_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+cat >>confdefs.h <<_ACEOF
+#define COMPRESS_FAST_OPT "$COMPRESS_FAST_OPT"
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_cv_header_stdint>
 
-int
-main ()
-{
-if ((intmax_t *) 0)
-  return 0;
-if (sizeof (intmax_t))
-  return 0;
-  ;
-  return 0;
-}
+
+cat >>confdefs.h <<_ACEOF
+#define COMPRESS_BEST_OPT "$COMPRESS_BEST_OPT"
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_type_intmax_t=yes
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNCOMPRESS_PATH "$UNCOMPRESS_PATH"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNCOMPRESS_OPT "$UNCOMPRESS_OPT"
+_ACEOF
+
+
+for ac_prog in Mail mailx mail
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MAILER+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  case $MAILER in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MAILER="$MAILER" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_MAILER="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
-ac_cv_type_intmax_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  ;;
+esac
 fi
-echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5
-echo "${ECHO_T}$ac_cv_type_intmax_t" >&6
-
+MAILER=$ac_cv_path_MAILER
 
-fi # shortcircut to system "stdint.h"
-# ------------------ PREPARE VARIABLES ------------------------------
-if test "$GCC" = "yes" ; then
-ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1`
+if test -n "$MAILER"; then
+  echo "$as_me:$LINENO: result: $MAILER" >&5
+echo "${ECHO_T}$MAILER" >&6
 else
-ac_cv_stdint_message="using $CC"
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-echo "$as_me:$LINENO: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5
-echo "${ECHO_T}make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&6
+  test -n "$MAILER" && break
+done
 
-# ----------------- DONE inttypes.h checks START header -------------
-          ac_config_commands="$ac_config_commands $ac_stdint_h"
+if test -z "$MAILER"; then
+    if $NO_SERVER_MODE; then
+       MAILER="NONE"
+       { echo "$as_me:$LINENO: WARNING: *** WARNING: Amanda cannot send mail reports without these programs." >&5
+echo "$as_me: WARNING: *** WARNING: Amanda cannot send mail reports without these programs." >&2;}
+    else
+       { { echo "$as_me:$LINENO: error: Set MAILER to some program that accepts -s subject user < message_file." >&5
+echo "$as_me: error: Set MAILER to some program that accepts -s subject user < message_file." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+fi
 
+cat >>confdefs.h <<_ACEOF
+#define MAILER "$MAILER"
+_ACEOF
 
 
-for ac_prog in ar
+for ac_prog in mt
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_AR+set}" = set; then
+if test "${ac_cv_path_MT+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $AR in
+  case $MT in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_AR="$AR" # Let the user override the test with a path.
+  ac_cv_path_MT="$MT" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -8483,7 +10075,7 @@ do
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_MT="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -8493,171 +10085,227 @@ done
   ;;
 esac
 fi
-AR=$ac_cv_path_AR
+MT=$ac_cv_path_MT
 
-if test -n "$AR"; then
-  echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6
+if test -n "$MT"; then
+  echo "$as_me:$LINENO: result: $MT" >&5
+echo "${ECHO_T}$MT" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$AR" && break
+  test -n "$MT" && break
 done
+test -n "$MT" || MT="mt"
 
 
-for ac_prog in gawk mawk nawk awk
+for ac_prog in chio
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_AWK+set}" = set; then
+if test "${ac_cv_path_CHIO+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test -n "$AWK"; then
-  ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+  case $CHIO in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_CHIO="$CHIO" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_AWK="$ac_prog"
+    ac_cv_path_CHIO="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
 
+  ;;
+esac
 fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
-  echo "$as_me:$LINENO: result: $AWK" >&5
-echo "${ECHO_T}$AWK" >&6
+CHIO=$ac_cv_path_CHIO
+
+if test -n "$CHIO"; then
+  echo "$as_me:$LINENO: result: $CHIO" >&5
+echo "${ECHO_T}$CHIO" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$AWK" && break
+  test -n "$CHIO" && break
 done
+test -n "$CHIO" || CHIO="chio"
 
 
-
-       echo "$as_me:$LINENO: checking for $AWK command line variable assignment" >&5
-echo $ECHO_N "checking for $AWK command line variable assignment... $ECHO_C" >&6
-if test "${amanda_cv_awk_var_assignment+set}" = set; then
+for ac_prog in chs
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_CHS+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
+  case $CHS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_CHS="$CHS" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_CHS="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
 
-               echo 'BEGIN{print i; exit}' > conftest.awk
-               result=`$AWK -f conftest.awk i=xx | wc -c`
-               if test "$result" -le 1; then
-                   result=`$AWK -f conftest.awk -v i=xx | wc -c`
-                   if test "$result" -le 1; then
-                       amanda_cv_awk_var_assignment=no
-                   else
-                       amanda_cv_awk_var_assignment="yes with -v"
-                   fi
-               else
-                   amanda_cv_awk_var_assignment="yes"
-               fi
-               rm -fr conftest.awk
-
+  ;;
+esac
+fi
+CHS=$ac_cv_path_CHS
 
+if test -n "$CHS"; then
+  echo "$as_me:$LINENO: result: $CHS" >&5
+echo "${ECHO_T}$CHS" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
-echo "$as_me:$LINENO: result: $amanda_cv_awk_var_assignment" >&5
-echo "${ECHO_T}$amanda_cv_awk_var_assignment" >&6
-       AWK_VAR_ASSIGNMENT_OPT=
-       case "$amanda_cv_awk_var_assignment" in
-           no)
-               HAVE_AWK_WITH_VAR=no
-               ;;
-           yes)
-               HAVE_AWK_WITH_VAR=yes
-               ;;
-           "yes with -v")
-               HAVE_AWK_WITH_VAR=yes
-               AWK_VAR_ASSIGNMENT_OPT=-v
-               ;;
-       esac
 
+  test -n "$CHS" && break
+done
+test -n "$CHS" || CHS="chs"
 
 
-if test "x$amanda_cv_awk_var_assignment" = xno; then
-    NO_AMPLOT_MODE=true
-    { echo "$as_me:$LINENO: WARNING: *** Your $awk cannot do command line variable assignment.  Amplot will not be installed." >&5
-echo "$as_me: WARNING: *** Your $awk cannot do command line variable assignment.  Amplot will not be installed." >&2;}
+for ac_prog in mtx
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MTX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MTX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MTX="$MTX" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_MTX="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
 fi
+MTX=$ac_cv_path_MTX
 
-for ac_prog in 'bison -y' byacc
+if test -n "$MTX"; then
+  echo "$as_me:$LINENO: result: $MTX" >&5
+echo "${ECHO_T}$MTX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$MTX" && break
+done
+test -n "$MTX" || MTX="mtx"
+
+
+for ac_prog in mcutil
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_YACC+set}" = set; then
+if test "${ac_cv_path_MCUTIL+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test -n "$YACC"; then
-  ac_cv_prog_YACC="$YACC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+  case $MCUTIL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MCUTIL="$MCUTIL" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_YACC="$ac_prog"
+    ac_cv_path_MCUTIL="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
 
+  ;;
+esac
 fi
-fi
-YACC=$ac_cv_prog_YACC
-if test -n "$YACC"; then
-  echo "$as_me:$LINENO: result: $YACC" >&5
-echo "${ECHO_T}$YACC" >&6
+MCUTIL=$ac_cv_path_MCUTIL
+
+if test -n "$MCUTIL"; then
+  echo "$as_me:$LINENO: result: $MCUTIL" >&5
+echo "${ECHO_T}$MCUTIL" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$YACC" && break
+  test -n "$MCUTIL" && break
 done
-test -n "$YACC" || YACC="yacc"
+test -n "$MCUTIL" || MCUTIL="mcutil"
 
-for ac_prog in cat
+
+for ac_prog in lpr lp
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_CAT+set}" = set; then
+if test "${ac_cv_path_PRINT+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $CAT in
+  case $PRINT in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_CAT="$CAT" # Let the user override the test with a path.
+  ac_cv_path_PRINT="$PRINT" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_PRINT="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -8667,34 +10315,64 @@ done
   ;;
 esac
 fi
-CAT=$ac_cv_path_CAT
+PRINT=$ac_cv_path_PRINT
 
-if test -n "$CAT"; then
-  echo "$as_me:$LINENO: result: $CAT" >&5
-echo "${ECHO_T}$CAT" >&6
+if test -n "$PRINT"; then
+  echo "$as_me:$LINENO: result: $PRINT" >&5
+echo "${ECHO_T}$PRINT" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$CAT" && break
+  test -n "$PRINT" && break
 done
 
-if test -z "$CAT"; then
-    CAT=cat
+if test ! -z "$PRINT"; then
+
+cat >>confdefs.h <<_ACEOF
+#define LPRCMD "$PRINT"
+_ACEOF
+
+    echo "$as_me:$LINENO: checking which flag to use to select a printer" >&5
+echo $ECHO_N "checking which flag to use to select a printer... $ECHO_C" >&6
+if test "${amanda_cv_printer_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       amanda_cv_printer_flag=$PRINTER_FLAG
+       case "$PRINT" in
+       lpr|*/lpr) amanda_cv_printer_flag="-P";;
+       lp|*/lp) amanda_cv_printer_flag="-d";;
+       esac
+
 fi
-for ac_prog in compress
+echo "$as_me:$LINENO: result: $amanda_cv_printer_flag" >&5
+echo "${ECHO_T}$amanda_cv_printer_flag" >&6
+    if test ! -z "$amanda_cv_printer_flag"; then
+
+cat >>confdefs.h <<_ACEOF
+#define LPRFLAG "$amanda_cv_printer_flag"
+_ACEOF
+
+    else
+       { echo "$as_me:$LINENO: WARNING: *** WARNING: amanda will always print to the default printer" >&5
+echo "$as_me: WARNING: *** WARNING: amanda will always print to the default printer" >&2;}
+    fi
+fi
+
+for ac_prog in pcat
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_COMPRESS+set}" = set; then
+if test "${ac_cv_path_PCAT+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $COMPRESS in
+  case $PCAT in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_COMPRESS="$COMPRESS" # Let the user override the test with a path.
+  ac_cv_path_PCAT="$PCAT" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -8704,7 +10382,7 @@ do
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_COMPRESS="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_PCAT="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -8714,31 +10392,31 @@ done
   ;;
 esac
 fi
-COMPRESS=$ac_cv_path_COMPRESS
+PCAT=$ac_cv_path_PCAT
 
-if test -n "$COMPRESS"; then
-  echo "$as_me:$LINENO: result: $COMPRESS" >&5
-echo "${ECHO_T}$COMPRESS" >&6
+if test -n "$PCAT"; then
+  echo "$as_me:$LINENO: result: $PCAT" >&5
+echo "${ECHO_T}$PCAT" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$COMPRESS" && break
+  test -n "$PCAT" && break
 done
 
-for ac_prog in dd
+for ac_prog in perl5 perl
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_DD+set}" = set; then
+if test "${ac_cv_path_PERL+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $DD in
+  case $PERL in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_DD="$DD" # Let the user override the test with a path.
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -8748,7 +10426,7 @@ do
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_DD="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -8758,41 +10436,43 @@ done
   ;;
 esac
 fi
-DD=$ac_cv_path_DD
+PERL=$ac_cv_path_PERL
 
-if test -n "$DD"; then
-  echo "$as_me:$LINENO: result: $DD" >&5
-echo "${ECHO_T}$DD" >&6
+if test -n "$PERL"; then
+  echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$DD" && break
+  test -n "$PERL" && break
 done
 
-for ac_prog in egrep
+
+
+for ac_prog in $DUMP_PROGRAMS
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_EGREP+set}" = set; then
+if test "${ac_cv_path_DUMP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $EGREP in
+  case $DUMP in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_EGREP="$EGREP" # Let the user override the test with a path.
+  ac_cv_path_DUMP="$DUMP" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $SYSLOCPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_EGREP="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_DUMP="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -8802,86 +10482,242 @@ done
   ;;
 esac
 fi
-EGREP=$ac_cv_path_EGREP
+DUMP=$ac_cv_path_DUMP
 
-if test -n "$EGREP"; then
-  echo "$as_me:$LINENO: result: $EGREP" >&5
-echo "${ECHO_T}$EGREP" >&6
+if test -n "$DUMP"; then
+  echo "$as_me:$LINENO: result: $DUMP" >&5
+echo "${ECHO_T}$DUMP" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$EGREP" && break
+  test -n "$DUMP" && break
 done
 
-for ac_prog in getconf
+for ac_prog in ufsrestore restore
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GETCONF+set}" = set; then
+if test "${ac_cv_path_RESTORE+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $GETCONF in
+  case $RESTORE in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a path.
+  ac_cv_path_RESTORE="$RESTORE" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSPATH
+for as_dir in $SYSLOCPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_GETCONF="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_RESTORE="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
 
-  ;;
-esac
+  ;;
+esac
+fi
+RESTORE=$ac_cv_path_RESTORE
+
+if test -n "$RESTORE"; then
+  echo "$as_me:$LINENO: result: $RESTORE" >&5
+echo "${ECHO_T}$RESTORE" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$RESTORE" && break
+done
+
+if test "$DUMP" -a "$RESTORE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define DUMP "$DUMP"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define RESTORE "$RESTORE"
+_ACEOF
+
+    if test -x $DUMP; then
+        echo "$as_me:$LINENO: checking whether $DUMP supports -E or -S for estimates" >&5
+echo $ECHO_N "checking whether $DUMP supports -E or -S for estimates... $ECHO_C" >&6
+if test "${amanda_cv_dump_estimate+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               case "$DUMP" in
+               *dump)
+                   { ac_try='$DUMP 9Ef /dev/null /dev/null/invalid/fs 2>&1
+                       | $GREP -v Dumping
+                       | $GREP -v Date
+                       | $GREP -v Label >conftest.d-E 2>&1'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+                   cat conftest.d-E >&5
+                   { ac_try='$DUMP 9Sf /dev/null /dev/null/invalid/fs 2>&1
+                       | $GREP -v Dumping
+                       | $GREP -v Date
+                       | $GREP -v Label >conftest.d-S 2>&1'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+                   cat conftest.d-S >&5
+                   { ac_try='$DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
+                       | $GREP -v Dumping
+                       | $GREP -v Date
+                       | $GREP -v Label >conftest.d 2>&1'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+                   cat conftest.d >&5
+                   if { ac_try='cmp conftest.d-E conftest.d 1>&2'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+                       amanda_cv_dump_estimate=E
+                   elif { ac_try='cmp conftest.d-S conftest.d 1>&2'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+                       amanda_cv_dump_estimate=S
+                   else
+                       amanda_cv_dump_estimate=no
+                   fi
+                   rm -f conftest.d conftest.d-E conftest.d-S
+                 ;;
+               *) amanda_cv_dump_estimate=no
+                 ;;
+               esac
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_dump_estimate" >&5
+echo "${ECHO_T}$amanda_cv_dump_estimate" >&6
+    else
+       { echo "$as_me:$LINENO: WARNING: *** $DUMP is not executable, cannot run -E/-S test" >&5
+echo "$as_me: WARNING: *** $DUMP is not executable, cannot run -E/-S test" >&2;}
+       amanda_cv_dump_estimate=no
+    fi
+    if test "x$amanda_cv_dump_estimate" != xno; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DUMP_ESTIMATE "$amanda_cv_dump_estimate"
+_ACEOF
+
+    fi
+
+
+# Check whether --with-dump-honor-nodump or --without-dump-honor-nodump was given.
+if test "${with_dump_honor_nodump+set}" = set; then
+  withval="$with_dump_honor_nodump"
+   if test -x $DUMP; then
+        echo "$as_me:$LINENO: checking whether $DUMP supports -h (honor nodump flag)" >&5
+echo $ECHO_N "checking whether $DUMP supports -h (honor nodump flag)... $ECHO_C" >&6
+if test "${amanda_cv_honor_nodump+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           case "$DUMP" in
+           *dump)
+               { ac_try='$DUMP 9hf 0 /dev/null /dev/null/invalid/fs 2>&1
+                   | $GREP -v Dumping
+                   | $GREP -v Date
+                   | $GREP -v Label >conftest.d-h 2>&1'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+               cat conftest.d-h >&5
+               { ac_try='$DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
+                   | $GREP -v Dumping
+                   | $GREP -v Date
+                   | $GREP -v Label >conftest.d 2>&1'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+               cat conftest.d >&5
+               if { ac_try='diff conftest.d-h conftest.d 1>&2'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+                   amanda_cv_honor_nodump=yes
+               else
+                   amanda_cv_honor_nodump=no
+               fi
+               rm -f conftest.d conftest.d-h
+             ;;
+           *) amanda_cv_honor_nodump=no
+             ;;
+           esac
+
 fi
-GETCONF=$ac_cv_path_GETCONF
+echo "$as_me:$LINENO: result: $amanda_cv_honor_nodump" >&5
+echo "${ECHO_T}$amanda_cv_honor_nodump" >&6
+      else
+       { echo "$as_me:$LINENO: WARNING: *** $DUMP is not executable, cannot run -h test" >&5
+echo "$as_me: WARNING: *** $DUMP is not executable, cannot run -h test" >&2;}
+       amanda_cv_honor_nodump=no
+      fi
+      if test "x$amanda_cv_honor_nodump" = xyes; then
 
-if test -n "$GETCONF"; then
-  echo "$as_me:$LINENO: result: $GETCONF" >&5
-echo "${ECHO_T}$GETCONF" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_HONOR_NODUMP 1
+_ACEOF
 
-  test -n "$GETCONF" && break
-done
+      fi
 
+fi;
+fi
 
-for ac_prog in gnuplot
+for ac_prog in xfsdump
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GNUPLOT+set}" = set; then
+if test "${ac_cv_path_XFSDUMP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $GNUPLOT in
+  case $XFSDUMP in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_GNUPLOT="$GNUPLOT" # Let the user override the test with a path.
+  ac_cv_path_XFSDUMP="$XFSDUMP" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $SYSLOCPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_GNUPLOT="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_XFSDUMP="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -8891,47 +10727,41 @@ done
   ;;
 esac
 fi
-GNUPLOT=$ac_cv_path_GNUPLOT
+XFSDUMP=$ac_cv_path_XFSDUMP
 
-if test -n "$GNUPLOT"; then
-  echo "$as_me:$LINENO: result: $GNUPLOT" >&5
-echo "${ECHO_T}$GNUPLOT" >&6
+if test -n "$XFSDUMP"; then
+  echo "$as_me:$LINENO: result: $XFSDUMP" >&5
+echo "${ECHO_T}$XFSDUMP" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$GNUPLOT" && break
+  test -n "$XFSDUMP" && break
 done
 
-if test -z "$GNUPLOT"; then
-    NO_AMPLOT_MODE=true
-    { echo "$as_me:$LINENO: WARNING: *** You do not have gnuplot.  Amplot will not be installed." >&5
-echo "$as_me: WARNING: *** You do not have gnuplot.  Amplot will not be installed." >&2;}
-fi
-
-for ac_prog in grep
+for ac_prog in xfsrestore
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GREP+set}" = set; then
+if test "${ac_cv_path_XFSRESTORE+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $GREP in
+  case $XFSRESTORE in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_GREP="$GREP" # Let the user override the test with a path.
+  ac_cv_path_XFSRESTORE="$XFSRESTORE" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $SYSLOCPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_XFSRESTORE="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -8941,50 +10771,59 @@ done
   ;;
 esac
 fi
-GREP=$ac_cv_path_GREP
+XFSRESTORE=$ac_cv_path_XFSRESTORE
 
-if test -n "$GREP"; then
-  echo "$as_me:$LINENO: result: $GREP" >&5
-echo "${ECHO_T}$GREP" >&6
+if test -n "$XFSRESTORE"; then
+  echo "$as_me:$LINENO: result: $XFSRESTORE" >&5
+echo "${ECHO_T}$XFSRESTORE" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$GREP" && break
+  test -n "$XFSRESTORE" && break
 done
 
-if test -z "$GREP"; then
-    GREP=grep
-fi
+if test "$XFSDUMP" -a "$XFSRESTORE"; then
 
 cat >>confdefs.h <<_ACEOF
-#define GREP "$GREP"
+#define XFSDUMP "$XFSDUMP"
 _ACEOF
 
 
-for ac_prog in gtar gnutar tar
+cat >>confdefs.h <<_ACEOF
+#define XFSRESTORE "$XFSRESTORE"
+_ACEOF
+
+    { echo "$as_me:$LINENO: WARNING: *** xfsdump causes the setuid-root rundump program to be enabled" >&5
+echo "$as_me: WARNING: *** xfsdump causes the setuid-root rundump program to be enabled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: *** to disable it, just #undef XFSDUMP in config/config.h" >&5
+echo "$as_me: WARNING: *** to disable it, just #undef XFSDUMP in config/config.h" >&2;}
+fi
+
+VXSYSLOCPATH="$SYSLOCPATH:/usr/lib/fs/vxfs"
+for ac_prog in vxdump
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GNUTAR+set}" = set; then
+if test "${ac_cv_path_VXDUMP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $GNUTAR in
+  case $VXDUMP in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_GNUTAR="$GNUTAR" # Let the user override the test with a path.
+  ac_cv_path_VXDUMP="$VXDUMP" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $VXSYSLOCPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_GNUTAR="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_VXDUMP="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -8994,58 +10833,41 @@ done
   ;;
 esac
 fi
-GNUTAR=$ac_cv_path_GNUTAR
+VXDUMP=$ac_cv_path_VXDUMP
 
-if test -n "$GNUTAR"; then
-  echo "$as_me:$LINENO: result: $GNUTAR" >&5
-echo "${ECHO_T}$GNUTAR" >&6
+if test -n "$VXDUMP"; then
+  echo "$as_me:$LINENO: result: $VXDUMP" >&5
+echo "${ECHO_T}$VXDUMP" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$GNUTAR" && break
+  test -n "$VXDUMP" && break
 done
 
-if test ! -z "$GNUTAR"; then
-  case "`\"$GNUTAR\" --version 2>&1`" in
-   *GNU*tar* | *Free*paxutils* )
-
-cat >>confdefs.h <<_ACEOF
-#define GNUTAR "$GNUTAR"
-_ACEOF
-
-               ;;
-   *)
-               { echo "$as_me:$LINENO: WARNING: *** $GNUTAR is not GNU tar, so it will not be used." >&5
-echo "$as_me: WARNING: *** $GNUTAR is not GNU tar, so it will not be used." >&2;}
-               GNUTAR=
-               ;;
-  esac
-fi
-
-for ac_prog in smbclient
+for ac_prog in vxrestore
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_SAMBA_CLIENT+set}" = set; then
+if test "${ac_cv_path_VXRESTORE+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $SAMBA_CLIENT in
+  case $VXRESTORE in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_SAMBA_CLIENT="$SAMBA_CLIENT" # Let the user override the test with a path.
+  ac_cv_path_VXRESTORE="$VXRESTORE" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $VXSYSLOCPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_SAMBA_CLIENT="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_VXRESTORE="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -9055,69 +10877,54 @@ done
   ;;
 esac
 fi
-SAMBA_CLIENT=$ac_cv_path_SAMBA_CLIENT
+VXRESTORE=$ac_cv_path_VXRESTORE
 
-if test -n "$SAMBA_CLIENT"; then
-  echo "$as_me:$LINENO: result: $SAMBA_CLIENT" >&5
-echo "${ECHO_T}$SAMBA_CLIENT" >&6
+if test -n "$VXRESTORE"; then
+  echo "$as_me:$LINENO: result: $VXRESTORE" >&5
+echo "${ECHO_T}$VXRESTORE" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$SAMBA_CLIENT" && break
+  test -n "$VXRESTORE" && break
 done
 
-if test ! -z "$SAMBA_CLIENT"; then
-  case "`\"$SAMBA_CLIENT\" '\\\\not.a.host.name\\notashare' -U nosuchuser -N -Tx /dev/null 2>&1`" in
-  *"Unknown host"*)
-               smbversion=1
-               ;;
-  *"Connection to not.a.host.name failed"*)
-               smbversion=2
-               ;;
-  *)
-               { echo "$as_me:$LINENO: WARNING: *** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used." >&5
-echo "$as_me: WARNING: *** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used." >&2;}
-               SAMBA_CLIENT=
-               ;;
-  esac
-  if test -n "$SAMBA_CLIENT"; then
+if test "$VXDUMP" -a "$VXRESTORE"; then
 
 cat >>confdefs.h <<_ACEOF
-#define SAMBA_CLIENT "$SAMBA_CLIENT"
+#define VXDUMP "$VXDUMP"
 _ACEOF
 
 
 cat >>confdefs.h <<_ACEOF
-#define SAMBA_VERSION $smbversion
+#define VXRESTORE "$VXRESTORE"
 _ACEOF
 
-  fi
 fi
 
-for ac_prog in gzip
+for ac_prog in vdump
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GZIP+set}" = set; then
+if test "${ac_cv_path_VDUMP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $GZIP in
+  case $VDUMP in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path.
+  ac_cv_path_VDUMP="$VDUMP" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $SYSLOCPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_VDUMP="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -9127,103 +10934,41 @@ done
   ;;
 esac
 fi
-GZIP=$ac_cv_path_GZIP
+VDUMP=$ac_cv_path_VDUMP
 
-if test -n "$GZIP"; then
-  echo "$as_me:$LINENO: result: $GZIP" >&5
-echo "${ECHO_T}$GZIP" >&6
+if test -n "$VDUMP"; then
+  echo "$as_me:$LINENO: result: $VDUMP" >&5
+echo "${ECHO_T}$VDUMP" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$GZIP" && break
+  test -n "$VDUMP" && break
 done
 
-if test "$GZIP"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GZIP 1
-_ACEOF
-
-    COMPRESS_PATH="$GZIP"
-    COMPRESS_SUFFIX=".gz"
-    COMPRESS_FAST_OPT="--fast"
-    COMPRESS_BEST_OPT="--best"
-    UNCOMPRESS_PATH="$GZIP"
-    UNCOMPRESS_OPT="-dc"
-else
-    if test "$COMPRESS"; then
-       COMPRESS_PATH="$COMPRESS"
-       COMPRESS_SUFFIX=".Z"
-       COMPRESS_FAST_OPT="-f"
-       COMPRESS_BEST_OPT="-f"
-       UNCOMPRESS_PATH="$COMPRESS"
-       UNCOMPRESS_OPT="-dc"
-    else
-                               { echo "$as_me:$LINENO: WARNING: *** Cannot find either gzip or compress.  Using cat. ***" >&5
-echo "$as_me: WARNING: *** Cannot find either gzip or compress.  Using cat. ***" >&2;}
-       COMPRESS_PATH="$CAT"
-       COMPRESS_SUFFIX=""
-       COMPRESS_FAST_OPT=""
-       COMPRESS_BEST_OPT=""
-       UNCOMPRESS_PATH="$CAT"
-       UNCOMPRESS_OPT=""
-    fi
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define COMPRESS_PATH "$COMPRESS_PATH"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define COMPRESS_SUFFIX "$COMPRESS_SUFFIX"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define COMPRESS_FAST_OPT "$COMPRESS_FAST_OPT"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define COMPRESS_BEST_OPT "$COMPRESS_BEST_OPT"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define UNCOMPRESS_PATH "$UNCOMPRESS_PATH"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define UNCOMPRESS_OPT "$UNCOMPRESS_OPT"
-_ACEOF
-
-
-for ac_prog in Mail mailx mail
+for ac_prog in vrestore
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_MAILER+set}" = set; then
+if test "${ac_cv_path_VRESTORE+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $MAILER in
+  case $VRESTORE in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_MAILER="$MAILER" # Let the user override the test with a path.
+  ac_cv_path_VRESTORE="$VRESTORE" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+for as_dir in $SYSLOCPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_MAILER="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_VRESTORE="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
   ;;
 esac
 fi
-MAILER=$ac_cv_path_MAILER
+VRESTORE=$ac_cv_path_VRESTORE
 
-if test -n "$MAILER"; then
-  echo "$as_me:$LINENO: result: $MAILER" >&5
-echo "${ECHO_T}$MAILER" >&6
+if test -n "$VRESTORE"; then
+  echo "$as_me:$LINENO: result: $VRESTORE" >&5
+echo "${ECHO_T}$VRESTORE" >&6
 else
   echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$MAILER" && break
+  test -n "$VRESTORE" && break
 done
 
-if test -z "$MAILER"; then
-    if $NO_SERVER_MODE; then
-       MAILER="NONE"
-       { echo "$as_me:$LINENO: WARNING: *** WARNING: Amanda cannot send mail reports without these programs." >&5
-echo "$as_me: WARNING: *** WARNING: Amanda cannot send mail reports without these programs." >&2;}
-    else
-       { { echo "$as_me:$LINENO: error: Set MAILER to some program that accepts -s subject user < message_file." >&5
-echo "$as_me: error: Set MAILER to some program that accepts -s subject user < message_file." >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-fi
+if test "$VDUMP" -a "$VRESTORE"; then
 
 cat >>confdefs.h <<_ACEOF
-#define MAILER "$MAILER"
+#define VDUMP "$VDUMP"
 _ACEOF
 
 
-for ac_prog in mt
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_MT+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $MT in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_MT="$MT" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_MT="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+cat >>confdefs.h <<_ACEOF
+#define VRESTORE "$VRESTORE"
+_ACEOF
 
-  ;;
-esac
 fi
-MT=$ac_cv_path_MT
 
-if test -n "$MT"; then
-  echo "$as_me:$LINENO: result: $MT" >&5
-echo "${ECHO_T}$MT" >&6
+if test "$PCAT"; then
+    AMPLOT_CAT_PACK="if(o==\"z\")print \"$PCAT\"; else"
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+    AMPLOT_CAT_PACK=
+fi
+if test "$COMPRESS"; then
+    AMPLOT_COMPRESS=$COMPRESS
+    AMPLOT_CAT_COMPRESS="if(o==\"Z\")print \"$COMPRESS -dc\"; else"
+else
+    AMPLOT_CAT_COMPRESS=
+fi
+if test "$GZIP"; then
+    AMPLOT_COMPRESS=$GZIP
+    AMPLOT_CAT_GZIP="if(o==\"gz\")print \"$GZIP -dc\"; else"
+else
+    AMPLOT_CAT_GZIP=
 fi
 
-  test -n "$MT" && break
-done
-test -n "$MT" || MT="mt"
 
 
-for ac_prog in chio
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_CHIO+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+
+
+# Determine the printf format characters to use when printing
+# values of type long long. This will normally be "ll", but where
+# the compiler treats "long long" as a alias for "long" and printf
+# doesn't know about "long long" use "l".  Hopefully the sprintf
+# will produce a inconsistant result in the later case.  If the compiler
+# fails due to seeing "%lld" we fall back to "l".
+#
+# Win32 uses "%I64d", but that's defined elsewhere since we don't use
+# configure on Win32.
+#
+echo "$as_me:$LINENO: checking printf format modifier for 64-bit integers" >&5
+echo $ECHO_N "checking printf format modifier for 64-bit integers... $ECHO_C" >&6
+if test "$cross_compiling" = yes; then
+  echo "$as_me:$LINENO: result: assuming target platform uses ll" >&5
+echo "${ECHO_T}assuming target platform uses ll" >&6
+       LL_FMT="%lld"
 else
-  case $CHIO in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_CHIO="$CHIO" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_CHIO="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
-  ;;
-esac
-fi
-CHIO=$ac_cv_path_CHIO
+#include <stdio.h>
+main() {
+       long long int j = 0;
+       char buf[100];
+       buf[0] = 0;
+       sprintf(buf, "%lld", j);
+       exit((sizeof(long long int) != sizeof(long int))? 0 :
+            (strcmp(buf, "0") != 0));
+}
 
-if test -n "$CHIO"; then
-  echo "$as_me:$LINENO: result: $CHIO" >&5
-echo "${ECHO_T}$CHIO" >&6
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: ll" >&5
+echo "${ECHO_T}ll" >&6
+       LL_FMT="%lld"
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+echo "$as_me:$LINENO: result: l" >&5
+echo "${ECHO_T}l" >&6
+       LL_FMT="%ld"
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
 
-  test -n "$CHIO" && break
-done
-test -n "$CHIO" || CHIO="chio"
+cat >>confdefs.h <<_ACEOF
+#define LL_FMT "$LL_FMT"
+_ACEOF
 
 
-for ac_prog in chs
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_CHS+set}" = set; then
+
+GZIP=
+
+need_resetofs=yes
+echo "$as_me:$LINENO: checking for large file compilation CFLAGS" >&5
+echo $ECHO_N "checking for large file compilation CFLAGS... $ECHO_C" >&6
+if test "${amanda_cv_LFS_CFLAGS+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $CHS in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_CHS="$CHS" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_CHS="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
 
-  ;;
-esac
-fi
-CHS=$ac_cv_path_CHS
+       amanda_cv_LFS_CFLAGS=
+       if test "$GETCONF"; then
+           if $GETCONF ${GETCONF_LFS}_CFLAGS >/dev/null 2>&1; then
+               amanda_cv_LFS_CFLAGS=`$GETCONF ${GETCONF_LFS}_CFLAGS 2>/dev/null`
+               need_resetofs=no
+           fi
+       fi
+
 
-if test -n "$CHS"; then
-  echo "$as_me:$LINENO: result: $CHS" >&5
-echo "${ECHO_T}$CHS" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
 fi
+echo "$as_me:$LINENO: result: $amanda_cv_LFS_CFLAGS" >&5
+echo "${ECHO_T}$amanda_cv_LFS_CFLAGS" >&6
+echo "$as_me:$LINENO: checking for large file compilation LDFLAGS" >&5
+echo $ECHO_N "checking for large file compilation LDFLAGS... $ECHO_C" >&6
+if test "${amanda_cv_LFS_LDFLAGS+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
 
-  test -n "$CHS" && break
-done
-test -n "$CHS" || CHS="chs"
+       amanda_cv_LFS_LDFLAGS=
+       if test "$GETCONF"; then
+           if $GETCONF ${GETCONF_LFS}_LDFLAGS >/dev/null 2>&1; then
+               amanda_cv_LFS_LDFLAGS=`$GETCONF ${GETCONF_LFS}_LDFLAGS 2>/dev/null`
+               need_resetofs=no
+           fi
+       fi
 
 
-for ac_prog in mtx
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_MTX+set}" = set; then
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_LFS_LDFLAGS" >&5
+echo "${ECHO_T}$amanda_cv_LFS_LDFLAGS" >&6
+echo "$as_me:$LINENO: checking for large file compilation LIBS" >&5
+echo $ECHO_N "checking for large file compilation LIBS... $ECHO_C" >&6
+if test "${amanda_cv_LFS_LIBS+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $MTX in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_MTX="$MTX" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_MTX="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
 
-  ;;
-esac
+       amanda_cv_LFS_LIBS=
+       if test "$GETCONF"; then
+           if $GETCONF ${GETCONF_LFS}_LIBS >/dev/null 2>&1; then
+               amanda_cv_LFS_LIBS=`$GETCONF ${GETCONF_LFS}_LIBS 2>/dev/null`
+               need_resetofs=no
+           fi
+       fi
+
+
 fi
-MTX=$ac_cv_path_MTX
+echo "$as_me:$LINENO: result: $amanda_cv_LFS_LIBS" >&5
+echo "${ECHO_T}$amanda_cv_LFS_LIBS" >&6
+if test "x$need_resetofs" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_RESETOFS 1
+_ACEOF
 
-if test -n "$MTX"; then
-  echo "$as_me:$LINENO: result: $MTX" >&5
-echo "${ECHO_T}$MTX" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
 fi
 
-  test -n "$MTX" && break
-done
-test -n "$MTX" || MTX="mtx"
 
+CFLAGS="$amanda_cv_LFS_CFLAGS $CFLAGS"
+CPPFLAGS="$amanda_cv_LFS_CPPFLAGS $CPPFLAGS"
+LDFLAGS="$amanda_cv_LFS_LDFLAGS $LDFLAGS"
+LIBS="$amanda_cv_LFS_LIBS $LIBS"
 
-for ac_prog in mcutil
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_MCUTIL+set}" = set; then
+echo "$as_me:$LINENO: checking for int" >&5
+echo $ECHO_N "checking for int... $ECHO_C" >&6
+if test "${ac_cv_type_int+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $MCUTIL in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_MCUTIL="$MCUTIL" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_MCUTIL="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((int *) 0)
+  return 0;
+if (sizeof (int))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-  ;;
-esac
+ac_cv_type_int=no
 fi
-MCUTIL=$ac_cv_path_MCUTIL
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
+echo "${ECHO_T}$ac_cv_type_int" >&6
 
-if test -n "$MCUTIL"; then
-  echo "$as_me:$LINENO: result: $MCUTIL" >&5
-echo "${ECHO_T}$MCUTIL" >&6
+echo "$as_me:$LINENO: checking size of int" >&5
+echo $ECHO_N "checking size of int... $ECHO_C" >&6
+if test "${ac_cv_sizeof_int+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  if test "$ac_cv_type_int" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
 fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-  test -n "$MCUTIL" && break
-done
-test -n "$MCUTIL" || MCUTIL="mcutil"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)];
+test_array [0] = 0
 
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)];
+test_array [0] = 0
 
-for ac_prog in lpr lp
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_PRINT+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
 else
-  case $PRINT in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PRINT="$PRINT" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PRINT="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-  ;;
-esac
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
 fi
-PRINT=$ac_cv_path_PRINT
-
-if test -n "$PRINT"; then
-  echo "$as_me:$LINENO: result: $PRINT" >&5
-echo "${ECHO_T}$PRINT" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
 
-  test -n "$PRINT" && break
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 done
+case $ac_lo in
+?*) ac_cv_sizeof_int=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (int)); }
+unsigned long ulongval () { return (long) (sizeof (int)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
 
-if test ! -z "$PRINT"; then
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (int))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (int))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (int))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
 
-cat >>confdefs.h <<_ACEOF
-#define LPRCMD "$PRINT"
+  ;
+  return 0;
+}
 _ACEOF
-
-    echo "$as_me:$LINENO: checking which flag to use to select a printer" >&5
-echo $ECHO_N "checking which flag to use to select a printer... $ECHO_C" >&6
-if test "${amanda_cv_printer_flag+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_int=`cat conftest.val`
 else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-       amanda_cv_printer_flag=$PRINTER_FLAG
-       case "$PRINT" in
-       lpr|*/lpr) amanda_cv_printer_flag="-P";;
-       lp|*/lp) amanda_cv_printer_flag="-d";;
-       esac
-
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
 fi
-echo "$as_me:$LINENO: result: $amanda_cv_printer_flag" >&5
-echo "${ECHO_T}$amanda_cv_printer_flag" >&6
-    if test ! -z "$amanda_cv_printer_flag"; then
-
-cat >>confdefs.h <<_ACEOF
-#define LPRFLAG "$amanda_cv_printer_flag"
-_ACEOF
-
-    else
-       { echo "$as_me:$LINENO: WARNING: *** WARNING: amanda will always print to the default printer" >&5
-echo "$as_me: WARNING: *** WARNING: amanda will always print to the default printer" >&2;}
-    fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
-
-for ac_prog in pcat
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_PCAT+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $PCAT in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PCAT="$PCAT" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PCAT="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-  ;;
-esac
 fi
-PCAT=$ac_cv_path_PCAT
-
-if test -n "$PCAT"; then
-  echo "$as_me:$LINENO: result: $PCAT" >&5
-echo "${ECHO_T}$PCAT" >&6
+rm -f conftest.val
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  ac_cv_sizeof_int=0
+fi
 fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
+echo "${ECHO_T}$ac_cv_sizeof_int" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
 
-  test -n "$PCAT" && break
-done
 
-for ac_prog in perl5 perl
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_PERL+set}" = set; then
+echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $PERL in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PERL="$PERL" # 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 $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+  return 0;
+if (sizeof (long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-  ;;
-esac
+ac_cv_type_long=no
 fi
-PERL=$ac_cv_path_PERL
-
-if test -n "$PERL"; then
-  echo "$as_me:$LINENO: result: $PERL" >&5
-echo "${ECHO_T}$PERL" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
 
-  test -n "$PERL" && break
-done
-
-
-
-for ac_prog in $DUMP_PROGRAMS
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_DUMP+set}" = set; then
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $DUMP in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_DUMP="$DUMP" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_DUMP="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-  ;;
-esac
-fi
-DUMP=$ac_cv_path_DUMP
-
-if test -n "$DUMP"; then
-  echo "$as_me:$LINENO: result: $DUMP" >&5
-echo "${ECHO_T}$DUMP" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+  if test "$ac_cv_type_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
 
-  test -n "$DUMP" && break
-done
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
 
-for ac_prog in ufsrestore restore
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_RESTORE+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
 else
-  case $RESTORE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_RESTORE="$RESTORE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_RESTORE="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-  ;;
-esac
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
 fi
-RESTORE=$ac_cv_path_RESTORE
-
-if test -n "$RESTORE"; then
-  echo "$as_me:$LINENO: result: $RESTORE" >&5
-echo "${ECHO_T}$RESTORE" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  test -n "$RESTORE" && break
-done
-
-if test "$DUMP" -a "$RESTORE"; then
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-cat >>confdefs.h <<_ACEOF
-#define DUMP "$DUMP"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
 
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
 
-cat >>confdefs.h <<_ACEOF
-#define RESTORE "$RESTORE"
+  ;
+  return 0;
+}
 _ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-    if test -x $DUMP; then
-        echo "$as_me:$LINENO: checking whether $DUMP supports -E or -S for estimates" >&5
-echo $ECHO_N "checking whether $DUMP supports -E or -S for estimates... $ECHO_C" >&6
-if test "${amanda_cv_dump_estimate+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
 else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-               case "$DUMP" in
-               *dump)
-                   { ac_try='$DUMP 9Ef /dev/null /dev/null/invalid/fs 2>&1
-                       | $GREP -v Dumping
-                       | $GREP -v Date
-                       | $GREP -v Label >conftest.d-E 2>&1'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }
-                   cat conftest.d-E >&5
-                   { ac_try='$DUMP 9Sf /dev/null /dev/null/invalid/fs 2>&1
-                       | $GREP -v Dumping
-                       | $GREP -v Date
-                       | $GREP -v Label >conftest.d-S 2>&1'
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }
-                   cat conftest.d-S >&5
-                   { ac_try='$DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
-                       | $GREP -v Dumping
-                       | $GREP -v Date
-                       | $GREP -v Label >conftest.d 2>&1'
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }
-                   cat conftest.d >&5
-                   if { ac_try='cmp conftest.d-E conftest.d 1>&2'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-                       amanda_cv_dump_estimate=E
-                   elif { ac_try='cmp conftest.d-S conftest.d 1>&2'
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-                       amanda_cv_dump_estimate=S
-                   else
-                       amanda_cv_dump_estimate=no
-                   fi
-                   rm -f conftest.d conftest.d-E conftest.d-S
-                 ;;
-               *) amanda_cv_dump_estimate=no
-                 ;;
-               esac
+  ac_cv_sizeof_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
 fi
-echo "$as_me:$LINENO: result: $amanda_cv_dump_estimate" >&5
-echo "${ECHO_T}$amanda_cv_dump_estimate" >&6
-    else
-       { echo "$as_me:$LINENO: WARNING: *** $DUMP is not executable, cannot run -E/-S test" >&5
-echo "$as_me: WARNING: *** $DUMP is not executable, cannot run -E/-S test" >&2;}
-       amanda_cv_dump_estimate=no
-    fi
-    if test "x$amanda_cv_dump_estimate" != xno; then
-
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
 cat >>confdefs.h <<_ACEOF
-#define HAVE_DUMP_ESTIMATE "$amanda_cv_dump_estimate"
+#define SIZEOF_LONG $ac_cv_sizeof_long
 _ACEOF
 
-    fi
-
 
-# Check whether --with-dump-honor-nodump or --without-dump-honor-nodump was given.
-if test "${with_dump_honor_nodump+set}" = set; then
-  withval="$with_dump_honor_nodump"
-   if test -x $DUMP; then
-        echo "$as_me:$LINENO: checking whether $DUMP supports -h (honor nodump flag)" >&5
-echo $ECHO_N "checking whether $DUMP supports -h (honor nodump flag)... $ECHO_C" >&6
-if test "${amanda_cv_honor_nodump+set}" = set; then
+echo "$as_me:$LINENO: checking for long long" >&5
+echo $ECHO_N "checking for long long... $ECHO_C" >&6
+if test "${ac_cv_type_long_long+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-
-           case "$DUMP" in
-           *dump)
-               { ac_try='$DUMP 9hf 0 /dev/null /dev/null/invalid/fs 2>&1
-                   | $GREP -v Dumping
-                   | $GREP -v Date
-                   | $GREP -v Label >conftest.d-h 2>&1'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long long *) 0)
+  return 0;
+if (sizeof (long long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }
-               cat conftest.d-h >&5
-               { ac_try='$DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
-                   | $GREP -v Dumping
-                   | $GREP -v Date
-                   | $GREP -v Label >conftest.d 2>&1'
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }
-               cat conftest.d >&5
-               if { ac_try='diff conftest.d-h conftest.d 1>&2'
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-                   amanda_cv_honor_nodump=yes
-               else
-                   amanda_cv_honor_nodump=no
-               fi
-               rm -f conftest.d conftest.d-h
-             ;;
-           *) amanda_cv_honor_nodump=no
-             ;;
-           esac
-
-fi
-echo "$as_me:$LINENO: result: $amanda_cv_honor_nodump" >&5
-echo "${ECHO_T}$amanda_cv_honor_nodump" >&6
-      else
-       { echo "$as_me:$LINENO: WARNING: *** $DUMP is not executable, cannot run -h test" >&5
-echo "$as_me: WARNING: *** $DUMP is not executable, cannot run -h test" >&2;}
-       amanda_cv_honor_nodump=no
-      fi
-      if test "x$amanda_cv_honor_nodump" = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_HONOR_NODUMP 1
-_ACEOF
-
-      fi
-
-fi;
-fi
-
-for ac_prog in xfsdump
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_XFSDUMP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  ac_cv_type_long_long=yes
 else
-  case $XFSDUMP in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_XFSDUMP="$XFSDUMP" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_XFSDUMP="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-  ;;
-esac
+ac_cv_type_long_long=no
 fi
-XFSDUMP=$ac_cv_path_XFSDUMP
-
-if test -n "$XFSDUMP"; then
-  echo "$as_me:$LINENO: result: $XFSDUMP" >&5
-echo "${ECHO_T}$XFSDUMP" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_long_long" >&6
 
-  test -n "$XFSDUMP" && break
-done
-
-for ac_prog in xfsrestore
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_XFSRESTORE+set}" = set; then
+echo "$as_me:$LINENO: checking size of long long" >&5
+echo $ECHO_N "checking size of long long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long_long+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $XFSRESTORE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_XFSRESTORE="$XFSRESTORE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_XFSRESTORE="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-  ;;
-esac
-fi
-XFSRESTORE=$ac_cv_path_XFSRESTORE
-
-if test -n "$XFSRESTORE"; then
-  echo "$as_me:$LINENO: result: $XFSRESTORE" >&5
-echo "${ECHO_T}$XFSRESTORE" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  test -n "$XFSRESTORE" && break
-done
-
-if test "$XFSDUMP" -a "$XFSRESTORE"; then
-
-cat >>confdefs.h <<_ACEOF
-#define XFSDUMP "$XFSDUMP"
+  if test "$ac_cv_type_long_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= 0)];
+test_array [0] = 0
 
-
-cat >>confdefs.h <<_ACEOF
-#define XFSRESTORE "$XFSRESTORE"
+  ;
+  return 0;
+}
 _ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+test_array [0] = 0
 
-    { echo "$as_me:$LINENO: WARNING: *** xfsdump causes the setuid-root rundump program to be enabled" >&5
-echo "$as_me: WARNING: *** xfsdump causes the setuid-root rundump program to be enabled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: *** to disable it, just #undef XFSDUMP in config/config.h" >&5
-echo "$as_me: WARNING: *** to disable it, just #undef XFSDUMP in config/config.h" >&2;}
-fi
-
-VXSYSLOCPATH="$SYSLOCPATH:/usr/lib/fs/vxfs"
-for ac_prog in vxdump
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_VXDUMP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $VXDUMP in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_VXDUMP="$VXDUMP" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $VXSYSLOCPATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_VXDUMP="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-  ;;
-esac
-fi
-VXDUMP=$ac_cv_path_VXDUMP
-
-if test -n "$VXDUMP"; then
-  echo "$as_me:$LINENO: result: $VXDUMP" >&5
-echo "${ECHO_T}$VXDUMP" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  test -n "$VXDUMP" && break
-done
-
-for ac_prog in vxrestore
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_VXRESTORE+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
 else
-  case $VXRESTORE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_VXRESTORE="$VXRESTORE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $VXSYSLOCPATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_VXRESTORE="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-  ;;
-esac
-fi
-VXRESTORE=$ac_cv_path_VXRESTORE
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-if test -n "$VXRESTORE"; then
-  echo "$as_me:$LINENO: result: $VXRESTORE" >&5
-echo "${ECHO_T}$VXRESTORE" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
 fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-  test -n "$VXRESTORE" && break
-done
-
-if test "$VXDUMP" -a "$VXRESTORE"; then
-
-cat >>confdefs.h <<_ACEOF
-#define VXDUMP "$VXDUMP"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) < 0)];
+test_array [0] = 0
 
-
-cat >>confdefs.h <<_ACEOF
-#define VXRESTORE "$VXRESTORE"
+  ;
+  return 0;
+}
 _ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= $ac_mid)];
+test_array [0] = 0
 
-fi
-
-for ac_prog in vdump
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_VDUMP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
 else
-  case $VDUMP in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_VDUMP="$VDUMP" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_VDUMP="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-  ;;
-esac
-fi
-VDUMP=$ac_cv_path_VDUMP
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-if test -n "$VDUMP"; then
-  echo "$as_me:$LINENO: result: $VDUMP" >&5
-echo "${ECHO_T}$VDUMP" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
 fi
-
-  test -n "$VDUMP" && break
-done
-
-for ac_prog in vrestore
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_VRESTORE+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
 else
-  case $VRESTORE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_VRESTORE="$VRESTORE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_VRESTORE="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-  ;;
-esac
+ac_lo= ac_hi=
 fi
-VRESTORE=$ac_cv_path_VRESTORE
-
-if test -n "$VRESTORE"; then
-  echo "$as_me:$LINENO: result: $VRESTORE" >&5
-echo "${ECHO_T}$VRESTORE" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-
-  test -n "$VRESTORE" && break
-done
-
-if test "$VDUMP" -a "$VRESTORE"; then
-
-cat >>confdefs.h <<_ACEOF
-#define VDUMP "$VDUMP"
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+test_array [0] = 0
 
-
-cat >>confdefs.h <<_ACEOF
-#define VRESTORE "$VRESTORE"
+  ;
+  return 0;
+}
 _ACEOF
-
-fi
-
-if test "$PCAT"; then
-    AMPLOT_CAT_PACK="if(o==\"z\")print \"$PCAT\"; else"
-else
-    AMPLOT_CAT_PACK=
-fi
-if test "$COMPRESS"; then
-    AMPLOT_COMPRESS=$COMPRESS
-    AMPLOT_CAT_COMPRESS="if(o==\"Z\")print \"$COMPRESS -dc\"; else"
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
 else
-    AMPLOT_CAT_COMPRESS=
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
 fi
-if test "$GZIP"; then
-    AMPLOT_COMPRESS=$GZIP
-    AMPLOT_CAT_GZIP="if(o==\"gz\")print \"$GZIP -dc\"; else"
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
 else
-    AMPLOT_CAT_GZIP=
-fi
-
-
-
-
-
-# Determine the printf format characters to use when printing
-# values of type long long. This will normally be "ll", but where
-# the compiler treats "long long" as a alias for "long" and printf
-# doesn't know about "long long" use "l".  Hopefully the sprintf
-# will produce a inconsistant result in the later case.  If the compiler
-# fails due to seeing "%lld" we fall back to "l".
-#
-# Win32 uses "%I64d", but that's defined elsewhere since we don't use
-# configure on Win32.
-#
-echo "$as_me:$LINENO: checking printf format modifier for 64-bit integers" >&5
-echo $ECHO_N "checking printf format modifier for 64-bit integers... $ECHO_C" >&6
-if test "$cross_compiling" = yes; then
-  echo "$as_me:$LINENO: result: assuming target platform uses ll" >&5
-echo "${ECHO_T}assuming target platform uses ll" >&6
-       LL_FMT="%lld"
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
 else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -10258,17 +12336,37 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
+$ac_includes_default
+long longval () { return (long) (sizeof (long long)); }
+unsigned long ulongval () { return (long) (sizeof (long long)); }
 #include <stdio.h>
-main() {
-       long long int j = 0;
-       char buf[100];
-       buf[0] = 0;
-       sprintf(buf, "%lld", j);
-       exit((sizeof(long long int) != sizeof(long int))? 0 :
-            (strcmp(buf, "0") != 0));
-}
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long long))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long long))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
 
+  ;
+  return 0;
+}
 _ACEOF
 rm -f conftest$ac_exeext
 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
@@ -10281,100 +12379,37 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  echo "$as_me:$LINENO: result: ll" >&5
-echo "${ECHO_T}ll" >&6
-       LL_FMT="%lld"
+  ac_cv_sizeof_long_long=`cat conftest.val`
 else
   echo "$as_me: program exited with status $ac_status" >&5
 echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 ( exit $ac_status )
-echo "$as_me:$LINENO: result: l" >&5
-echo "${ECHO_T}l" >&6
-       LL_FMT="%ld"
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
 fi
 rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
-
-cat >>confdefs.h <<_ACEOF
-#define LL_FMT "$LL_FMT"
-_ACEOF
-
-
-
-GZIP=
-
-need_resetofs=yes
-echo "$as_me:$LINENO: checking for large file compilation CFLAGS" >&5
-echo $ECHO_N "checking for large file compilation CFLAGS... $ECHO_C" >&6
-if test "${amanda_cv_LFS_CFLAGS+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-       amanda_cv_LFS_CFLAGS=
-       if test "$GETCONF"; then
-           if $GETCONF ${GETCONF_LFS}_CFLAGS >/dev/null 2>&1; then
-               amanda_cv_LFS_CFLAGS=`$GETCONF ${GETCONF_LFS}_CFLAGS 2>/dev/null`
-               need_resetofs=no
-           fi
-       fi
-
-
 fi
-echo "$as_me:$LINENO: result: $amanda_cv_LFS_CFLAGS" >&5
-echo "${ECHO_T}$amanda_cv_LFS_CFLAGS" >&6
-echo "$as_me:$LINENO: checking for large file compilation LDFLAGS" >&5
-echo $ECHO_N "checking for large file compilation LDFLAGS... $ECHO_C" >&6
-if test "${amanda_cv_LFS_LDFLAGS+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f conftest.val
 else
-
-       amanda_cv_LFS_LDFLAGS=
-       if test "$GETCONF"; then
-           if $GETCONF ${GETCONF_LFS}_LDFLAGS >/dev/null 2>&1; then
-               amanda_cv_LFS_LDFLAGS=`$GETCONF ${GETCONF_LFS}_LDFLAGS 2>/dev/null`
-               need_resetofs=no
-           fi
-       fi
-
-
+  ac_cv_sizeof_long_long=0
 fi
-echo "$as_me:$LINENO: result: $amanda_cv_LFS_LDFLAGS" >&5
-echo "${ECHO_T}$amanda_cv_LFS_LDFLAGS" >&6
-echo "$as_me:$LINENO: checking for large file compilation LIBS" >&5
-echo $ECHO_N "checking for large file compilation LIBS... $ECHO_C" >&6
-if test "${amanda_cv_LFS_LIBS+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-       amanda_cv_LFS_LIBS=
-       if test "$GETCONF"; then
-           if $GETCONF ${GETCONF_LFS}_LIBS >/dev/null 2>&1; then
-               amanda_cv_LFS_LIBS=`$GETCONF ${GETCONF_LFS}_LIBS 2>/dev/null`
-               need_resetofs=no
-           fi
-       fi
-
-
 fi
-echo "$as_me:$LINENO: result: $amanda_cv_LFS_LIBS" >&5
-echo "${ECHO_T}$amanda_cv_LFS_LIBS" >&6
-if test "x$need_resetofs" = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define NEED_RESETOFS 1
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
 _ACEOF
 
-fi
-CFLAGS="$amanda_cv_LFS_CFLAGS $CFLAGS"
-CPPFLAGS="$amanda_cv_LFS_CFLAGS $CPPFLAGS"
-LDFLAGS="$amanda_cv_LFS_LDFLAGS $LDFLAGS"
-LIBS="$amanda_cv_LFS_LIBS $LIBS"
 
-echo "$as_me:$LINENO: checking for int" >&5
-echo $ECHO_N "checking for int... $ECHO_C" >&6
-if test "${ac_cv_type_int+set}" = set; then
+echo "$as_me:$LINENO: checking for intmax_t" >&5
+echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6
+if test "${ac_cv_type_intmax_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -10387,9 +12422,9 @@ $ac_includes_default
 int
 main ()
 {
-if ((int *) 0)
+if ((intmax_t *) 0)
   return 0;
-if (sizeof (int))
+if (sizeof (intmax_t))
   return 0;
   ;
   return 0;
@@ -10417,24 +12452,24 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_int=yes
+  ac_cv_type_intmax_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_type_int=no
+ac_cv_type_intmax_t=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
-echo "${ECHO_T}$ac_cv_type_int" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5
+echo "${ECHO_T}$ac_cv_type_intmax_t" >&6
 
-echo "$as_me:$LINENO: checking size of int" >&5
-echo $ECHO_N "checking size of int... $ECHO_C" >&6
-if test "${ac_cv_sizeof_int+set}" = set; then
+echo "$as_me:$LINENO: checking size of intmax_t" >&5
+echo $ECHO_N "checking size of intmax_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_intmax_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$ac_cv_type_int" = yes; then
+  if test "$ac_cv_type_intmax_t" = yes; then
   # The cast to unsigned long works around a bug in the HP C Compiler
   # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
   # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -10451,7 +12486,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) >= 0)];
 test_array [0] = 0
 
   ;
@@ -10492,7 +12527,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -10549,7 +12584,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) < 0)];
 test_array [0] = 0
 
   ;
@@ -10590,7 +12625,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) >= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -10655,7 +12690,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 done
 case $ac_lo in
-?*) ac_cv_sizeof_int=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+?*) ac_cv_sizeof_intmax_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (intmax_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (int), 77
+echo "$as_me: error: cannot compute sizeof (intmax_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; } ;;
 esac
@@ -10716,8 +12751,8 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-long longval () { return (long) (sizeof (int)); }
-unsigned long ulongval () { return (long) (sizeof (int)); }
+long longval () { return (long) (sizeof (intmax_t)); }
+unsigned long ulongval () { return (long) (sizeof (intmax_t)); }
 #include <stdio.h>
 #include <stdlib.h>
 int
@@ -10727,17 +12762,17 @@ main ()
   FILE *f = fopen ("conftest.val", "w");
   if (! f)
     exit (1);
-  if (((long) (sizeof (int))) < 0)
+  if (((long) (sizeof (intmax_t))) < 0)
     {
       long i = longval ();
-      if (i != ((long) (sizeof (int))))
+      if (i != ((long) (sizeof (intmax_t))))
        exit (1);
       fprintf (f, "%ld\n", i);
     }
   else
     {
       unsigned long i = ulongval ();
-      if (i != ((long) (sizeof (int))))
+      if (i != ((long) (sizeof (intmax_t))))
        exit (1);
       fprintf (f, "%lu\n", i);
     }
@@ -10758,16 +12793,16 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_sizeof_int=`cat conftest.val`
+  ac_cv_sizeof_intmax_t=`cat conftest.val`
 else
   echo "$as_me: program exited with status $ac_status" >&5
 echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 ( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (intmax_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (int), 77
+echo "$as_me: error: cannot compute sizeof (intmax_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 fi
 fi
 rm -f conftest.val
 else
-  ac_cv_sizeof_int=0
+  ac_cv_sizeof_intmax_t=0
 fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
-echo "${ECHO_T}$ac_cv_sizeof_int" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_intmax_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_intmax_t" >&6
 cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT $ac_cv_sizeof_int
+#define SIZEOF_INTMAX_T $ac_cv_sizeof_intmax_t
 _ACEOF
 
 
-echo "$as_me:$LINENO: checking for long" >&5
-echo $ECHO_N "checking for long... $ECHO_C" >&6
-if test "${ac_cv_type_long+set}" = set; then
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -10801,9 +12836,9 @@ $ac_includes_default
 int
 main ()
 {
-if ((long *) 0)
+if ((off_t *) 0)
   return 0;
-if (sizeof (long))
+if (sizeof (off_t))
   return 0;
   ;
   return 0;
@@ -10831,24 +12866,24 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_long=yes
+  ac_cv_type_off_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_type_long=no
+ac_cv_type_off_t=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
-echo "${ECHO_T}$ac_cv_type_long" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
 
-echo "$as_me:$LINENO: checking size of long" >&5
-echo $ECHO_N "checking size of long... $ECHO_C" >&6
-if test "${ac_cv_sizeof_long+set}" = set; then
+echo "$as_me:$LINENO: checking size of off_t" >&5
+echo $ECHO_N "checking size of off_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_off_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$ac_cv_type_long" = yes; then
+  if test "$ac_cv_type_off_t" = yes; then
   # The cast to unsigned long works around a bug in the HP C Compiler
   # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
   # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -10865,7 +12900,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= 0)];
 test_array [0] = 0
 
   ;
@@ -10906,7 +12941,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -10963,7 +12998,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) < 0)];
 test_array [0] = 0
 
   ;
@@ -11004,7 +13039,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -11069,7 +13104,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 done
 case $ac_lo in
-?*) ac_cv_sizeof_long=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+?*) ac_cv_sizeof_off_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long), 77
+echo "$as_me: error: cannot compute sizeof (off_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; } ;;
 esac
@@ -11130,8 +13165,8 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-long longval () { return (long) (sizeof (long)); }
-unsigned long ulongval () { return (long) (sizeof (long)); }
+long longval () { return (long) (sizeof (off_t)); }
+unsigned long ulongval () { return (long) (sizeof (off_t)); }
 #include <stdio.h>
 #include <stdlib.h>
 int
@@ -11141,17 +13176,17 @@ main ()
   FILE *f = fopen ("conftest.val", "w");
   if (! f)
     exit (1);
-  if (((long) (sizeof (long))) < 0)
+  if (((long) (sizeof (off_t))) < 0)
     {
       long i = longval ();
-      if (i != ((long) (sizeof (long))))
+      if (i != ((long) (sizeof (off_t))))
        exit (1);
       fprintf (f, "%ld\n", i);
     }
   else
     {
       unsigned long i = ulongval ();
-      if (i != ((long) (sizeof (long))))
+      if (i != ((long) (sizeof (off_t))))
        exit (1);
       fprintf (f, "%lu\n", i);
     }
@@ -11172,16 +13207,16 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_sizeof_long=`cat conftest.val`
+  ac_cv_sizeof_off_t=`cat conftest.val`
 else
   echo "$as_me: program exited with status $ac_status" >&5
 echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 ( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long), 77
+echo "$as_me: error: cannot compute sizeof (off_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 fi
 fi
 rm -f conftest.val
 else
-  ac_cv_sizeof_long=0
+  ac_cv_sizeof_off_t=0
 fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
-echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_off_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_off_t" >&6
 cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG $ac_cv_sizeof_long
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
 _ACEOF
 
 
-echo "$as_me:$LINENO: checking for long long" >&5
-echo $ECHO_N "checking for long long... $ECHO_C" >&6
-if test "${ac_cv_type_long_long+set}" = set; then
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -11215,9 +13250,9 @@ $ac_includes_default
 int
 main ()
 {
-if ((long long *) 0)
+if ((size_t *) 0)
   return 0;
-if (sizeof (long long))
+if (sizeof (size_t))
   return 0;
   ;
   return 0;
@@ -11245,24 +13280,24 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_long_long=yes
+  ac_cv_type_size_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_type_long_long=no
+ac_cv_type_size_t=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
-echo "${ECHO_T}$ac_cv_type_long_long" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
 
-echo "$as_me:$LINENO: checking size of long long" >&5
-echo $ECHO_N "checking size of long long... $ECHO_C" >&6
-if test "${ac_cv_sizeof_long_long+set}" = set; then
+echo "$as_me:$LINENO: checking size of size_t" >&5
+echo $ECHO_N "checking size of size_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_size_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$ac_cv_type_long_long" = yes; then
+  if test "$ac_cv_type_size_t" = yes; then
   # The cast to unsigned long works around a bug in the HP C Compiler
   # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
   # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -11279,7 +13314,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) >= 0)];
 test_array [0] = 0
 
   ;
@@ -11320,7 +13355,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -11377,7 +13412,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) < 0)];
 test_array [0] = 0
 
   ;
@@ -11418,7 +13453,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) >= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -11483,7 +13518,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 done
 case $ac_lo in
-?*) ac_cv_sizeof_long_long=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+?*) ac_cv_sizeof_size_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (size_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long long), 77
+echo "$as_me: error: cannot compute sizeof (size_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; } ;;
 esac
@@ -11544,8 +13579,8 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-long longval () { return (long) (sizeof (long long)); }
-unsigned long ulongval () { return (long) (sizeof (long long)); }
+long longval () { return (long) (sizeof (size_t)); }
+unsigned long ulongval () { return (long) (sizeof (size_t)); }
 #include <stdio.h>
 #include <stdlib.h>
 int
@@ -11555,17 +13590,17 @@ main ()
   FILE *f = fopen ("conftest.val", "w");
   if (! f)
     exit (1);
-  if (((long) (sizeof (long long))) < 0)
+  if (((long) (sizeof (size_t))) < 0)
     {
       long i = longval ();
-      if (i != ((long) (sizeof (long long))))
+      if (i != ((long) (sizeof (size_t))))
        exit (1);
       fprintf (f, "%ld\n", i);
     }
   else
     {
       unsigned long i = ulongval ();
-      if (i != ((long) (sizeof (long long))))
+      if (i != ((long) (sizeof (size_t))))
        exit (1);
       fprintf (f, "%lu\n", i);
     }
@@ -11586,16 +13621,16 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_sizeof_long_long=`cat conftest.val`
+  ac_cv_sizeof_size_t=`cat conftest.val`
 else
   echo "$as_me: program exited with status $ac_status" >&5
 echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 ( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (size_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long long), 77
+echo "$as_me: error: cannot compute sizeof (size_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 fi
 fi
 rm -f conftest.val
 else
-  ac_cv_sizeof_long_long=0
+  ac_cv_sizeof_size_t=0
 fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5
-echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_size_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_size_t" >&6
 cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
 _ACEOF
 
 
-echo "$as_me:$LINENO: checking for intmax_t" >&5
-echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6
-if test "${ac_cv_type_intmax_t+set}" = set; then
+echo "$as_me:$LINENO: checking for ssize_t" >&5
+echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6
+if test "${ac_cv_type_ssize_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -11629,9 +13664,9 @@ $ac_includes_default
 int
 main ()
 {
-if ((intmax_t *) 0)
+if ((ssize_t *) 0)
   return 0;
-if (sizeof (intmax_t))
+if (sizeof (ssize_t))
   return 0;
   ;
   return 0;
@@ -11659,24 +13694,24 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_intmax_t=yes
+  ac_cv_type_ssize_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_type_intmax_t=no
+ac_cv_type_ssize_t=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5
-echo "${ECHO_T}$ac_cv_type_intmax_t" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
 
-echo "$as_me:$LINENO: checking size of intmax_t" >&5
-echo $ECHO_N "checking size of intmax_t... $ECHO_C" >&6
-if test "${ac_cv_sizeof_intmax_t+set}" = set; then
+echo "$as_me:$LINENO: checking size of ssize_t" >&5
+echo $ECHO_N "checking size of ssize_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_ssize_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$ac_cv_type_intmax_t" = yes; then
+  if test "$ac_cv_type_ssize_t" = yes; then
   # The cast to unsigned long works around a bug in the HP C Compiler
   # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
   # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -11693,7 +13728,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) >= 0)];
 test_array [0] = 0
 
   ;
@@ -11734,7 +13769,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -11791,7 +13826,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) < 0)];
 test_array [0] = 0
 
   ;
@@ -11832,7 +13867,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) >= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -11897,7 +13932,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 done
 case $ac_lo in
-?*) ac_cv_sizeof_intmax_t=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (intmax_t), 77
+?*) ac_cv_sizeof_ssize_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (ssize_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (intmax_t), 77
+echo "$as_me: error: cannot compute sizeof (ssize_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; } ;;
 esac
@@ -11958,8 +13993,8 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-long longval () { return (long) (sizeof (intmax_t)); }
-unsigned long ulongval () { return (long) (sizeof (intmax_t)); }
+long longval () { return (long) (sizeof (ssize_t)); }
+unsigned long ulongval () { return (long) (sizeof (ssize_t)); }
 #include <stdio.h>
 #include <stdlib.h>
 int
@@ -11969,17 +14004,17 @@ main ()
   FILE *f = fopen ("conftest.val", "w");
   if (! f)
     exit (1);
-  if (((long) (sizeof (intmax_t))) < 0)
+  if (((long) (sizeof (ssize_t))) < 0)
     {
       long i = longval ();
-      if (i != ((long) (sizeof (intmax_t))))
+      if (i != ((long) (sizeof (ssize_t))))
        exit (1);
       fprintf (f, "%ld\n", i);
     }
   else
     {
       unsigned long i = ulongval ();
-      if (i != ((long) (sizeof (intmax_t))))
+      if (i != ((long) (sizeof (ssize_t))))
        exit (1);
       fprintf (f, "%lu\n", i);
     }
@@ -12000,16 +14035,16 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_sizeof_intmax_t=`cat conftest.val`
+  ac_cv_sizeof_ssize_t=`cat conftest.val`
 else
   echo "$as_me: program exited with status $ac_status" >&5
 echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 ( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (intmax_t), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (ssize_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (intmax_t), 77
+echo "$as_me: error: cannot compute sizeof (ssize_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 fi
 fi
 rm -f conftest.val
 else
-  ac_cv_sizeof_intmax_t=0
+  ac_cv_sizeof_ssize_t=0
 fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_intmax_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_intmax_t" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_ssize_t" >&6
 cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INTMAX_T $ac_cv_sizeof_intmax_t
+#define SIZEOF_SSIZE_T $ac_cv_sizeof_ssize_t
 _ACEOF
 
 
-echo "$as_me:$LINENO: checking for off_t" >&5
-echo $ECHO_N "checking for off_t... $ECHO_C" >&6
-if test "${ac_cv_type_off_t+set}" = set; then
+echo "$as_me:$LINENO: checking for time_t" >&5
+echo $ECHO_N "checking for time_t... $ECHO_C" >&6
+if test "${ac_cv_type_time_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -12043,9 +14078,9 @@ $ac_includes_default
 int
 main ()
 {
-if ((off_t *) 0)
+if ((time_t *) 0)
   return 0;
-if (sizeof (off_t))
+if (sizeof (time_t))
   return 0;
   ;
   return 0;
@@ -12073,24 +14108,24 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_off_t=yes
+  ac_cv_type_time_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ac_cv_type_off_t=no
+ac_cv_type_time_t=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
-echo "${ECHO_T}$ac_cv_type_off_t" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_time_t" >&5
+echo "${ECHO_T}$ac_cv_type_time_t" >&6
 
-echo "$as_me:$LINENO: checking size of off_t" >&5
-echo $ECHO_N "checking size of off_t... $ECHO_C" >&6
-if test "${ac_cv_sizeof_off_t+set}" = set; then
+echo "$as_me:$LINENO: checking size of time_t" >&5
+echo $ECHO_N "checking size of time_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_time_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$ac_cv_type_off_t" = yes; then
+  if test "$ac_cv_type_time_t" = yes; then
   # The cast to unsigned long works around a bug in the HP C Compiler
   # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
   # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -12107,7 +14142,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) >= 0)];
 test_array [0] = 0
 
   ;
@@ -12148,7 +14183,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -12205,7 +14240,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) < 0)];
 test_array [0] = 0
 
   ;
@@ -12246,7 +14281,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) >= $ac_mid)];
 test_array [0] = 0
 
   ;
@@ -12311,7 +14346,7 @@ $ac_includes_default
 int
 main ()
 {
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) <= $ac_mid)];
 test_array [0] = 0
 
   ;
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 done
 case $ac_lo in
-?*) ac_cv_sizeof_off_t=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
+?*) ac_cv_sizeof_time_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (time_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (off_t), 77
+echo "$as_me: error: cannot compute sizeof (time_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; } ;;
 esac
@@ -12372,8 +14407,8 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-long longval () { return (long) (sizeof (off_t)); }
-unsigned long ulongval () { return (long) (sizeof (off_t)); }
+long longval () { return (long) (sizeof (time_t)); }
+unsigned long ulongval () { return (long) (sizeof (time_t)); }
 #include <stdio.h>
 #include <stdlib.h>
 int
@@ -12383,17 +14418,17 @@ main ()
   FILE *f = fopen ("conftest.val", "w");
   if (! f)
     exit (1);
-  if (((long) (sizeof (off_t))) < 0)
+  if (((long) (sizeof (time_t))) < 0)
     {
       long i = longval ();
-      if (i != ((long) (sizeof (off_t))))
+      if (i != ((long) (sizeof (time_t))))
        exit (1);
       fprintf (f, "%ld\n", i);
     }
   else
     {
       unsigned long i = ulongval ();
-      if (i != ((long) (sizeof (off_t))))
+      if (i != ((long) (sizeof (time_t))))
        exit (1);
       fprintf (f, "%lu\n", i);
     }
@@ -12414,16 +14449,16 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_sizeof_off_t=`cat conftest.val`
+  ac_cv_sizeof_time_t=`cat conftest.val`
 else
   echo "$as_me: program exited with status $ac_status" >&5
 echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 ( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (time_t), 77
 See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (off_t), 77
+echo "$as_me: error: cannot compute sizeof (time_t), 77
 See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 fi
 fi
 rm -f conftest.val
 else
-  ac_cv_sizeof_off_t=0
+  ac_cv_sizeof_time_t=0
 fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_off_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_off_t" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_time_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_time_t" >&6
 cat >>confdefs.h <<_ACEOF
-#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
 _ACEOF
 
 
@@ -12977,7 +15012,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 12980 "configure"' > conftest.$ac_ext
+  echo '#line 15015 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -14083,7 +16118,7 @@ fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:14086:" \
+echo "$as_me:16121:" \
      "checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -15185,11 +17220,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15188: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17223: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15192: \$? = $ac_status" >&5
+   echo "$as_me:17227: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -15447,11 +17482,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15450: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17485: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15454: \$? = $ac_status" >&5
+   echo "$as_me:17489: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -15509,11 +17544,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15512: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17547: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:15516: \$? = $ac_status" >&5
+   echo "$as_me:17551: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17757,7 +19792,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 17760 "configure"
+#line 19795 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -17855,7 +19890,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 17858 "configure"
+#line 19893 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -20114,11 +22149,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:20117: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:22152: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:20121: \$? = $ac_status" >&5
+   echo "$as_me:22156: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -20176,11 +22211,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:20179: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:22214: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:20183: \$? = $ac_status" >&5
+   echo "$as_me:22218: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -21553,7 +23588,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 21556 "configure"
+#line 23591 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -21651,7 +23686,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 21654 "configure"
+#line 23689 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -22536,11 +24571,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:22539: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:24574: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:22543: \$? = $ac_status" >&5
+   echo "$as_me:24578: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -22598,11 +24633,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:22601: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:24636: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:22605: \$? = $ac_status" >&5
+   echo "$as_me:24640: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -24732,11 +26767,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:24735: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:26770: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:24739: \$? = $ac_status" >&5
+   echo "$as_me:26774: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -24994,11 +27029,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:24997: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:27032: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:25001: \$? = $ac_status" >&5
+   echo "$as_me:27036: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -25056,11 +27091,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:25059: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:27094: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:25063: \$? = $ac_status" >&5
+   echo "$as_me:27098: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -27304,7 +29339,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 27307 "configure"
+#line 29342 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -27402,7 +29437,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 27405 "configure"
+#line 29440 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -29397,45 +31432,6 @@ if test "$LEX" = :; then
   LEX=${am_missing_run}flex
 fi
 
-
-echo "$as_me:$LINENO: checking for socklen_t" >&5
-echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
-if test "${ac_cv_type_socklen_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-#include <sys/socket.h>
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "(^|[^a-zA-Z_0-9])socklen_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
-  ac_cv_type_socklen_t=yes
-else
-  ac_cv_type_socklen_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
-echo "${ECHO_T}$ac_cv_type_socklen_t" >&6
-if test "x$ac_cv_type_socklen_t" = xno; then
-
-cat >>confdefs.h <<\_ACEOF
-#define socklen_t int
-_ACEOF
-
-fi
-
-
 echo "$as_me:$LINENO: checking for ANSI C header files" >&5
 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
 if test "${ac_cv_header_stdc+set}" = set; then
 
 
 
+echo "$as_me:$LINENO: checking for socklen_t" >&5
+echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
+if test "${ac_cv_type_socklen_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <sys/socket.h>
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "(^|[^a-zA-Z_0-9])socklen_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  ac_cv_type_socklen_t=yes
+else
+  ac_cv_type_socklen_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
+echo "${ECHO_T}$ac_cv_type_socklen_t" >&6
+if test "x$ac_cv_type_socklen_t" = xno; then
+
+cat >>confdefs.h <<\_ACEOF
+#define socklen_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for sa_family_t" >&5
+echo $ECHO_N "checking for sa_family_t... $ECHO_C" >&6
+if test "${ac_cv_type_sa_family_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <sys/socket.h>
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "(^|[^a-zA-Z_0-9])sa_family_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  ac_cv_type_sa_family_t=yes
+else
+  ac_cv_type_sa_family_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_sa_family_t" >&5
+echo "${ECHO_T}$ac_cv_type_sa_family_t" >&6
+if test "x$ac_cv_type_sa_family_t" = xno; then
+
+cat >>confdefs.h <<\_ACEOF
+#define sa_family_t unsigned short
+_ACEOF
+
+fi
+
+
+
+
 
 
 
@@ -30513,6 +32586,9 @@ fi
 
 
 
+
+
+
 
 
 
@@ -30531,8 +32607,10 @@ for ac_header in \
        grp.h \
        history.h \
        libc.h \
+       libgen.h \
        limits.h \
        linux/zftape.h \
+       math.h \
        mntent.h \
        mnttab.h \
        ndbm.h \
@@ -30543,6 +32621,7 @@ for ac_header in \
        readline/readline.h \
        scsi/sg.h \
        scsi/scsi_ioctl.h \
+       stdarg.h \
        stdlib.h \
        string.h \
        strings.h \
@@ -32543,7 +34622,8 @@ fi
 if test "x$ac_cv_lib_termcap_tgetent" = xyes ||
    test "x$ac_cv_lib_curses_tgetent" = xyes ||
    test "x$ac_cv_lib_ncurses_tgetent" = xyes; then
-    echo "$as_me:$LINENO: checking for readline in -lreadline" >&5
+
+echo "$as_me:$LINENO: checking for readline in -lreadline" >&5
 echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6
 if test "${ac_cv_lib_readline_readline+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5
 echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6
 if test $ac_cv_lib_readline_readline = yes; then
-  READLINE_LIBS="-lreadline";
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBREADLINE 1
+_ACEOF
+
+  LIBS="-lreadline $LIBS"
 
 fi
 
-    if test "x$ac_cv_lib_readline_readline" != xyes; then
+    if test "x$ac_cv_lib_readline_readline" = xyes; then
+       READLINE_LIBS="-lreadline"
+
+    else
        { echo "$as_me:$LINENO: WARNING: *** No readline library, no history and command line editing in amrecover!" >&5
 echo "$as_me: WARNING: *** No readline library, no history and command line editing in amrecover!" >&2;}
     fi
@@ -34871,18 +36958,522 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
- ice_have_atof=yes
+ ice_have_atof=yes
+fi
+done
+
+if test "${ice_have_atof}" = yes; then
+echo "$as_me:$LINENO: checking for atof declaration in stdlib.h" >&5
+echo $ECHO_N "checking for atof declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_atof_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_atof_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdlib.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}atof[  ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_atof_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atof_decl" = yes; then
+       break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}atof[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_atof_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atof_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_atof_decl" >&5
+echo "${ECHO_T}$ice_cv_have_atof_decl" >&6
+if test "$ice_cv_have_atof_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATOF_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_atoi=no
+
+for ac_func in atoi
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ ice_have_atoi=yes
+fi
+done
+
+if test "${ice_have_atoi}" = yes; then
+echo "$as_me:$LINENO: checking for atoi declaration in stdlib.h" >&5
+echo $ECHO_N "checking for atoi declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_atoi_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_atoi_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdlib.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}atoi[  ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_atoi_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atoi_decl" = yes; then
+       break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}atoi[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_atoi_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atoi_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_atoi_decl" >&5
+echo "${ECHO_T}$ice_cv_have_atoi_decl" >&6
+if test "$ice_cv_have_atoi_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATOI_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_atol=no
+
+for ac_func in atol
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ ice_have_atol=yes
+fi
+done
+
+if test "${ice_have_atol}" = yes; then
+echo "$as_me:$LINENO: checking for atol declaration in stdlib.h" >&5
+echo $ECHO_N "checking for atol declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_atol_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_atol_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdlib.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}atol[  ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_atol_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atol_decl" = yes; then
+       break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}atol[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_atol_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atol_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_atol_decl" >&5
+echo "${ECHO_T}$ice_cv_have_atol_decl" >&6
+if test "$ice_cv_have_atol_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATOL_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_atoll=no
+
+for ac_func in atoll
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ ice_have_atoll=yes
 fi
 done
 
-if test "${ice_have_atof}" = yes; then
-echo "$as_me:$LINENO: checking for atof declaration in stdlib.h" >&5
-echo $ECHO_N "checking for atof declaration in stdlib.h... $ECHO_C" >&6
-if test "${ice_cv_have_atof_decl+set}" = set; then
+if test "${ice_have_atoll}" = yes; then
+echo "$as_me:$LINENO: checking for atoll declaration in stdlib.h" >&5
+echo $ECHO_N "checking for atoll declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_atoll_decl+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-ice_cv_have_atof_decl=no
+ice_cv_have_atoll_decl=no
 ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
 ice_re_word='(^|[^a-zA-Z0-9_])'
 for header in stdlib.h; do
@@ -34897,12 +37488,12 @@ cat >>conftest.$ac_ext <<_ACEOF
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "${ice_re_word}atof[  ]*\(" >/dev/null 2>&1; then
-  ice_cv_have_atof_decl=yes
+  $EGREP "${ice_re_word}atoll[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_atoll_decl=yes
 fi
 rm -f conftest*
 
-if test "$ice_cv_have_atof_decl" = yes; then
+if test "$ice_cv_have_atoll_decl" = yes; then
        break
 fi
 # Check for "fixed" declaration like "getpid _PARAMS((int))"
@@ -34916,24 +37507,24 @@ cat >>conftest.$ac_ext <<_ACEOF
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "${ice_re_word}atof[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
-  ice_cv_have_atof_decl=yes
+  $EGREP "${ice_re_word}atoll[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_atoll_decl=yes
 fi
 rm -f conftest*
 
-if test "$ice_cv_have_atof_decl" = yes; then
+if test "$ice_cv_have_atoll_decl" = yes; then
        break
 fi
 done
 
 fi
 
-echo "$as_me:$LINENO: result: $ice_cv_have_atof_decl" >&5
-echo "${ECHO_T}$ice_cv_have_atof_decl" >&6
-if test "$ice_cv_have_atof_decl" = yes; then
+echo "$as_me:$LINENO: result: $ice_cv_have_atoll_decl" >&5
+echo "${ECHO_T}$ice_cv_have_atoll_decl" >&6
+if test "$ice_cv_have_atoll_decl" = yes; then
 
 cat >>confdefs.h <<_ACEOF
-#define HAVE_ATOF_DECL 1
+#define HAVE_ATOLL_DECL 1
 _ACEOF
 
 fi
@@ -39353,161 +41944,265 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
- ice_have_gettimeofday=yes
-fi
-done
-
-if test "${ice_have_gettimeofday}" = yes; then
-echo "$as_me:$LINENO: checking for gettimeofday declaration in time.h sys/time.h" >&5
-echo $ECHO_N "checking for gettimeofday declaration in time.h sys/time.h... $ECHO_C" >&6
-if test "${ice_cv_have_gettimeofday_decl+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-ice_cv_have_gettimeofday_decl=no
-ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
-ice_re_word='(^|[^a-zA-Z0-9_])'
-for header in time.h sys/time.h; do
-# Check for ordinary declaration
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$header>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "${ice_re_word}gettimeofday[  ]*\(" >/dev/null 2>&1; then
-  ice_cv_have_gettimeofday_decl=yes
-fi
-rm -f conftest*
-
-if test "$ice_cv_have_gettimeofday_decl" = yes; then
-       break
-fi
-# Check for "fixed" declaration like "getpid _PARAMS((int))"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$header>
+ ice_have_gettimeofday=yes
+fi
+done
+
+if test "${ice_have_gettimeofday}" = yes; then
+echo "$as_me:$LINENO: checking for gettimeofday declaration in time.h sys/time.h" >&5
+echo $ECHO_N "checking for gettimeofday declaration in time.h sys/time.h... $ECHO_C" >&6
+if test "${ice_cv_have_gettimeofday_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_gettimeofday_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in time.h sys/time.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}gettimeofday[  ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_gettimeofday_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_gettimeofday_decl" = yes; then
+       break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}gettimeofday[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_gettimeofday_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_gettimeofday_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_gettimeofday_decl" >&5
+echo "${ECHO_T}$ice_cv_have_gettimeofday_decl" >&6
+if test "$ice_cv_have_gettimeofday_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GETTIMEOFDAY_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+
+       echo "$as_me:$LINENO: checking for gettimeofday number of arguments" >&5
+echo $ECHO_N "checking for gettimeofday number of arguments... $ECHO_C" >&6
+if test "${amanda_cv_gettimeofday_args+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef TIME_WITH_SYS_TIME
+#  include <sys/time.h>
+#  include <time.h>
+#else
+#  ifdef HAVE_SYS_TIME_H
+#    include <sys/time.h>
+#  else
+#    include <time.h>
+#  endif
+#endif
+
+int
+main ()
+{
+
+                       struct timeval val;
+                       struct timezone zone;
+                       gettimeofday(&val, &zone);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  amanda_cv_gettimeofday_args=2
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_gettimeofday_args=1
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_gettimeofday_args" >&5
+echo "${ECHO_T}$amanda_cv_gettimeofday_args" >&6
+       if test "$amanda_cv_gettimeofday_args" = 2; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TWO_ARG_GETTIMEOFDAY 1
+_ACEOF
+
+       fi
+
+
+
+
+
+for ac_func in getvfsent initgroups isascii
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "${ice_re_word}gettimeofday[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
-  ice_cv_have_gettimeofday_decl=yes
-fi
-rm -f conftest*
-
-if test "$ice_cv_have_gettimeofday_decl" = yes; then
-       break
 fi
 done
 
-fi
-
-echo "$as_me:$LINENO: result: $ice_cv_have_gettimeofday_decl" >&5
-echo "${ECHO_T}$ice_cv_have_gettimeofday_decl" >&6
-if test "$ice_cv_have_gettimeofday_decl" = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GETTIMEOFDAY_DECL 1
-_ACEOF
-
-fi
-fi
-
-
-
-       echo "$as_me:$LINENO: checking for gettimeofday number of arguments" >&5
-echo $ECHO_N "checking for gettimeofday number of arguments... $ECHO_C" >&6
-if test "${amanda_cv_gettimeofday_args+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-               cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#ifdef TIME_WITH_SYS_TIME
-#  include <sys/time.h>
-#  include <time.h>
-#else
-#  ifdef HAVE_SYS_TIME_H
-#    include <sys/time.h>
-#  else
-#    include <time.h>
-#  endif
-#endif
-
-int
-main ()
-{
-
-                       struct timeval val;
-                       struct timezone zone;
-                       gettimeofday(&val, &zone);
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  amanda_cv_gettimeofday_args=2
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-amanda_cv_gettimeofday_args=1
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-
-fi
-echo "$as_me:$LINENO: result: $amanda_cv_gettimeofday_args" >&5
-echo "${ECHO_T}$amanda_cv_gettimeofday_args" >&6
-       if test "$amanda_cv_gettimeofday_args" = 2; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_TWO_ARG_GETTIMEOFDAY 1
-_ACEOF
-
-       fi
-
-
-
 
+ice_have_initgroups=no
 
-for ac_func in getvfsent initgroups isascii
+for ac_func in initgroups
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -39604,14 +42299,78 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
+ ice_have_initgroups=yes
+fi
+done
+
+if test "${ice_have_initgroups}" = yes; then
+echo "$as_me:$LINENO: checking for initgroups declaration in grp.h sys/types.h unistd.h libc.h" >&5
+echo $ECHO_N "checking for initgroups declaration in grp.h sys/types.h unistd.h libc.h... $ECHO_C" >&6
+if test "${ice_cv_have_initgroups_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_initgroups_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in grp.h sys/types.h unistd.h libc.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}initgroups[    ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_initgroups_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_initgroups_decl" = yes; then
+       break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$header>
 
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ice_re_word}initgroups[    ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_initgroups_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_initgroups_decl" = yes; then
+       break
 fi
 done
 
+fi
 
-ice_have_initgroups=no
+echo "$as_me:$LINENO: result: $ice_cv_have_initgroups_decl" >&5
+echo "${ECHO_T}$ice_cv_have_initgroups_decl" >&6
+if test "$ice_cv_have_initgroups_decl" = yes; then
 
-for ac_func in initgroups
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INITGROUPS_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_ioctl=no
+
+for ac_func in ioctl
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -39708,21 +42467,21 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
- ice_have_initgroups=yes
+ ice_have_ioctl=yes
 fi
 done
 
-if test "${ice_have_initgroups}" = yes; then
-echo "$as_me:$LINENO: checking for initgroups declaration in grp.h sys/types.h unistd.h libc.h" >&5
-echo $ECHO_N "checking for initgroups declaration in grp.h sys/types.h unistd.h libc.h... $ECHO_C" >&6
-if test "${ice_cv_have_initgroups_decl+set}" = set; then
+if test "${ice_have_ioctl}" = yes; then
+echo "$as_me:$LINENO: checking for ioctl declaration in sys/ioctl.h unistd.h libc.h" >&5
+echo $ECHO_N "checking for ioctl declaration in sys/ioctl.h unistd.h libc.h... $ECHO_C" >&6
+if test "${ice_cv_have_ioctl_decl+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-ice_cv_have_initgroups_decl=no
+ice_cv_have_ioctl_decl=no
 ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
 ice_re_word='(^|[^a-zA-Z0-9_])'
-for header in grp.h sys/types.h unistd.h libc.h; do
+for header in sys/ioctl.h unistd.h libc.h; do
 # Check for ordinary declaration
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -39734,12 +42493,12 @@ cat >>conftest.$ac_ext <<_ACEOF
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "${ice_re_word}initgroups[    ]*\(" >/dev/null 2>&1; then
-  ice_cv_have_initgroups_decl=yes
+  $EGREP "${ice_re_word}ioctl[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_ioctl_decl=yes
 fi
 rm -f conftest*
 
-if test "$ice_cv_have_initgroups_decl" = yes; then
+if test "$ice_cv_have_ioctl_decl" = yes; then
        break
 fi
 # Check for "fixed" declaration like "getpid _PARAMS((int))"
@@ -39753,33 +42512,33 @@ cat >>conftest.$ac_ext <<_ACEOF
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "${ice_re_word}initgroups[    ]*$ice_re_params\(\(" >/dev/null 2>&1; then
-  ice_cv_have_initgroups_decl=yes
+  $EGREP "${ice_re_word}ioctl[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_ioctl_decl=yes
 fi
 rm -f conftest*
 
-if test "$ice_cv_have_initgroups_decl" = yes; then
+if test "$ice_cv_have_ioctl_decl" = yes; then
        break
 fi
 done
 
 fi
 
-echo "$as_me:$LINENO: result: $ice_cv_have_initgroups_decl" >&5
-echo "${ECHO_T}$ice_cv_have_initgroups_decl" >&6
-if test "$ice_cv_have_initgroups_decl" = yes; then
+echo "$as_me:$LINENO: result: $ice_cv_have_ioctl_decl" >&5
+echo "${ECHO_T}$ice_cv_have_ioctl_decl" >&6
+if test "$ice_cv_have_ioctl_decl" = yes; then
 
 cat >>confdefs.h <<_ACEOF
-#define HAVE_INITGROUPS_DECL 1
+#define HAVE_IOCTL_DECL 1
 _ACEOF
 
 fi
 fi
 
 
-ice_have_ioctl=no
+ice_have_isnormal=no
 
-for ac_func in ioctl
+for ac_func in isnormal
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -39876,21 +42635,21 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
- ice_have_ioctl=yes
+ ice_have_isnormal=yes
 fi
 done
 
-if test "${ice_have_ioctl}" = yes; then
-echo "$as_me:$LINENO: checking for ioctl declaration in sys/ioctl.h unistd.h libc.h" >&5
-echo $ECHO_N "checking for ioctl declaration in sys/ioctl.h unistd.h libc.h... $ECHO_C" >&6
-if test "${ice_cv_have_ioctl_decl+set}" = set; then
+if test "${ice_have_isnormal}" = yes; then
+echo "$as_me:$LINENO: checking for isnormal declaration in math.h" >&5
+echo $ECHO_N "checking for isnormal declaration in math.h... $ECHO_C" >&6
+if test "${ice_cv_have_isnormal_decl+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-ice_cv_have_ioctl_decl=no
+ice_cv_have_isnormal_decl=no
 ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
 ice_re_word='(^|[^a-zA-Z0-9_])'
-for header in sys/ioctl.h unistd.h libc.h; do
+for header in math.h; do
 # Check for ordinary declaration
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -39902,12 +42661,12 @@ cat >>conftest.$ac_ext <<_ACEOF
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "${ice_re_word}ioctl[         ]*\(" >/dev/null 2>&1; then
-  ice_cv_have_ioctl_decl=yes
+  $EGREP "${ice_re_word}isnormal[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_isnormal_decl=yes
 fi
 rm -f conftest*
 
-if test "$ice_cv_have_ioctl_decl" = yes; then
+if test "$ice_cv_have_isnormal_decl" = yes; then
        break
 fi
 # Check for "fixed" declaration like "getpid _PARAMS((int))"
@@ -39921,24 +42680,24 @@ cat >>conftest.$ac_ext <<_ACEOF
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "${ice_re_word}ioctl[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
-  ice_cv_have_ioctl_decl=yes
+  $EGREP "${ice_re_word}isnormal[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_isnormal_decl=yes
 fi
 rm -f conftest*
 
-if test "$ice_cv_have_ioctl_decl" = yes; then
+if test "$ice_cv_have_isnormal_decl" = yes; then
        break
 fi
 done
 
 fi
 
-echo "$as_me:$LINENO: result: $ice_cv_have_ioctl_decl" >&5
-echo "${ECHO_T}$ice_cv_have_ioctl_decl" >&6
-if test "$ice_cv_have_ioctl_decl" = yes; then
+echo "$as_me:$LINENO: result: $ice_cv_have_isnormal_decl" >&5
+echo "${ECHO_T}$ice_cv_have_isnormal_decl" >&6
+if test "$ice_cv_have_isnormal_decl" = yes; then
 
 cat >>confdefs.h <<_ACEOF
-#define HAVE_IOCTL_DECL 1
+#define HAVE_ISNORMAL_DECL 1
 _ACEOF
 
 fi
 done
 
 
-# Check whether --enable-largefile or --disable-largefile was given.
-if test "${enable_largefile+set}" = set; then
-  enableval="$enable_largefile"
-
-fi;
-if test "$enable_largefile" != no; then
-
-  echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
-echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
-if test "${ac_cv_sys_largefile_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_sys_largefile_CC=no
-     if test "$GCC" != yes; then
-       ac_save_CC=$CC
-       while :; do
-        # IRIX 6.2 and later do not support large files by default,
-        # so use the C compiler's -n32 option if that helps.
-        cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-        rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext
-        CC="$CC -n32"
-        rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_sys_largefile_CC=' -n32'; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext
-        break
-       done
-       CC=$ac_save_CC
-       rm -f conftest.$ac_ext
-    fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
-echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
-  if test "$ac_cv_sys_largefile_CC" != no; then
-    CC=$CC$ac_cv_sys_largefile_CC
-  fi
-
-  echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
-if test "${ac_cv_sys_file_offset_bits+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  while :; do
-  ac_cv_sys_file_offset_bits=no
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_sys_file_offset_bits=64; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  break
-done
-fi
-echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
-echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
-if test "$ac_cv_sys_file_offset_bits" != no; then
-
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
-_ACEOF
-
-fi
-rm -f conftest*
-  echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
-echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
-if test "${ac_cv_sys_large_files+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  while :; do
-  ac_cv_sys_large_files=no
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#define _LARGE_FILES 1
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"
-                        || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_sys_large_files=1; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  break
-done
-fi
-echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
-echo "${ECHO_T}$ac_cv_sys_large_files" >&6
-if test "$ac_cv_sys_large_files" != no; then
-
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
-
-fi
-rm -f conftest*
-fi
-
 
 echo "$as_me:$LINENO: checking disk device prefixes" >&5
 echo $ECHO_N "checking disk device prefixes... $ECHO_C" >&6
@@ -52864,31 +55259,28 @@ DOC_BUILD_DATE=`date '+%d-%m-%Y'`
 
 
 
-# Check whether --with-xsltproc or --without-xsltproc was given.
-if test "${with_xsltproc+set}" = set; then
-  withval="$with_xsltproc"
-   case "$withval" in
-        y | ye | yes)
-          USE_XSLTPROC=yes;;
-        n | no)
-          USE_XSLTPROC=no;;
-        *)
-          USE_XSLTPROC=yes;
-          XSLTPROC="$withval";;
-      esac
-
+# Check whether --with-built-manpages or --without-built-manpages was given.
+if test "${with_built_manpages+set}" = set; then
+  withval="$with_built_manpages"
+   BUILDMANPAGES=$withval;
 else
-   USE_XSLTPROC=maybe;
+   BUILDMANPAGES=yes;
 fi;
 
 
+if test "x$BUILDMANPAGES" = "xyes"; then
+  BUILD_MAN_PAGES_TRUE=
+  BUILD_MAN_PAGES_FALSE='#'
+else
+  BUILD_MAN_PAGES_TRUE='#'
+  BUILD_MAN_PAGES_FALSE=
+fi
 
-# This looks bad, but && and || have equal precedence in shells, so
-# actually it's all OK.
-if test "$USE_XSLTPROC" = "yes" || test "$USE_XSLTPROC" = "maybe" && \
-   test -z "$XSLTPROC"; then
-    # Extract the first word of "xsltproc", so it can be a program name with args.
-set dummy xsltproc; ac_word=$2
+
+for ac_prog in xsltproc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
 echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_path_XSLTPROC+set}" = set; then
@@ -52900,7 +55292,7 @@ else
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+for as_dir in $LOCSYSPATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
@@ -52926,22 +55318,24 @@ else
 echo "${ECHO_T}no" >&6
 fi
 
-    if test -n "$XSLTPROC"; then
-        USE_XSLTPROC=yes;
-    else
-        if test "$USE_XSLTPROC" = yes; then
-           { { echo "$as_me:$LINENO: error: can't find xsltproc, but running with --with-xsltproc." >&5
-echo "$as_me: error: can't find xsltproc, but running with --with-xsltproc." >&2;}
-   { (exit 1); exit 1; }; }
-        else
-           USE_XSLTPROC=no;
-        fi
-    fi
-fi
+  test -n "$XSLTPROC" && break
+done
+
+if test -z "$XSLTPROC"; then
+  USE_XSLTPROC=no
+  { echo "$as_me:$LINENO: WARNING: can't find xsltproc, xsltproc support is unavailable" >&5
+echo "$as_me: WARNING: can't find xsltproc, xsltproc support is unavailable" >&2;}
+else
+  USE_XSLTPROC=yes
 
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_XSLTPROC 1
+_ACEOF
 
+fi
 
-if test "$USE_XSLTPROC" = yes; then
+
+if test "x$USE_XSLTPROC" = "xyes"; then
   HAVE_XSLTPROC_TRUE=
   HAVE_XSLTPROC_FALSE='#'
 else
@@ -52950,7 +55344,71 @@ else
 fi
 
 
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ac_config_files="$ac_config_files amplot/amcat.awk amplot/amplot.sh amplot/Makefile changer-src/chg-manual.sh changer-src/chg-multi.sh changer-src/chg-mtx.sh changer-src/chg-chs.sh changer-src/chg-rth.pl changer-src/chg-chio.pl changer-src/chg-zd-mtx.sh changer-src/Makefile changer-src/chg-juke.sh changer-src/chg-rait.sh changer-src/chg-null.sh changer-src/chg-mcutil.sh changer-src/chg-disk.sh changer-src/chg-iomega.pl client-src/patch-system.sh client-src/Makefile dumper-src/gnutar.pl dumper-src/generic-dumper.pl dumper-src/Makefile common-src/versuff.c common-src/Makefile example/amanda.conf example/Makefile example/chg-mcutil.conf man/Makefile docs/Makefile recover-src/Makefile restore-src/Makefile server-src/amcheckdb.sh server-src/amcleanup.sh server-src/amdump.sh server-src/amfreetapes.sh server-src/amoverview.pl server-src/amrmtape.sh server-src/amtoc.pl server-src/amverify.sh server-src/Makefile server-src/amstatus.pl server-src/amverifyrun.sh server-src/amcrypt.sh server-src/amaespipe.sh tape-src/Makefile config/Makefile Makefile"
+#### Enforce amanda code cleanliness rules.
+#### Done here to allow configuration code to remain intact.
+if test "x$CC" = "xgcc"; then
+  AM_CFLAGS="$AM_CFLAGS -Wall"
+  $CC -v --help 2>&1 | $GREP -- '-Wextra ' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wextra"
+  else
+   AM_CFLAGS="$AM_CFLAGS -W"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wparentheses' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wparentheses"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wdeclaration-after-statement' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wdeclaration-after-statement"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wmissing-prototypes ' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wmissing-prototypes"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wstrict-prototypes ' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wstrict-prototypes"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wmissing-declarations ' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wmissing-declarations"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wformat' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wformat"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wsign-compare' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wsign-compare"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-fno-strict-aliasing' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -fno-strict-aliasing"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wfloat-equal' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wfloat-equal"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wold-style-definition' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wold-style-definition"
+  fi
+fi
+
+
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        ac_config_files="$ac_config_files amplot/amcat.awk amplot/amplot.sh amplot/Makefile amandad-src/Makefile changer-src/chg-manual.sh changer-src/chg-multi.sh changer-src/chg-mtx.sh changer-src/chg-chs.sh changer-src/chg-rth.pl changer-src/chg-chio.pl changer-src/chg-zd-mtx.sh changer-src/Makefile changer-src/chg-juke.sh changer-src/chg-rait.sh changer-src/chg-null.sh changer-src/chg-mcutil.sh changer-src/chg-disk.sh changer-src/chg-iomega.pl client-src/patch-system.sh client-src/Makefile dumper-src/gnutar.pl dumper-src/generic-dumper.pl dumper-src/Makefile common-src/versuff.c common-src/Makefile example/amanda.conf example/Makefile example/chg-mcutil.conf example/amanda-client.conf man/Makefile docs/Makefile recover-src/Makefile oldrecover-src/Makefile restore-src/Makefile server-src/amcheckdb.sh server-src/amcleanup.sh server-src/amdump.sh server-src/amfreetapes.sh server-src/amoverview.pl server-src/amrmtape.sh server-src/amtoc.pl server-src/amverify.sh server-src/Makefile server-src/amstatus.pl server-src/amverifyrun.sh server-src/amcrypt.sh server-src/amaespipe.sh server-src/amcrypt-ossl.sh server-src/amcrypt-ossl-asym.sh tape-src/Makefile config/Makefile Makefile"
+
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -53148,6 +55606,13 @@ echo "$as_me: error: conditional \"WANT_SSH_SECURITY\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
+if test -z "${BUILD_MAN_PAGES_TRUE}" && test -z "${BUILD_MAN_PAGES_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"BUILD_MAN_PAGES\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"BUILD_MAN_PAGES\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 if test -z "${HAVE_XSLTPROC_TRUE}" && test -z "${HAVE_XSLTPROC_FALSE}"; then
   { { echo "$as_me:$LINENO: error: conditional \"HAVE_XSLTPROC\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
@@ -53620,6 +56085,7 @@ do
   "amplot/amcat.awk" ) CONFIG_FILES="$CONFIG_FILES amplot/amcat.awk" ;;
   "amplot/amplot.sh" ) CONFIG_FILES="$CONFIG_FILES amplot/amplot.sh" ;;
   "amplot/Makefile" ) CONFIG_FILES="$CONFIG_FILES amplot/Makefile" ;;
+  "amandad-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES amandad-src/Makefile" ;;
   "changer-src/chg-manual.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-manual.sh" ;;
   "changer-src/chg-multi.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-multi.sh" ;;
   "changer-src/chg-mtx.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-mtx.sh" ;;
   "example/amanda.conf" ) CONFIG_FILES="$CONFIG_FILES example/amanda.conf" ;;
   "example/Makefile" ) CONFIG_FILES="$CONFIG_FILES example/Makefile" ;;
   "example/chg-mcutil.conf" ) CONFIG_FILES="$CONFIG_FILES example/chg-mcutil.conf" ;;
+  "example/amanda-client.conf" ) CONFIG_FILES="$CONFIG_FILES example/amanda-client.conf" ;;
   "man/Makefile" ) CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
   "docs/Makefile" ) CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;;
   "recover-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES recover-src/Makefile" ;;
+  "oldrecover-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES oldrecover-src/Makefile" ;;
   "restore-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES restore-src/Makefile" ;;
   "server-src/amcheckdb.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcheckdb.sh" ;;
   "server-src/amcleanup.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcleanup.sh" ;;
@@ -53661,6 +56129,8 @@ do
   "server-src/amverifyrun.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amverifyrun.sh" ;;
   "server-src/amcrypt.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcrypt.sh" ;;
   "server-src/amaespipe.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amaespipe.sh" ;;
+  "server-src/amcrypt-ossl.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcrypt-ossl.sh" ;;
+  "server-src/amcrypt-ossl-asym.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcrypt-ossl-asym.sh" ;;
   "tape-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES tape-src/Makefile" ;;
   "config/Makefile" ) CONFIG_FILES="$CONFIG_FILES config/Makefile" ;;
   "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
@@ -53793,6 +56263,26 @@ s,@VERSION_MINOR@,$VERSION_MINOR,;t t
 s,@VERSION_PATCH@,$VERSION_PATCH,;t t
 s,@VERSION_COMMENT@,$VERSION_COMMENT,;t t
 s,@VERSION_SUFFIX@,$VERSION_SUFFIX,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@GREP@,$GREP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@AMLINT@,$AMLINT,;t t
+s,@AMLINTFLAGS@,$AMLINTFLAGS,;t t
 s,@DUMPER_DIR@,$DUMPER_DIR,;t t
 s,@CONFIG_DIR@,$CONFIG_DIR,;t t
 s,@USE_VERSION_SUFFIXES@,$USE_VERSION_SUFFIXES,;t t
@@ -53813,25 +56303,8 @@ s,@AMANDA_TMPDIR@,$AMANDA_TMPDIR,;t t
 s,@AMANDA_DBGDIR@,$AMANDA_DBGDIR,;t t
 s,@AMANDA_DEBUG_DAYS@,$AMANDA_DEBUG_DAYS,;t t
 s,@SERVICE_SUFFIX@,$SERVICE_SUFFIX,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@DEPDIR@,$DEPDIR,;t t
-s,@am__include@,$am__include,;t t
-s,@am__quote@,$am__quote,;t t
-s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
-s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
-s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
-s,@CCDEPMODE@,$CCDEPMODE,;t t
-s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
-s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
 s,@MT_FILE_FLAG@,$MT_FILE_FLAG,;t t
 s,@CPP@,$CPP,;t t
-s,@EGREP@,$EGREP,;t t
 s,@AR@,$AR,;t t
 s,@AWK_VAR_ASSIGNMENT_OPT@,$AWK_VAR_ASSIGNMENT_OPT,;t t
 s,@YACC@,$YACC,;t t
@@ -53840,7 +56313,6 @@ s,@COMPRESS@,$COMPRESS,;t t
 s,@DD@,$DD,;t t
 s,@GETCONF@,$GETCONF,;t t
 s,@GNUPLOT@,$GNUPLOT,;t t
-s,@GREP@,$GREP,;t t
 s,@GNUTAR@,$GNUTAR,;t t
 s,@SAMBA_CLIENT@,$SAMBA_CLIENT,;t t
 s,@GZIP@,$GZIP,;t t
@@ -53919,9 +56391,12 @@ s,@WANT_SSH_SECURITY_FALSE@,$WANT_SSH_SECURITY_FALSE,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
 s,@LTALLOCA@,$LTALLOCA,;t t
 s,@DOC_BUILD_DATE@,$DOC_BUILD_DATE,;t t
+s,@BUILD_MAN_PAGES_TRUE@,$BUILD_MAN_PAGES_TRUE,;t t
+s,@BUILD_MAN_PAGES_FALSE@,$BUILD_MAN_PAGES_FALSE,;t t
 s,@XSLTPROC@,$XSLTPROC,;t t
 s,@HAVE_XSLTPROC_TRUE@,$HAVE_XSLTPROC_TRUE,;t t
 s,@HAVE_XSLTPROC_FALSE@,$HAVE_XSLTPROC_FALSE,;t t
+s,@AM_CFLAGS@,$AM_CFLAGS,;t t
 CEOF
 
 _ACEOF
index 2128f16e0b31056c87c0fa580a71706c03cd0acf..3330438c245c0f387f7221fbc35e5d1bf2602dcc 100644 (file)
@@ -1,4 +1,3 @@
-dnl Process this file with autoconf to produce a configure script.
 
 AC_INIT
 AC_CONFIG_SRCDIR([common-src/amanda.h])
@@ -14,7 +13,7 @@ AC_DEFINE_UNQUOTED(CONFIGURE_COMMAND,"$CONFIGURE_COMMAND",
          [Saves the original ./configure command line arguments])
 AC_SUBST(CONFIGURE_COMMAND)
 
-AM_INIT_AUTOMAKE(amanda, 2.5.0p2)
+AM_INIT_AUTOMAKE(amanda, 2.5.1)
 AM_CONFIG_HEADER(config/config.h)
 
 AC_PREREQ(2.57)                dnl Minimum Autoconf version required.
@@ -55,9 +54,9 @@ AC_SUBST(VERSION_COMMENT)
 AC_SUBST(VERSION_SUFFIX)
 
 dnl
-dnl runtime and compile time
+dnl runtime and compile time paths
 dnl
-SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
+SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/opt/SUNWspro/bin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
 LOCPATH=`(
     test "x$prefix" = xNONE && prefix=$ac_default_prefix
     test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
@@ -66,17 +65,107 @@ LOCPATH=`(
 SYSLOCPATH="$SYSPATH:$LOCPATH"
 LOCSYSPATH="$LOCPATH:$SYSPATH"
 
+dnl
+dnl Set up compiler location, basic CFLAGS, and include locations
+dnl and library locations before we start checking the system
+dnl configuration in more detail...
+dnl
+
 AC_ARG_WITH(cflags,
     [  --with-cflags=CFLAGS   arguments to the c compiler (-Wall, -g, etc)],
     [
        case "$withval" in
        "" | y | ye | yes | n | no)
-           AC_MSG_ERROR([*** You must supply an argument to the --with-includes option.])
+           AC_MSG_ERROR([*** You must supply an argument to the --with-cflags option.])
            ;;
        esac
        CFLAGS="$withval"
     ])
 
+CFLAGS="-D_GNU_SOURCE $CFLAGS"
+
+AC_PROG_CC
+AC_OBJEXT
+AC_EXEEXT
+AC_SYS_LARGEFILE
+
+dnl
+dnl Process tool locations for tools we need right away to configure.
+dnl
+AC_PATH_PROGS(GREP,grep,,$LOCSYSPATH)
+if test -z "$GREP"; then
+    GREP=grep
+fi
+AC_DEFINE_UNQUOTED(GREP,"$GREP",[Define the location of the grep program. ])
+AC_PATH_PROGS(EGREP,egrep,,$LOCSYSPATH)
+
+AC_PATH_PROGS(AMLINT,lint,,/opt/SUNWspro/bin:$SYSLOCPATH)
+if test ! -z "$AMLINT"; then
+  $AMLINT -flags | $GREP -- '-errfmt=' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AMLINTFLAGS="-n -s -u -m -x"
+    AMLINTFLAGS="$AMLINTFLAGS -errchk=%all"
+    AMLINTFLAGS="$AMLINTFLAGS -errfmt=macro"
+    AMLINTFLAGS="$AMLINTFLAGS -errhdr=no%/usr/include"
+    AMLINTFLAGS="$AMLINTFLAGS -errhdr=%user"
+    AMLINTFLAGS="$AMLINTFLAGS -errsecurity=extended"
+    AMLINTFLAGS="$AMLINTFLAGS -errtags=yes"
+    AMLINTFLAGS="$AMLINTFLAGS -Ncheck=%all"
+    AMLINTFLAGS="$AMLINTFLAGS -Nlevel=2"
+    AMLINTFLAGS="$AMLINTFLAGS -erroff=E_ASGN_NEVER_USED"
+    AMLINTFLAGS="$AMLINTFLAGS,E_ASGN_RESET"
+    AMLINTFLAGS="$AMLINTFLAGS,E_CAST_INT_CONST_TO_SMALL_INT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_CAST_INT_TO_SMALL_INT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_CAST_UINT_TO_SIGNED_INT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_CONSTANT_CONDITION"
+    AMLINTFLAGS="$AMLINTFLAGS,E_ENUM_UNUSE"
+    AMLINTFLAGS="$AMLINTFLAGS,E_EXPR_NULL_EFFECT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_FUNC_RET_ALWAYS_IGNOR"
+    AMLINTFLAGS="$AMLINTFLAGS,E_FUNC_RET_MAYBE_IGNORED"
+    AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK0"
+    AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK1"
+    AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK2"
+    AMLINTFLAGS="$AMLINTFLAGS,E_INCL_MNUSD"
+    AMLINTFLAGS="$AMLINTFLAGS,E_INCL_NUSD"
+    AMLINTFLAGS="$AMLINTFLAGS,E_MCR_NODIFF"
+    AMLINTFLAGS="$AMLINTFLAGS,E_NAME_MULTIPLY_DEF"
+    AMLINTFLAGS="$AMLINTFLAGS,E_P_REF_NULL_PSBL"
+    AMLINTFLAGS="$AMLINTFLAGS,E_P_REF_SUSP"
+    AMLINTFLAGS="$AMLINTFLAGS,E_PTRDIFF_OVERFLOW"
+    AMLINTFLAGS="$AMLINTFLAGS,E_P_USE_NULL_PSBL"
+    AMLINTFLAGS="$AMLINTFLAGS,E_P_USE_SUSP"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_ACCESS_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CHDIR_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CHMOD_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CREAT_WITHOUT_EXCL"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_EXEC_PATH"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_EXEC_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_FOPEN_MODE"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_GETENV_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_MKDIR_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_PRINTF_VAR_FMT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_RAND_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SCANF_VAR_FMT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SELECT_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SHELL_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_STRNCPY_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_UMASK_WARN"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SEC_USE_AFTER_STAT"
+    AMLINTFLAGS="$AMLINTFLAGS,E_SIGN_EXTENSION_PSBL"
+    AMLINTFLAGS="$AMLINTFLAGS,E_TYPEDEF_UNUSE"
+    AMLINTFLAGS="$AMLINTFLAGS,E_UNCAL_F"
+  else
+    AMLINTFLAGS=""
+  fi
+else
+  AC_PATH_PROGS(AMLINT,splint,,$SYSLOCPATH)
+  if test ! -z "$AMLINT"; then
+    AMLINT="splint"
+  fi
+  AMLINTFLAGS='+show-scan +unixlib -weak -globs +usedef +usereleased +impouts -paramimptemp -varuse -warnposix -redef -preproc -fixedformalarray -retval -unrecog -usevarargs -formatcode'
+fi
+AC_SUBST(AMLINTFLAGS)
+
 AC_ARG_WITH(includes,
     [  --with-includes=DIR    site header files for readline, etc in DIR],
     [
@@ -124,6 +213,10 @@ if test "$LIBRARY_DIRS"; then
        done
 fi
 
+dnl
+dnl Process configuration flags
+dnl
+
 AC_ARG_WITH(dumperdir,
     [  --with-dumperdir=DIR   where we install the dumpers [[EPREFIX/dumper]]],
     [
@@ -474,8 +567,8 @@ AC_ARG_WITH(tape-device,
            dnl bytes are returned upon reading to the next tape mark,
            dnl instead of returning an error.  Look for devices that have
            dnl a 'b' in their name.
-           tape_dev=null:
-           nr_tape_dev=null:
+           tape_dev=
+           nr_tape_dev=
            if test -d /dev/rmt; then
 
                dnl See if we can find two devices, one being the norewind
@@ -509,13 +602,11 @@ AC_ARG_WITH(tape-device,
     ]
 )
 
-if test -z "$DEFAULT_TAPE_DEVICE"; then
-    DEFAULT_TAPE_DEVICE=/dev/null
+if test ! -z "$DEFAULT_TAPE_DEVICE"; then
+    AC_DEFINE_UNQUOTED(DEFAULT_TAPE_DEVICE,"$DEFAULT_TAPE_DEVICE",[This is the default no-rewinding tape device. ])
+    AC_SUBST(DEFAULT_TAPE_DEVICE)
 fi
 
-AC_DEFINE_UNQUOTED(DEFAULT_TAPE_DEVICE,"$DEFAULT_TAPE_DEVICE",[This is the default no-rewinding tape device. ])
-AC_SUBST(DEFAULT_TAPE_DEVICE)
-
 AC_ARG_WITH(ftape-raw-device,
     [  --with-ftape-rawdevice=ARG raw device on tape server HOST's if using Linux ftape >=3.04d],
     [
@@ -617,6 +708,29 @@ y |  ye | yes) AC_DEFINE(HAVE_BROKEN_FSF,1,[Define this if issuing a fsf on a ta
   ;;
 esac
 
+AC_ARG_WITH(reuseports,
+    [  --without-reuseaddr    Don't closed network connections to be reused until full timeout period.],
+    [ case "$withval" in
+        y | ye | yes)
+          REUSEADDR=no;;
+        n | no)
+          REUSEADDR=yes;;
+        *)
+          REUSEADDR=no;;
+      esac
+    ],
+    [ REUSEADDR=yes; ])
+case "$REUSEADDR" in
+n | no) :
+    ;;
+y |  ye | yes)
+    AC_DEFINE(USE_REUSEADDR,1,[Define to set SO_REUSEADDR on network connections.])
+    ;;
+*)
+    AC_MSG_ERROR([*** You must not supply an argument to --with-reuseports option.])
+    ;;
+esac
+
 AC_ARG_WITH(gnutar,
     [  --with-gnutar[[=PROG]]      use PROG as GNU tar executable [[default: looks for one]]],
     [
@@ -723,8 +837,15 @@ n | no)
     DBMALLOCLIBS=""
     ;;
 *) 
-    DBMALLOCCFLAGS="-I$DBMALLOC -DUSE_DBMALLOC"
-    DBMALLOCLIBS="-L$DBMALLOC -ldbmalloc"
+    AC_CHECK_LIB(dbmalloc,malloc)
+    if test "x$ac_cv_lib_dbmalloc_malloc" != "xyes"; then
+      AC_MSG_WARN([*** dbmalloc library not found - no malloc debugging support!])
+      DBMALLOCCFLAGS=""
+      DBMALLOCLIBS=""
+    else
+      DBMALLOCCFLAGS="-I$DBMALLOC -DUSE_DBMALLOC"
+      DBMALLOCLIBS="-L$DBMALLOC -ldbmalloc"
+    fi
     ;;
 esac
 
@@ -827,6 +948,34 @@ y |  ye | yes) AC_DEFINE(SSH_SECURITY,1,[Define if SSH transport should be enabl
   ;;
 esac
 
+AC_ARG_WITH(bsdtcp-security,
+    [  --with-bsdtcp-security use tcp as a transport],
+    BSDTCP_SECURITY=$withval,
+    : ${BSDTCP_SECURITY=yes}
+)
+case "$BSDTCP_SECURITY" in
+n | no) : ;;
+y |  ye | yes) AC_DEFINE(BSDTCP_SECURITY,1,[Define if BSDTCP transport should be enabled. ])
+              BSDTCP_SECURITY_SET=true
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument the to --with-bsdtcp-security option.])
+  ;;
+esac
+
+AC_ARG_WITH(bsdudp-security,
+    [  --with-bsdudp-security use tcp as a transport],
+    BSDUDP_SECURITY=$withval,
+    : ${BSDUDP_SECURITY=yes}
+)
+case "$BSDUDP_SECURITY" in
+n | no) : ;;
+y |  ye | yes) AC_DEFINE(BSDUDP_SECURITY,1,[Define if BSDUDP transport should be enabled. ])
+              BSDUDP_SECURITY_SET=true
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument the to --with-bsdudp-security option.])
+  ;;
+esac
+
 AC_ARG_WITH(server-principal,
     [    --with-server-principal=ARG    server host principal  [["amanda"]]],
     [
@@ -968,17 +1117,23 @@ AC_MSG_CHECKING(for Kerberos V)
 KRB5_DIR_FOUND=""
 KRB5_CFLAGS=""
 for dir in $KRB5_SPOTS; do
-    k5libdir=${dir}/lib
+  for lib in lib lib64; do
+    k5libdir=${dir}/${lib}
     if test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libgssapi_krb5.a -a -f ${k5libdir}/libcom_err.a; then
-       if test -f ${k5libdir}/libcrypto.a; then
-           K5CRYPTO=${k5libdir}/libcrypto.a
-       elif test -f ${k5libdir}/libk5crypto.a; then
+       if test -f ${k5libdir}/libk5crypto.a; then
            K5CRYPTO=${k5libdir}/libk5crypto.a
+       elif test -f ${k5libdir}/libcrypto.a; then
+           K5CRYPTO=${k5libdir}/libcrypto.a
        else
            K5CRYPTO=""
        fi
+       if test -f ${k5libdir}/libkrb5support.a; then
+           K5SUPPORT=${k5libdir}/libkrb5support.a
+       else
+           K5SUPPORT=""
+       fi
        KRB5_DIR_FOUND=$dir
-       KRB5LIBS="${k5libdir}/libgssapi_krb5.a ${k5libdir}/libkrb5.a $K5CRYPTO ${k5libdir}/libcom_err.a"
+       KRB5LIBS="${k5libdir}/libgssapi_krb5.a ${k5libdir}/libkrb5.a $K5CRYPTO $K5SUPPORT ${k5libdir}/libcom_err.a"
        KRB5CFLAGS=""
        break
     elif test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libasn1.a -a -f ${k5libdir}/libgssapi.a; then
@@ -987,6 +1142,7 @@ for dir in $KRB5_SPOTS; do
        KRB5_CFLAGS="-DKRB5_HEIMDAL_INCLUDES"
        break
     fi
+  done
 done
 
 if test "$KRB5_DIR_FOUND"; then
@@ -1007,6 +1163,7 @@ if test "$KRB5_DIR_FOUND"; then
        if test "$KRB5_CFLAGS" ; then
                KRB5INCLUDES="$KRB5INCLUDES $KRB5_CFLAGS"
        fi
+        AC_CHECK_LIB(krb5support,main)
        KRB5LDFLAGS=-L$k5libdir
        break
 fi
@@ -1016,12 +1173,32 @@ if test "x$KRB5LDFLAGS" = "x" ; then
 fi
 
 
-AC_ARG_WITH(portrange,
-    [  --with-portrange=low,high     bind unreserved TCP server sockets to ports within this range [[unlimited]]],
+AC_ARG_WITH(low-tcpportrange,
+    [  --with-low-tcpportrange=low,high     bind reserved TCP server sockets to ports within this range [unlimited] (mainly for amrecover)],
     [
-       TCPPORTRANGE="$withval"
+       LOW_TCPPORTRANGE="$withval"
     ]
 )
+if test x"${LOW_TCPPORTRANGE+set}" = x"set"; then
+    if test x`echo "$LOW_TCPPORTRANGE" | sed 's/[[0-9]][[0-9]]*,[[0-9]][[0-9]]*//'` != x""; then
+       AC_MSG_ERROR([*** --with-low-tcpportrange requires two comma-separated positive numbers])
+    fi
+    min_low_tcp_port=`echo "$LOW_TCPPORTRANGE" | sed 's/,.*//'`
+    max_low_tcp_port=`echo "$LOW_TCPPORTRANGE" | sed 's/.*,//'`
+    if test $min_low_tcp_port -gt $max_low_tcp_port; then
+       AC_MSG_ERROR([*** the second TCP port number must be greater than the first in --with-low-tcpportrange])
+    fi
+    if test $min_low_tcp_port -lt 512; then
+       AC_MSG_WARN([*** the low TCP port range should be 512 or greater in --with-low-tcpportrange])
+    fi
+    if test $max_low_tcp_port -ge 1024; then
+       AC_MSG_WARN([*** the low TCP port range should be less than 1024 in --with-low-tcpportrange])
+    fi
+    AC_DEFINE_UNQUOTED(LOW_TCPPORTRANGE,$LOW_TCPPORTRANGE,[A comma-separated list of two integers, determining the minimum and
+   maximum reserved TCP port numbers sockets should be bound to. (mainly for amrecover) ])
+fi
+
 AC_ARG_WITH(tcpportrange,
     [  --with-tcpportrange=low,high  bind unreserved TCP server sockets to ports within this range [[unlimited]]],
     [
@@ -1238,10 +1415,6 @@ AC_DEFINE_UNQUOTED(KAMANDA_SERVICE_NAME, "$KAMANDA_SERVICE_NAME", [The name for
     AC_DEFINE_UNQUOTED(mandir,"$tmp",[Directory in which man-pages should be installed])
 )
 
-AC_PROG_CC
-AC_OBJEXT
-AC_EXEEXT
-
 dnl Set the order of dump programs to look for.  Finding the proper file
 dnl system dumping program is problematic.  Some systems, notably HP-UX
 dnl and AIX, have both the backup and dump programs.  HP-UX can't use the
@@ -1294,6 +1467,8 @@ case "$target" in
                        ;;
   *-pc-linux-*)
                        ;;
+  *-redhat-linux-*)
+                       ;;
   x86_64-*-linux-*)
                        ;;
   alpha*-*-linux-*)
@@ -1407,7 +1582,6 @@ if test -z "$CAT"; then
 fi
 AC_PATH_PROGS(COMPRESS,compress,,$LOCSYSPATH)
 AC_PATH_PROGS(DD,dd,,$LOCSYSPATH)
-AC_PATH_PROGS(EGREP,egrep,,$LOCSYSPATH)
 AC_PATH_PROGS(GETCONF,getconf,,$SYSPATH)
 
 AC_PATH_PROGS(GNUPLOT,gnuplot,,$LOCSYSPATH)
@@ -1416,12 +1590,6 @@ if test -z "$GNUPLOT"; then
     AC_MSG_WARN([*** You do not have gnuplot.  Amplot will not be installed.])
 fi
 
-AC_PATH_PROGS(GREP,grep,,$LOCSYSPATH)
-if test -z "$GREP"; then
-    GREP=grep
-fi
-AC_DEFINE_UNQUOTED(GREP,"$GREP",[Define the location of the grep program. ])
-
 AC_PATH_PROGS(GNUTAR,gtar gnutar tar,,$LOCSYSPATH)
 if test ! -z "$GNUTAR"; then
   case "`\"$GNUTAR\" --version 2>&1`" in
@@ -1755,8 +1923,10 @@ AC_CACHE_CHECK(
 if test "x$need_resetofs" = xyes; then
     AC_DEFINE(NEED_RESETOFS,1,[Define if we have to reset tape offsets when reacing 2GB. ])
 fi
+
+
 CFLAGS="$amanda_cv_LFS_CFLAGS $CFLAGS"
-CPPFLAGS="$amanda_cv_LFS_CFLAGS $CPPFLAGS"
+CPPFLAGS="$amanda_cv_LFS_CPPFLAGS $CPPFLAGS"
 LDFLAGS="$amanda_cv_LFS_LDFLAGS $LDFLAGS"
 LIBS="$amanda_cv_LFS_LIBS $LIBS"
 
@@ -1765,6 +1935,9 @@ AC_CHECK_SIZEOF(long)
 AC_CHECK_SIZEOF(long long)
 AC_CHECK_SIZEOF(intmax_t)
 AC_CHECK_SIZEOF(off_t)
+AC_CHECK_SIZEOF(size_t)
+AC_CHECK_SIZEOF(ssize_t)
+AC_CHECK_SIZEOF(time_t)
 
 AM_PROG_LIBTOOL
 AC_SUBST(LIBTOOL_DEPS)
@@ -1782,6 +1955,9 @@ AC_TYPE_SIGNAL
 AC_STRUCT_TM
 AM_PROG_LEX
 
+dnl From here on we need to know about STDC_HEADERS
+AC_HEADER_STDC
+
 dnl AC_CHECK_TYPE does not work for socklen_t because it does not look
 dnl in <sys/socket.h>, so this is a variant that adds another header.
 AC_DEFUN([AMANDA_CHECK_TYPE],
@@ -1803,9 +1979,9 @@ if test "x$ac_cv_type_$1" = xno; then
 fi
 ])
 AMANDA_CHECK_TYPE(socklen_t, int, sys/socket.h)
+AMANDA_CHECK_TYPE(sa_family_t, unsigned short, sys/socket.h)
 
 dnl Checks for header files.
-AC_HEADER_STDC
 AC_HEADER_DIRENT
 CF_WAIT
 CF_WAIT_INT
@@ -1824,8 +2000,10 @@ AC_CHECK_HEADERS(\
        grp.h \
        history.h \
        libc.h \
+       libgen.h \
        limits.h \
        linux/zftape.h \
+       math.h \
        mntent.h \
        mnttab.h \
        ndbm.h \
@@ -1836,6 +2014,7 @@ AC_CHECK_HEADERS(\
        readline/readline.h \
        scsi/sg.h \
        scsi/scsi_ioctl.h \
+       stdarg.h \
        stdlib.h \
        string.h \
        strings.h \
@@ -2138,10 +2317,11 @@ fi
 if test "x$ac_cv_lib_termcap_tgetent" = xyes ||
    test "x$ac_cv_lib_curses_tgetent" = xyes ||
    test "x$ac_cv_lib_ncurses_tgetent" = xyes; then
-    AC_CHECK_LIB(readline,readline,
-       READLINE_LIBS="-lreadline"; AC_SUBST(READLINE_LIBS)
-    )
-    if test "x$ac_cv_lib_readline_readline" != xyes; then
+    AC_CHECK_LIB(readline,readline)
+    if test "x$ac_cv_lib_readline_readline" = xyes; then
+       READLINE_LIBS="-lreadline"
+       AC_SUBST(READLINE_LIBS)
+    else
        AC_MSG_WARN([*** No readline library, no history and command line editing in amrecover!])
     fi
 else
@@ -2545,6 +2725,9 @@ ICE_CHECK_DECL(accept,sys/types.h sys/socket.h)
 AC_FUNC_ALLOCA
 AC_CHECK_FUNCS(atexit)
 ICE_CHECK_DECL(atof,stdlib.h)
+ICE_CHECK_DECL(atoi,stdlib.h)
+ICE_CHECK_DECL(atol,stdlib.h)
+ICE_CHECK_DECL(atoll,stdlib.h)
 AC_CHECK_FUNCS(basename)
 ICE_CHECK_DECL(bind,sys/types.h sys/socket.h)
 ICE_CHECK_DECL(bcopy,string.h strings.h stdlib.h)
@@ -2578,6 +2761,7 @@ AMANDA_FUNC_GETTIMEOFDAY_ARGS
 AC_CHECK_FUNCS(getvfsent initgroups isascii)
 ICE_CHECK_DECL(initgroups,grp.h sys/types.h unistd.h libc.h)
 ICE_CHECK_DECL(ioctl,sys/ioctl.h unistd.h libc.h)
+ICE_CHECK_DECL(isnormal,math.h)
 ICE_CHECK_DECL(listen,sys/types.h sys/socket.h)
 ICE_CHECK_DECL(lstat,sys/types.h sys/stat.h)
 ICE_CHECK_DECL(malloc,stdlib.h)
@@ -2703,7 +2887,6 @@ ICE_CHECK_DECL(strcasecmp,string.h strings.h)
 
 AC_CHECK_FUNCS(fnmatch)
 
-AC_SYS_LARGEFILE
 
 dnl disk device prefixes
 AC_MSG_CHECKING(disk device prefixes)
@@ -2935,44 +3118,91 @@ AC_SUBST(LTALLOCA)
 DOC_BUILD_DATE=`date '+%d-%m-%Y'`
 AC_SUBST(DOC_BUILD_DATE)
 
-AC_ARG_WITH(xsltproc,
+AC_ARG_WITH(built-manpages,
     [  --without-built-manpages Do not build manpages from XML source.],
-    [ case "$withval" in
-        y | ye | yes)
-          USE_XSLTPROC=yes;;
-        n | no)
-          USE_XSLTPROC=no;;
-        *)
-          USE_XSLTPROC=yes;
-          XSLTPROC="$withval";;
-      esac
-    ],
-    [ USE_XSLTPROC=maybe; ])
+    [ BUILDMANPAGES=$withval; ],
+    [ BUILDMANPAGES=yes; ])
+AM_CONDITIONAL(BUILD_MAN_PAGES, test "x$BUILDMANPAGES" = "xyes")
+
+AC_PATH_PROGS(XSLTPROC,xsltproc,,$LOCSYSPATH)
+if test -z "$XSLTPROC"; then
+  USE_XSLTPROC=no
+  AC_MSG_WARN([can't find xsltproc, xsltproc support is unavailable])
+else
+  USE_XSLTPROC=yes
+  AC_DEFINE(HAVE_XSLTPROC,1,[xslt is available to generate man pages])
+fi
+AM_CONDITIONAL(HAVE_XSLTPROC, test "x$USE_XSLTPROC" = "xyes")
+
+#### Enforce amanda code cleanliness rules.
+#### Done here to allow configuration code to remain intact.
+if test "x$CC" = "xgcc"; then
+  AM_CFLAGS="$AM_CFLAGS -Wall"
+  $CC -v --help 2>&1 | $GREP -- '-Wextra ' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wextra"
+  else
+   AM_CFLAGS="$AM_CFLAGS -W"
+  fi
 
-AC_DEFUN([AC_PATH_XSLTPROC], [AC_PATH_PROG(XSLTPROC, xsltproc)])
+  $CC -v --help 2>&1 | $GREP -- '-Wparentheses' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wparentheses"
+  fi
 
-# This looks bad, but && and || have equal precedence in shells, so
-# actually it's all OK.
-if test "$USE_XSLTPROC" = "yes" || test "$USE_XSLTPROC" = "maybe" && \
-   test -z "$XSLTPROC"; then
-    AC_PATH_XSLTPROC
-    if test -n "$XSLTPROC"; then
-        USE_XSLTPROC=yes;
-    else
-        if test "$USE_XSLTPROC" = yes; then
-           AC_MSG_ERROR([can't find xsltproc, but running with --with-xsltproc.])
-        else
-           USE_XSLTPROC=no;
-        fi
-    fi
-fi
+  $CC -v --help 2>&1 | $GREP -- '-Wdeclaration-after-statement' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wdeclaration-after-statement"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wmissing-prototypes ' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wmissing-prototypes"
+  fi
 
-AM_CONDITIONAL(HAVE_XSLTPROC, test "$USE_XSLTPROC" = yes)
+  $CC -v --help 2>&1 | $GREP -- '-Wstrict-prototypes ' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wstrict-prototypes"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wmissing-declarations ' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wmissing-declarations"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wformat' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wformat"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wsign-compare' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wsign-compare"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-fno-strict-aliasing' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -fno-strict-aliasing"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wfloat-equal' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wfloat-equal"
+  fi
+
+  $CC -v --help 2>&1 | $GREP -- '-Wold-style-definition' 2>&1 > /dev/null
+  if test $? -eq 0; then
+    AM_CFLAGS="$AM_CFLAGS -Wold-style-definition"
+  fi
+fi
+AC_SUBST(AM_CFLAGS)
 
 AC_CONFIG_FILES([\
        amplot/amcat.awk                amplot/amplot.sh                \
        amplot/Makefile                                                 \
                                                                        \
+       amandad-src/Makefile                                            \
+                                                                       \
        changer-src/chg-manual.sh       changer-src/chg-multi.sh        \
        changer-src/chg-mtx.sh          changer-src/chg-chs.sh          \
        changer-src/chg-rth.pl          changer-src/chg-chio.pl         \
@@ -2989,13 +3219,15 @@ AC_CONFIG_FILES([\
        common-src/versuff.c            common-src/Makefile             \
                                                                        \
        example/amanda.conf             example/Makefile                \
-       example/chg-mcutil.conf                                         \
+       example/chg-mcutil.conf         example/amanda-client.conf      \
                                                                        \
        man/Makefile                                                    \
                                                                        \
        docs/Makefile                                                   \
                                                                        \
        recover-src/Makefile                                            \
+
+       oldrecover-src/Makefile                                         \
                                                                        \
        restore-src/Makefile                                            \
                                                                        \
@@ -3005,9 +3237,10 @@ AC_CONFIG_FILES([\
        server-src/amtoc.pl             server-src/amverify.sh          \
        server-src/Makefile             server-src/amstatus.pl          \
        server-src/amverifyrun.sh       server-src/amcrypt.sh           \
-       server-src/amaespipe.sh                                         \
-                                                                       \
+       server-src/amaespipe.sh         server-src/amcrypt-ossl.sh      \
+       server-src/amcrypt-ossl-asym.sh                                 \
        tape-src/Makefile                                               \
                                                                        \
        config/Makefile                 Makefile])
+
 AC_OUTPUT
index 9efbd5748b1bf5a52e36321e4369a36d282b8925..314321247778a8df48be070fd6701c45f2edaabd 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/local/bin/perl
 # ========================================================================
-# @(#) $Id: set_prod_link.pl,v 1.2 1999/11/02 21:30:10 oliva Exp $
+# @(#) $Id: set_prod_link.pl,v 1.3 2006/05/25 01:47:13 johnfranks Exp $
 # ------------------------------------------------------------------------
 # $Source: /cvsroot/amanda/amanda/contrib/set_prod_link.pl,v $
 # ------------------------------------------------------------------------
 # History:
 #
 # $Log: set_prod_link.pl,v $
+# Revision 1.3  2006/05/25 01:47:13  johnfranks
+# Allow spaces and arbitrary binary characters in file names
+# and configuration files.
+#
+# 64-bit / type portability clean code.
+#
+# Add 'make lint' options to appropriate Makefiles.
+#
+# Fully lint clean code using Sun's lint, and splint code checkers.
+#
+# Various bug fixes that have not been pushed.
+#
+# Modified Files:
+#      Modified most of the files...
+#
 # Revision 1.2  1999/11/02 21:30:10  oliva
 # * contrib/set_prod_link.pl: Create the links for a configuration
 # with --with-suffix.
index ba866da3d8c58eceb710134b0c4609f03732cc34..482497ea08406b4a608226c47a8c4125f746390f 100644 (file)
@@ -54,6 +54,11 @@ Sam Johnston <samj@samj.net> reported problems with an Amanda server on which
 bastille was used with the "restrict system resources" option.  See bug
 118616 in the Debian bug tracking system for more information.
 
+If you choose to use the SSH authentication method and associated transport,
+please be aware that there may be problems if /usr/libamanda/dumper is suid.
+You can fix this on your server with chmod u-s /usr/lib/amanda/dumper, or
+investigate dpkg-statoverride.
+
 Concerns have been expressed about the reliability of 'dump' as a backup tool
 on live Linux systems.  Nothing can guarantee a consistent and meaningful 
 backup of a live filesystem under all circumstances.  The tar utility is 
index 935b1f61ea341287596030435ed674ffb2755abc..9845b18481c52e1b5e49414519ac0c686dc356cf 100644 (file)
@@ -1,10 +1,16 @@
-amanda (1:2.5.0p2-2.1) unstable; urgency=medium
-
-  * Non-maintainer upload.
-  * Added Replaces:amanda-client to amanda-common control information; thanks
-    to Bill Alombert (closes: #391026).
-
- -- martin f. krafft <madduck@debian.org>  Sat,  7 Oct 2006 13:11:08 +0200
+amanda (1:2.5.1-1) unstable; urgency=low
+
+  * new upstream version, closes: #361716
+  * incorporate patch from NMU by Martin Krafft based on a suggestion by
+    Bill Alombert (thanks!), accounting for the fact that we now deliver
+    content in amanda-common that used to be in amanda-client, closes: #391026
+  * updated ja.po from Hideki Yamane, closes: #392153
+  * change debconf notification about old/rare conflict with amandadates file
+    to be of type 'error' instead of 'note', closes: #388707
+  * add --with-ssh-security to configure and note issue with suid of dumper
+    to README.Debian, closes: #365306
+
+ -- Bdale Garbee <bdale@gag.com>  Wed, 18 Oct 2006 01:02:23 -0600
 
 amanda (1:2.5.0p2-2) unstable; urgency=low
 
index 1e03969de6bbdb4601d3ca2011dd724fc9554998..aa8d7d643df13c6047f8ddb955eec934d69f4471 100644 (file)
@@ -15,7 +15,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: amanda_1:2.4.5-1\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: 2005-07-19 18:48+0300\n"
 "Last-Translator: Ossama M. Khayat <okhayat@yahoo.com>\n"
 "Language-Team: Arabic <debian-l10n-arabic@lists.debian.org>\n"
@@ -24,14 +24,14 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.9.1\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 #, fuzzy
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "الرجاء دمج /var/lib/amandates و /var/lib/amanda/amandates."
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index ea26fde60f5963512640ee92424b6de635cb5dbf..f479ae634eda9cdd76404fd74a58510e6c5fd1af 100644 (file)
@@ -15,7 +15,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: amanda\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: 2006-06-04 17:06+0200\n"
 "Last-Translator: Miroslav Kure <kurem@debian.cz>\n"
 "Language-Team: Czech <debian-l10n-czech@lists.debian.org>\n"
@@ -23,13 +23,13 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "Spojte prosím /var/lib/amandates a /var/lib/amanda/amandates"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index dc52d6096dfff02d1c217833ae4378c115a65114..4dcc9ae34dfd2df760b7626503307fbc940a87c5 100644 (file)
@@ -16,7 +16,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -24,14 +24,14 @@ msgstr ""
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 #, fuzzy
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "Venligst flet /var/lib/amandates og /var/lib/amanda/amandates."
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index 4c61e193ff715a792e5db5f56fd8185327668381..7d5623a91ff872a6c6fefb43bbfec723ccf54b53 100644 (file)
@@ -16,7 +16,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -24,7 +24,7 @@ msgstr ""
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 #, fuzzy
@@ -32,7 +32,7 @@ msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr ""
 "Bitte fügen Sie /var/lib/amandates und /var/lib/amanda/amandates zusammen."
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index f07fdf2f9ad59b613520de92ba9f3208727cb3f1..67aea542cea91706ef7ce8d5b1c79c80afd629cf 100644 (file)
@@ -16,7 +16,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -24,14 +24,14 @@ msgstr ""
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 #, fuzzy
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "Por favor fusione los ficheros de datos"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index 513f4feb8909265f7e934e8f30b68b51b76ce8e9..1364b569c6bb9b240a058abba7ed51c85a7e26fb 100644 (file)
@@ -19,7 +19,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: fr\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: 2006-05-28 17:13+0200\n"
 "Last-Translator: Christian Perrier <bubulle@debian.org>\n"
 "Language-Team: French <debian-l10n-french@lists.debian.org>\n"
@@ -28,14 +28,14 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.2\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr ""
 "Fusion indispensable de /var/lib/amandates et /var/lib/amanda/amandates"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index 31e5ad92bfdbda21ebd2e41b6afc9b8cf698014d..ba3f81a86f53b05eebcd780e14a5767b35a07bb9 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: amanda 1:2.5.0p2 italian debconf templates\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: 2006-05-30 10:30+0200\n"
 "Last-Translator: Luca Monducci <luca.mo@tiscali.it>\n"
 "Language-Team: Italian <debian-l10n-italian@lists.debian.org>\n"
@@ -15,13 +15,13 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "Unire /var/lib/amandates e /var/lib/amanda/amndates."
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index c000202b599d85b6aebda59d7da5ac099b2293d9..7fb70a28461832b3f916d604de426a893c619ecc 100644 (file)
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: amanda 2.4.4p2\n"
+"Project-Id-Version: amanda 2.5.0p2-2.1\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
-"PO-Revision-Date: 2004-02-21 01:08+0900\n"
-"Last-Translator: Hideki Yamane <henrich@samba.gr.jp>\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
+"PO-Revision-Date: 2006-10-11 00:08+0900\n"
+"Last-Translator: Hideki Yamane (Debian-JP) <henrich@debian.or.jp>\n"
 "Language-Team: Japanese <debian-japanese@lists.debian.org>\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=EUC-JP\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
-#, fuzzy
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
-msgstr "/var/lib/amandates ¤È /var/lib/amanda/amandates ¤ò¥Þ¡¼¥¸¤·¤Æ¤¯¤À¤µ¤¤¡£"
+msgstr "/var/lib/amandates と /var/lib/amanda/amandates をマージしてください。"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
@@ -39,6 +38,6 @@ msgid ""
 "review the files, and merge the contents you care about to the /var/lib/"
 "amanda/amandates location, and remove the old file /var/lib/amandates."
 msgstr ""
-"/var/lib/amandates ¤È /var/lib/amanda/amandates ¤ÎξÊý¤¬¤¢¤ê¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤ò"
-"³Îǧ¤·¡¢/var/lib/amanda/amandates ¤ËÃí°Õ¤¬É¬ÍפÊÆâÍƤò¥Þ¡¼¥¸¤·¤Æ¤«¤é¡¢¸Å¤¤"
-"¥Õ¥¡¥¤¥ë /var/lib/amandates ¤òºï½ü¤·¤Æ¤¯¤À¤µ¤¤¡£"
+"/var/lib/amandates と /var/lib/amanda/amandates の両方があります。ファイルを"
+"確認し、/var/lib/amanda/amandates に注意が必要な内容をマージしてから、古い"
+"ファイル /var/lib/amandates を削除してください。"
index 6c0e4a404142dfeb02accbb971e7f0131c9fe958..44012700e633b0728e290d7012551ca846a0f68f 100644 (file)
@@ -21,7 +21,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: amanda 1:2.5.0p2-1\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: 2006-06-18 20:45+0100\n"
 "Last-Translator: Kurt De Bree <kdebree(AT)telenet(DOT)be>\n"
 "Language-Team: Debian l10n Dutch <debian-l10n-dutch@lists.debian.org>\n"
@@ -29,13 +29,13 @@ msgstr ""
 "Content-Type: text/plain; charset=iso-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "Voeg /var/lib/amandates en /var/lib/amanda/amandates samen."
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index cb409e5ffcfd04475d939757784c6bfc457d3962..6d8894aeabda9ac5ff041bf9de87a38ab9df9b8a 100644 (file)
@@ -15,7 +15,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: amanda_1%3A2.4.4p1-1_pt\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: 2003-10-18 13:47+0100\n"
 "Last-Translator: Bruno Rodrigues <bruno.rodrigues@litux.org>\n"
 "Language-Team: Portuguese <debian-l10n-portuguese@lists.debian.org>\n"
@@ -24,7 +24,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.0.2\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 #, fuzzy
@@ -32,7 +32,7 @@ msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr ""
 "Deverá integrar o conteúdo de /var/lib/amandates em /var/lib/amanda/amandates"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index a03a2e6e0258f0e58fb18f9fce4a6bf198bc91dc..be350ce92770fb6896cb526981f672c67921ae50 100644 (file)
@@ -16,7 +16,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -24,14 +24,14 @@ msgstr ""
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 #, fuzzy
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "Por favor junte /var/lib/amandates e /var/lib/amanda/amandates."
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index 1d34ea48ab4630b48b6c519c55157d1ba046cde6..7588be48398c0116a5f1046fbfc24337252f4ce3 100644 (file)
@@ -16,7 +16,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -24,14 +24,14 @@ msgstr ""
 "Content-Type: text/plain; charset=KOI8-R\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 #, fuzzy
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "ðÏÖÁÌÕÊÓÔÁ, ÓÏÅÄÉÎÉÔÅ /var/lib/amandates É /var/lib/amanda/amandates."
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index bc2574fb0f270d413e1ffd3144db6a07648ea868..db2f139379baec9ccf7c9a2d0ce294aa6a51b203 100644 (file)
@@ -15,7 +15,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: amanda 1:2.5.0p2-1\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: 2006-06-27 23:05+0100\n"
 "Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -23,13 +23,13 @@ msgstr ""
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "Sammanfoga /var/lib/amandates och /var/lib/amanda/amandates"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index 97aa346b25f3fbf71cdde07460081f2e4f2df104..aa097e88f3200cf654e9db88e8d21f303c412998 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-10-07 11:13+0000\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,13 +16,13 @@ msgstr ""
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr ""
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index b4e3320ed65ddb7e34a3561796b9053cbd5f2058..4210d220f6f54255113e91deeec17321127668bb 100644 (file)
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: amanda 1/2.4.4p3-2\n"
 "Report-Msgid-Bugs-To: bdale@gag.com\n"
-"POT-Creation-Date: 2006-08-28 13:34-0400\n"
+"POT-Creation-Date: 2006-10-18 01:32-0600\n"
 "PO-Revision-Date: 2005-05-05 13:29+0930\n"
 "Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
 "Language-Team: Vietnamese <gnomevi-list@lists.sourceforge.net>\n"
@@ -15,14 +15,14 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0\n"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 #, fuzzy
 msgid "Please merge /var/lib/amandates and /var/lib/amanda/amandates"
 msgstr "Hãy kết hợp /var/lib/amandates và /var/lib/amanda/amandates"
 
-#. Type: note
+#. Type: error
 #. Description
 #: ../templates:1001
 msgid ""
index 80721f5447624673a3e5d3c631ce9dc5aa4aeeea..770d20e3dd3ab370fa02883216c16038f0eb60b0 100755 (executable)
@@ -30,7 +30,8 @@ build-stamp: /sbin/dump /usr/bin/smbclient debian/po/templates.pot
                --with-debugging=/var/log/amanda \
                --with-dumperdir=/usr/lib/amanda/dumper.d \
                --with-tcpportrange=50000,50100 --with-udpportrange=840,860 \
-               --with-maxtapeblocksize=256
+               --with-maxtapeblocksize=256 \
+               --with-ssh-security
        touch missing
        make CFLAGS="-O2 -g -Wall \
                -DAMANDATES_FILE='\"/var/lib/amanda/amandates\"' \
index ec4614a450a6157f5f3c2d1b8d2a66b786ce8280..b3256eea7d9f5819d415b97a393a8908a90d09e2 100644 (file)
@@ -1,5 +1,5 @@
 Template: amanda-common/merge_amandates
-Type: note
+Type: error
 _Description: Please merge /var/lib/amandates and /var/lib/amanda/amandates
  You have both /var/lib/amandates and /var/lib/amanda/amandates. Please
  review the files, and merge the contents you care about to the
index 099ae71c3d8861205094e5c1252cb223795278ad..1d32508f0a8ca91b4b41171cd7e5b01f16a517f3 100644 (file)
@@ -5,18 +5,84 @@ Prev            Next
 -------------------------------------------------------------------------------
 
 
-Appendixes
+Part VII. Appendixes
 
 Table of Contents
 
 
-  35._The_AMANDA_Manual_Pages.
+  36._The_Amanda_Manual_Pages.
+
+
+        amadmin - administrative interface to control Amanda backups
+
+        amaespipe - wrapper program for aespipe
+
+        amanda - Advanced Maryland Automatic Network Disk Archiver
+
+        amanda.conf - Main configuration file for Amanda, the Advanced Maryland
+        Automatic Network Disk Archiver
+
+        amanda-client.conf - Client configuration file for Amanda, the Advanced
+        Maryland Automatic Network Disk Archiver
+
+        amcheck - run Amanda self-checks
+
+        amcheckdb - check Amanda database for tape consistency
+
+        amcleanup - run the Amanda cleanup process after a failure
+
+        amcrypt - reference crypt program for Amanda symmetric data encryption
+
+        amcrypt-ossl - crypt program for Amanda symmetric data encryption using
+        OpenSSL
+
+        amcrypt-ossl-asym - crypt program for Amanda asymmetric data encryption
+        using OpenSSL
+
+        amdd - Amanda version of dd
+
+        amdump - back up all disks in an Amanda configuration
+
+        amfetchdump - extract backup images from multiple Amanda tapes.
+
+        amflush - flush Amanda backup files from holding disk to tape
+
+        amgetconf - look up amanda.conf variables
+
+        amlabel - label an Amanda tape
+
+        ammt - Amanda version of mt
+
+        amoverview - display file systems processed by Amanda over time
+
+        amplot - visualize the behavior of Amanda
+
+        amrecover - Amanda index database browser
+
+        amreport - generate a formatted output of statistics for an Amanda run
+
+        amrestore - extract backup images from an Amanda tape
+
+        amrmtape - remove a tape from the Amanda database
+
+        amstatus - display the state of an Amanda run
+
+        amtape - user interface to Amanda tape changer controls
+
+        amtapetype - generate a tapetype definition.
+
+        amtoc - generate TOC (Table Of Contents) for an Amanda run
+
+        amverify - check an Amanda tape for errors
+
+        amverifyrun - check the tapes written by the last Amanda run
+
 
-  36._Web_Ressources
+  37._Web_Ressources
 
 -------------------------------------------------------------------------------
 
-Prev                              Up                                   Next
-Chapter 34. Usage of floppy tape Home  Chapter 35. The AMANDA Manual Pages.
+Prev                                                                   Next
+Chapter 35. Usage of floppy tape Home  Chapter 36. The Amanda Manual Pages.
 drives on Linux 
 
index 4945798d9d2cfe1f3859b5f8f1cc66150caa73db..d4bbf4189287556b8efbbb25febace886a38037f 100644 (file)
@@ -2,13 +2,19 @@
 pkgdata_DATA = \
        Appendix.txt \
        amadmin.8.txt \
+       amaespipe.8.txt \
        amanda.8.txt \
        amanda.conf.5.txt \
+       amanda-client.conf.5.txt \
        amcheck.8.txt \
        amcheckdb.8.txt \
        amcleanup.8.txt \
+       amcrypt.8.txt \
+       amcrypt-asym-ossl.8.txt \
+       amcrypt-ossl.8.txt \
        amdd.8.txt \
        amdump.8.txt \
+       amfetchdump.8.txt \
        amflush.8.txt \
        amgetconf.8.txt \
        amlabel.8.txt \
@@ -32,6 +38,7 @@ pkgdata_DATA = \
        faq.txt \
        historical.txt \
        howto-afs.txt \
+       howto-auth.txt \
        howto-cygwin.txt \
        howto-filedriver.txt \
        howto-wrapper.txt \
index b1d3d8744f463c8cb8db7a3744249fd6b92406c0..594471340bf54ff685711d47ea8aed5e9120e616 100644 (file)
@@ -66,11 +66,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -78,6 +81,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -261,13 +266,19 @@ target_vendor = @target_vendor@
 pkgdata_DATA = \
        Appendix.txt \
        amadmin.8.txt \
+       amaespipe.8.txt \
        amanda.8.txt \
        amanda.conf.5.txt \
+       amanda-client.conf.5.txt \
        amcheck.8.txt \
        amcheckdb.8.txt \
        amcleanup.8.txt \
+       amcrypt.8.txt \
+       amcrypt-asym-ossl.8.txt \
+       amcrypt-ossl.8.txt \
        amdd.8.txt \
        amdump.8.txt \
+       amfetchdump.8.txt \
        amflush.8.txt \
        amgetconf.8.txt \
        amlabel.8.txt \
@@ -291,6 +302,7 @@ pkgdata_DATA = \
        faq.txt \
        historical.txt \
        howto-afs.txt \
+       howto-auth.txt \
        howto-cygwin.txt \
        howto-filedriver.txt \
        howto-wrapper.txt \
index 209c3af51a45faa9b872e79a91309ed21658b4dc..d99a9ec8608d04ba5e7538e513fa4534781e57ba 100644 (file)
@@ -1,22 +1,22 @@
 
                               amadmin
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amadmin \14 administrative interface to control AMANDA backups
+amadmin \14 administrative interface to control Amanda backups
 
 Synopsis
 
-amadmin config command [ command options ]
+amadmin config command [command options] [ -o | configoption ]*
 
 DESCRIPTION
 
-Amadmin performs various administrative tasks on the config AMANDA
+Amadmin performs various administrative tasks on the config Amanda
 configuration.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 COMMANDS
 
@@ -33,18 +33,18 @@ DISK EXPRESSION" section of amanda(8) for a description.
 
   force-bump [ hostname [ disks ]* ]+
       Force the disks on hostname to bump to a new incremental level during the
-      next AMANDA run.
+      next Amanda run.
 
   force-no-bump [ hostname [ disks ]* ]+
       Force the disks on hostname to not bump to a new incremental level during
-      the next AMANDA run.
+      the next Amanda run.
 
   unforce-bump [ hostname [ disks ]* ]+
       Undo a previous force-bump or force-no-bump command.
 
   force [ hostname [ disks ]* ]+
       Force the disks on hostname to do a full (level 0) backup during the next
-      AMANDA run.
+      Amanda run.
 
   unforce [ hostname [ disks ]* ]+
       Undo a previous force command.
@@ -56,30 +56,30 @@ DISK EXPRESSION" section of amanda(8) for a description.
   no-reuse tapelabel [ ... ]
       The tapes listed will not be reused when their turn comes up again in the
       tape cycle. Note that if this causes the number of reusable tapes to drop
-      below the amanda.conf tapecycle value, AMANDA will request new tapes
+      below the amanda.conf tapecycle value, Amanda will request new tapes
       until the count is satisfied again.
 
   due [ hostname [ disks ]* ]*
       Show when the next full dump is due.
 
-  find [ --sort hkdlb ] [ hostname [ disks ]* ]*
+  find [ --sort hkdlpb ] [ hostname [ disks ]* ]*
       Display all backups currently on tape or in the holding disk. The tape
       label or holding disk filename, file number, and status are displayed.
       The --sort option changes the sort order using the following flags:
-      hhost name kdisk name ddump date lbackup level btape label
+      hhost name kdisk name ddump date lbackup level p dump part btape label
       An uppercase letter reverses the sort order for that key. The default
-      sort order is hkdlb.
+      sort order is hkdlpb.
 
   delete [ hostname [ disks ]* ]+
-      Delete the specified disks on hostname from the AMANDA database.
+      Delete the specified disks on hostname from the Amanda database.
 
       Note
 
-      If you do not also remove the disk from the disklist file, AMANDA will
+      If you do not also remove the disk from the disklist file, Amanda will
       treat it as a new disk during the next run.
 
   tape
-      Display the tape(s) AMANDA expects to write to during the next run. See
+      Display the tape(s) Amanda expects to write to during the next run. See
       also amcheck(8).
 
   bumpsize
@@ -90,11 +90,11 @@ DISK EXPRESSION" section of amanda(8) for a description.
       Display the distribution of full backups throughout the dump schedule.
 
   export [ hostname [ disks ]* ]*
-      Convert records from the AMANDA database to a text format that may be
-      transmitted to another AMANDA machine and imported.
+      Convert records from the Amanda database to a text format that may be
+      transmitted to another Amanda machine and imported.
 
   import
-      Convert exported records read from standard input to a form AMANDA uses
+      Convert exported records read from standard input to a form Amanda uses
       and insert them into the database on this machine.
 
   disklist [ hostname [ disks ]* ]*
@@ -105,11 +105,14 @@ DISK EXPRESSION" section of amanda(8) for a description.
       Display the database record for each of the disks on hostname (or all
       hosts). Mostly used for debugging.
 
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
 
 EXAMPLES
 
 Request three specific file systems on machine-a get a full level 0 backup
-during the next AMANDA run.
+during the next Amanda run.
 
   $ amadmin daily force machine-a / /var /usr
   amadmin: machine-a:/ is set to a forced level 0 tonight.
@@ -117,7 +120,7 @@ during the next AMANDA run.
   amadmin: machine-a:/usr is set to a forced level 0 tonight.
 
 Request all file systems on machine-b get a full level 0 backup during the next
-AMANDA run.
+Amanda run.
 
   $ amadmin daily force machine-b
   amadmin: machine-b:/ is set to a forced level 0 tonight.
@@ -140,30 +143,30 @@ holding disk. The status column tells you whether the backup was successful or
 had some type of error.
 
   $ amadmin daily find machine-c /var
-  date        host      disk lv tape or file                    file status
-  2000-11-09  machine-c /var  0 000110                             9 OK
-  2000-11-08  machine-c /var  2 000109                             2 OK
-  2000-11-07  machine-c /var  2 /amanda/20001107/machine-c._var.2  0 OK
-  2000-11-06  machine-c /var  2 000107                             2 OK
-  2000-11-05  machine-c /var  2 000106                             3 OK
-  2000-11-04  machine-c /var  2 000105                             2 OK
-  2000-11-03  machine-c /var  2 000104                             2 OK
-  2000-11-02  machine-c /var  2 000103                             2 OK
-  2000-11-01  machine-c /var  1 000102                             5 OK
-  2000-10-31  machine-c /var  1 000101                             3 OK
+  date        host      disk lv tape or file                 file part  status
+  2000\-11\-09  machine\-c /var  0 000110                       9   --  OK
+  2000\-11\-08  machine\-c /var  2 000109                       2   --  OK
+  2000\-11\-07  machine\-c /var  2 /amanda/20001107/machine-c._var.2  0 OK
+  2000\-11\-06  machine\-c /var  2 000107                       2   --  OK
+  2000\-11\-05  machine\-c /var  2 000106                       3   --  OK
+  2000\-11\-04  machine\-c /var  2 000105                       2   --  OK
+  2000\-11\-03  machine\-c /var  2 000104                       2   --  OK
+  2000\-11\-02  machine\-c /var  2 000103                       2   --  OK
+  2000\-11\-01  machine\-c /var  1 000102                       5   --  OK
+  2000\-10\-31  machine\-c /var  1 000101                       3   --  OK
 
 Forget about the /workspace disk on machine-d. If you do not also remove the
-disk from the disklist file, AMANDA will treat it as a new disk during the next
+disk from the disklist file, Amanda will treat it as a new disk during the next
 run.
 
   $ amadmin daily delete machine-d /workspace
   amadmin: machine-d:/workspace deleted from database.
   amadmin: NOTE: you'll have to remove these from the disklist yourself.
 
-Find the next tape AMANDA will use (in this case, 123456).
+Find the next tape Amanda will use (in this case, 123456).
 
   $ amadmin daily tape
-  The next AMANDA run should go onto tape 123456 or a new tape.
+  The next Amanda run should go onto tape 123456 or a new tape.
 
 Show how well full backups are balanced across the dump cycle. The due-date
 column is the day the backups are due for a full backup. #fs shows the number
@@ -171,16 +174,16 @@ of filesystems doing full backups that night, and orig KB and out KB show the
 estimated total size of the backups before and after any compression,
 respectively.
 The balance column shows how far off that night's backups are from the average
-size (shown at the bottom of the balance column). AMANDA tries to keep the
+size (shown at the bottom of the balance column). Amanda tries to keep the
 backups within +/- 5%, but since the amount of data on each filesystem is
-always changing, and AMANDA will never delay backups just to rebalance the
+always changing, and Amanda will never delay backups just to rebalance the
 schedule, it is common for the schedule to fluctuate by larger percentages. In
 particular, in the case of a tape or backup failure, a bump will occur the
 following night, which will not be smoothed out until the next pass through the
 schedule.
-The last line also shows an estimate of how many AMANDA runs will be made
+The last line also shows an estimate of how many Amanda runs will be made
 between full backups for a file system. In the example, a file system will
-probably have a full backup done every eight times AMANDA is run (e.g. every
+probably have a full backup done every eight times Amanda is run (e.g. every
 eight days).
 
   $ amadmin daily balance
@@ -207,14 +210,14 @@ FILES
 AUTHOR
 
 James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
 
-amanda(8), amcheck(8), amdump(8), amrestore(8)
+amanda(8), amcheck(8), amdump(8), amrestore(8), amfetchdump(8)
 -------------------------------------------------------------------------------
 
-Prev                                   Up     Next
-Chapter 35. The AMANDA Manual Pages.  Home  amanda
+Prev                                   Up        Next
+Chapter 36. The Amanda Manual Pages.  Home  amaespipe
 
diff --git a/docs/amaespipe.8.txt b/docs/amaespipe.8.txt
new file mode 100644 (file)
index 0000000..b222701
--- /dev/null
@@ -0,0 +1,35 @@
+
+                             amaespipe
+Prev  Chapter 36. The Amanda Manual Pages.  Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amaespipe \14 wrapper program for aespipe
+
+Synopsis
+
+amaespipe
+
+DESCRIPTION
+
+amaespipe requires aespipe, uuencode and gpg to work. Aespipe is available from
+http://loop-aes.sourceforge.net
+amaespipe will search for the aespipe program in the following directories: /
+usr/bin:/usr/local/bin:/sbin:/usr/sbin.
+amaespipe is called by amcrypt for Amanda data encryption.
+amaespipe is based on aespipe's bzaespipe program. It calls aespipe to encrypt
+data using AES256 as the encryption and SHA256 as the hash function. GPG key
+should be stored in $AMANDA_HOME/.gnupg/am_key.gpg. amaespipe reads passphrase
+from file descriptor 3. During decryption, amaespipe autodects encryption type
+and hash function from the encrypted image.
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), aespipe(1), amcrypt(8), gpg(1)
+-------------------------------------------------------------------------------
+
+Prev      Up     Next
+amadmin  Home  amanda
+
diff --git a/docs/amanda-client.conf.5.txt b/docs/amanda-client.conf.5.txt
new file mode 100644 (file)
index 0000000..2444dc8
--- /dev/null
@@ -0,0 +1,121 @@
+
+                      amanda-client.conf
+Prev  Chapter 36. The Amanda Manual Pages.  Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amanda-client.conf \14 Client configuration file for Amanda, the Advanced
+Maryland Automatic Network Disk Archiver
+
+DESCRIPTION
+
+amanda-client.conf is the client configuration file for Amanda. This manpage
+lists the relevant sections and parameters of this file for quick reference.
+
+PARAMETERS
+
+There are a number of configuration parameters that control the behavior of the
+Amanda programs. All have default values, so you need not specify the parameter
+in amanda-client.conf if the default is suitable.
+Lines starting with # are ignored, as are blank lines. Comments may be placed
+on a line with a directive by starting the comment with a #. The remainder of
+the line is ignored.
+Keywords are case insensitive, i.e. auth and Auth are treated the same.
+Integer arguments may have one of the following (case insensitive) suffixes,
+some of which have a multiplier effect:
+
+POSSIBLE SUFFIXES
+
+
+
+  b byte bytes
+      Some number of bytes.
+
+  bps
+      Some number of bytes per second.
+
+  k kb kbyte kbytes kilobyte kilobytes
+      Some number of kilobytes (bytes*1024).
+
+  kps kbps
+      Some number of kilobytes per second (bytes*1024).
+
+  m mb meg mbyte mbytes megabyte megabytes
+      Some number of megabytes (bytes*1024*1024).
+
+  mps mbps
+      Some number of megabytes per second (bytes*1024*1024).
+
+  g gb gbyte gbytes gigabyte gigabytes
+      Some number of gigabytes (bytes*1024*1024*1024).
+
+  tape tapes
+      Some number of tapes.
+
+  day days
+      Some number of days.
+
+  week weeks
+      Some number of weeks (days*7).
+
+      Note
+
+      The value inf may be used in most places where an integer is expected to
+      mean an infinite amount.
+      Boolean arguments may have any of the values y, yes, t, true or on to
+      indicate a true state, or n, no, f, false or off to indicate a false
+      state. If no argument is given, true is assumed.
+
+
+PARAMETERS
+
+
+
+  conf string
+      Default: Set by configure. The conf use by amrecover.
+
+  index_server string
+      Default: Set by configure. The amindexd server amrecover will connect to.
+
+  tape_server string
+      Default: Set by configure. The amidxtaped server amrecover will connect
+      to.
+
+  tapedev string
+      Default: Set by configure. The tapedev amrecover will use.
+
+  auth string
+      Default: bsd. Type of authorization to perform between tape server and
+      backup client hosts.
+      bsd, bsd authorization with udp initial connection and one tcp connection
+      by data stream.
+      bsdtcp, bsd authorization but use only one tcp connection.
+      bsdudp, like bsd, but will use only one tcp connection for all data
+      stream.
+      krb4 to use Kerberos-IV authorization.
+      krb5 to use Kerberos-V authorization.
+      rsh to use rsh authorization.
+      ssh to use OpenSSH authorization.
+
+  ssh_keys string
+      Default: No default. The key file the ssh auth will use, it must be the
+      private key. If this parameter is not specified, then the deafult ssh key
+      will be used.
+
+
+AUTHOR
+
+James da Silva, <jds@amanda.org>: Original text
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
+XML-conversion, major update, splitting
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), amcrypt(8), aespipe(1),
+-------------------------------------------------------------------------------
+
+Prev          Up      Next
+amanda.conf  Home  amcheck
+
index 1deec2631f1eb0ba48931c68d1862031ab89946a..6572c6294589e27fc7cd23c9a3583a936009f90b 100644 (file)
@@ -1,6 +1,6 @@
 
                                amanda
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
@@ -14,8 +14,10 @@ amadmin config command [options]
 amcheck [options] config
 amcheckdb config
 amcleanup config
+amcrypt
 amdd [options]
 amdump config
+amaespipe
 amflush [-f ] config
 amgetconf [config] parameter
 amlabel config label [ slot slot ]
@@ -25,6 +27,7 @@ amplot [options] amdump-files
 amrecover [config] [options]
 amreport [config] [options]
 amrestore [options] tapedevice [ hostname [diskname]]
+amfetchdump [options] config [ hostname [ diskname [ date [level]]]]
 amrmtape [options] config label
 amstatus config [options]
 amtape config command [options]
@@ -35,15 +38,15 @@ amverifyrun config
 
 DESCRIPTION
 
-AMANDA is the "Advanced Maryland Automatic Network Disk Archiver". This manual
-page gives an overview of the AMANDA commands and configuration files for quick
+Amanda is the "Advanced Maryland Automatic Network Disk Archiver". This manual
+page gives an overview of the Amanda commands and configuration files for quick
 reference.
-Here are all the AMANDA commands. Each one has its own manual page. See them
+Here are all the Amanda commands. Each one has its own manual page. See them
 for all the gory details.
 
 
   amdump
-      Take care of automatic AMANDA backups. This is normally executed by cron
+      Take care of automatic Amanda backups. This is normally executed by cron
       on a computer called the tape server host and requests backups of file
       systems located on backup clients. Amdump backs up all disks in the
       disklist file (discussed below) to tape or, if there is a problem, to a
@@ -62,18 +65,24 @@ for all the gory details.
       server host crashed while amdump was running.
 
   amrecover
-      Provides an interactive interface to browse the AMANDA index files
+      Provides an interactive interface to browse the Amanda index files
       (backup image catalogues) and select which tapes to recover files from.
       It can also run amrestore and a restore program (e.g. tar) to actually
       recover the files.
 
   amrestore
-      Read an AMANDA tape, searching for requested backups. Amrestore is
+      Read an Amanda tape, searching for requested backups. Amrestore is
       suitable for everything from interactive restores of single files to a
       full restore of all partitions on a failed disk.
 
+  amfetchdump
+      Performs Amanda tape restoration, similar to amrestore. Additional
+      capabilities include "hands-off" searching of multiple tapes, automatic
+      retrieval of specific dump files based on dump logs, and assembly of
+      tape-spanning split dump files.
+
   amlabel
-      Write an AMANDA format label onto a tape. All AMANDA tapes must be
+      Write an Amanda format label onto a tape. All Amanda tapes must be
       labeled with amlabel. Amdump and amflush will not write to an unlabeled
       tape (see TAPE MANAGEMENT below).
 
@@ -93,10 +102,10 @@ for all the gory details.
       tapes, ejecting tapes and scanning the tape storage slots.
 
   amverify
-      Check AMANDA backup tapes for errors.
+      Check Amanda backup tapes for errors.
 
   amrmtape
-      Delete a tape from the AMANDA databases.
+      Delete a tape from the Amanda databases.
 
   amstatus
       Report the status of a running or completed amdump.
@@ -105,30 +114,36 @@ for all the gory details.
       Display a chart of hosts and file systems backed up every run.
 
   amplot
-      Generate utilization plots of AMANDA runs for performance tuning.
+      Generate utilization plots of Amanda runs for performance tuning.
 
   amreport
-      Generate an AMANDA summary E-mail report.
+      Generate an Amanda summary E-mail report.
 
   amtoc
-      Generate table of content files for AMANDA tapes.
+      Generate table of content files for Amanda tapes.
 
   amcheckdb
-      Verify every tape AMANDA knows about is consistent in the database.
+      Verify every tape Amanda knows about is consistent in the database.
 
   amgetconf
-      Look up parameters in the AMANDA configuration file.
+      Look up parameters in the Amanda configuration file.
 
   amtapetype
       Generate a tapetype definition.
 
+  amaespipe
+      Wrapper program from aespipe (data encryption utility)
+
+  amcrypt
+      Reference encryption program for Amanda symmetric data encryption
+
 
 CONFIGURATION
 
-There are three user-editable files that control the behavior of AMANDA.
+There are three user-editable files that control the behavior of Amanda.
 The first is amanda.conf, the main configuration file. It contains parameters
-to customize AMANDA for the site. Refer to the amanda.conf(5), manpage for
-details on AMANDA configuration parameters.
+to customize Amanda for the site. Refer to the amanda.conf(5), manpage for
+details on Amanda configuration parameters.
 Second is the disklist file, which lists hosts and disk partitions to back up.
 Third is the tapelist file, which lists tapes that are currently active. These
 files are described in more detail in the following sections.
@@ -137,14 +152,14 @@ etc/amanda/. A site will often have more than one configuration. For example,
 it might have a normal configuration for everyday backups and an archive
 configuration for infrequent full archival backups. The configuration files
 would be stored under directories /usr/local/etc/amanda/normal/ and /usr/local/
-etc/amanda/archive/, respectively. Part of the job of an AMANDA administrator
+etc/amanda/archive/, respectively. Part of the job of an Amanda administrator
 is to create, populate and maintain these directories.
-All log and database files generated by AMANDA go in corresponding directories
+All log and database files generated by Amanda go in corresponding directories
 somewhere. The exact location is controlled by entries in amanda.conf. A
 typical location would be under /var/adm/amanda. For the above example, the
 files might go in /var/adm/amanda/normal/ and /var/adm/amanda/archive/.
 As log files are no longer needed (no longer contain relevant information),
-AMANDA cycles them out in various ways, depending on the type of file.
+Amanda cycles them out in various ways, depending on the type of file.
 Detailed information about amdump runs are stored in files named amdump.NN
 where NN is a sequence number, with 1 being the most recent file. Amdump
 rotates these files each run, keeping roughly the last tapecycle (see below)
@@ -153,7 +168,7 @@ The file used by amreport to generate the mail summary is named log.YYYYMMDD.NN
 where YYYYMMDD is the datestamp of the start of the amdump run and NN is a
 sequence number started at 0. At the end of each amdump run, log files for runs
 whose tapes have been reused are renamed into a subdirectory of the main log
-directory (see the logdir parameter below) named oldlog. It is up to the AMANDA
+directory (see the logdir parameter below) named oldlog. It is up to the Amanda
 administrator to remove them from this directory when desired.
 Index (backup image catalogue) files older than the full dump matching the
 oldest backup image for a given client and disk are removed by amdump at the
@@ -161,7 +176,7 @@ end of each run.
 
 DISKLIST FILE
 
-The disklist file determines which disks will be backed up by AMANDA. The file
+The disklist file determines which disks will be backed up by Amanda. The file
 usually contains one line per disk:
 
   hostname diskname [diskdevice] dumptype [spindle [interface] ]
@@ -173,7 +188,7 @@ following meanings:
 
   hostname
       The name of the host to be backed up. If diskdevice refers to a PC share,
-      this is the host AMANDA will run the Samba smbclient program on to back
+      this is the host Amanda will run the Samba smbclient program on to back
       up the share.
 
   diskname
@@ -181,7 +196,7 @@ following meanings:
       the diskdevice and you don't set the diskdevice. If you want multiple
       entries with the same diskdevice, you must set a different diskname for
       each entry. It's the diskname that you use on the commandline for any
-      AMANDA command. Look at the example/disklist file for example.
+      Amanda command. Look at the example/disklist file for example.
 
   diskdevice
       Default: same as diskname. The name of the disk device to be backed up.
@@ -200,7 +215,7 @@ following meanings:
       priority, etc.
 
   spindle
-      Default: -1. A number used to balance backup load on a host. AMANDA will
+      Default: -1. A number used to balance backup load on a host. Amanda will
       not run multiple backups at the same time on the same spindle, unless the
       spindle number is -1, which means there is no spindle restriction.
 
@@ -226,13 +241,13 @@ work instead of defining a new dumptype:
 TAPE MANAGEMENT
 
 The tapelist file contains the list of tapes in active use. This file is
-maintained entirely by AMANDA and should not be created or edited during normal
+maintained entirely by Amanda and should not be created or edited during normal
 operation. It contains lines of the form:
 
   YYYYMMDD label flags
 
 Where YYYYMMDD is the date the tape was written, label is a label for the tape
-as written by amlabel and flags tell AMANDA whether the tape may be reused, etc
+as written by amlabel and flags tell Amanda whether the tape may be reused, etc
 (see the reuse options of amadmin).
 Amdump and amflush will refuse to write to an unlabeled tape, or to a labeled
 tape that is considered active. There must be more tapes in active rotation
@@ -245,7 +260,7 @@ OUTPUT DRIVERS
 The normal value for the tapedev parameter, or for what a tape changer returns,
 is a full path name to a non-rewinding tape device, such as /dev/nst0 or /dev/
 rmt/0mn or /dev/nst0.1 or whatever conventions the operating system uses.
-AMANDA provides additional application level drivers that support non-
+Amanda provides additional application level drivers that support non-
 traditional tape-simulations or features. To access a specific output driver,
 set tapedev (or configure your changer to return) a string of the form driver:
 driver-info where driver is one of the supported drivers and driver-info is
@@ -268,7 +283,7 @@ The supported drivers are:
   null
       This driver throws away anything written to it and returns EOF for any
       reads except a special case is made for reading a label, in which case a
-      "fake" value is returned that AMANDA checks for and allows through
+      "fake" value is returned that Amanda checks for and allows through
       regardless of what you have set in labelstr. The driver-info field is not
       used and may be left blank:
 
@@ -315,7 +330,7 @@ The supported drivers are:
       for the actual data. Create a symlink named data in the file directory to
       one of the data directories. Set the tapetype length to whatever the
       medium will hold.
-      When AMANDA fills the file device, remove the symlink and (optionally)
+      When Amanda fills the file device, remove the symlink and (optionally)
       create a new symlink to another data area. Use a CD writer software
       package to burn the image from the first data area.
       To read the CD, mount it and create the data symlink in the file device
@@ -324,34 +339,37 @@ The supported drivers are:
 
 AUTHORIZATION
 
-AMANDA processes on the tape server host run as the dumpuser user listed in
-amanda.conf. When they connect to a backup client, they do so with an AMANDA-
+Amanda processes on the tape server host run as the dumpuser user listed in
+amanda.conf. When they connect to a backup client, they do so with an Amanda-
 specific protocol. They do not, for instance, use rsh or ssh directly.
 On the client side, the amandad daemon validates the connection using one of
 several methods, depending on how it was compiled and on options it is passed:
 
 
   .rhosts
-      Even though AMANDA does not use rsh, it can use .rhosts-style
+      Even though Amanda does not use rsh, it can use .rhosts-style
       authentication and a .rhosts file.
 
   .amandahosts
       This is essentially the same as .rhosts authentication except a different
       file, with almost the same format, is used. This is the default mechanism
-      built into AMANDA.
+      built into Amanda.
       The format of the .amandahosts file is:
-      hostname [ username ]
+      hostname [ username [ service ]*]
       If username is ommitted, it defaults to the user running amandad, i.e.
       the user listed in the inetd or xinetd configuration file.
+      The service is a list of the service the client is authorized to execute:
+      amdump, noop, selfcheck, sendsize, sendbackup, amindexd, amidxtaped.
+      amdump is a shortcut for "noop selfcheck sendsize sendbackup"
 
   Kerberos
-      AMANDA may use the Kerberos authentication system. Further information is
-      in the docs/KERBEROS file that comes with an AMANDA distribution.
-      For Samba access, AMANDA needs a file on the Samba server (which may or
+      Amanda may use the Kerberos authentication system. Further information is
+      in the docs/KERBEROS file that comes with an Amanda distribution.
+      For Samba access, Amanda needs a file on the Samba server (which may or
       may not also be the tape server) named /etc/amandapass with share names,
       (clear text) passwords and (optional) domain names, in that order, one
       per line, whitespace separated. By default, the user used to connect to
-      the PC is the same for all PC's and is compiled into AMANDA. It may be
+      the PC is the same for all PC's and is compiled into Amanda. It may be
       changed on a host by host basis by listing it first in the password field
       followed by a percent sign and then the password. For instance:
 
@@ -359,10 +377,10 @@ several methods, depending on how it was compiled and on options it is passed:
           //another-pc/disk otheruser%otherpw
 
       With clear text passwords, this file should obviously be tightly
-      protected. It only needs to be readable by the AMANDA-user on the Samba
+      protected. It only needs to be readable by the Amanda-user on the Samba
       server.
       You can find further information in the docs/SAMBA file that comes with
-      an AMANDA distribution.
+      an Amanda distribution.
 
 
 HOST & DISK EXPRESSION
@@ -376,37 +394,35 @@ expression at left with a '^'. You can anchor the expression at right with a
 '$'. The matcher is case insensitive for host but is case sensitive for disk. A
 match succeeds if all words in your expression match contiguous words in the
 host or disk.
- ________________________________________________________
-|._|word_separator_for_a_host____________________________|
-|/_|word_separator_for_a_disk____________________________|
-|^_|anchor_at_left_______________________________________|
-|$_|anchor_at_right______________________________________|
-|?_|match_exactly_one_character_except_the_separator_____|
-|*_|match_zero_or_more_characters_except_the_separator___|
-|**|match_zero_or_more_characters_including_the_separator|
 
+.  word separator for a host
+/  word separator for a disk
+^  anchor at left
+$  anchor at right
+?  match exactly one character except the separator
+*  match zero or more characters except the separator
+** match zero or more characters including the separator
 Some examples:
- ___________________________________________
-|EXPRESSION|WILL_MATCH_______|WILL_NOT_MATCH|
-|hosta_____|hosta____________|hostb_________|
-|__________|hoSTA.dOMAIna.ORG|______________|
-|__________|foo.hosta.org____|______________|
-|host______|host_____________|hosta_________|
-|host?_____|hosta____________|host__________|
-|__________|hostb____________|______________|
-|ho*na_____|hoina____________|ho.aina.org___|
-|ho**na____|hoina____________|______________|
-|__________|ho.aina.org______|______________|
-|^hosta____|hosta____________|foo.hosta.org_|
-|sda*______|/dev/sda1________|______________|
-|__________|/dev/sda12_______|______________|
-|/opt/_____|opt_(disk)_______|opt_(host)____|
-|.opt._____|opt_(host)_______|opt_(disk)____|
-|/_________|/________________|any_other_disk|
-|/usr______|/usr_____________|______________|
-|__________|/usr/opt_________|______________|
-|/usr$_____|/usr_____________|/usr/opt______|
 
+EXPRESSION     WILL MATCH           WILL NOT MATCH
+hosta          hosta                hostb
+               hoSTA.dOMAIna.ORG 
+               foo.hosta.org 
+host           host                 hosta
+host?          hosta                host
+               hostb 
+ho*na          hoina                ho.aina.org
+ho**na         hoina 
+               ho.aina.org 
+^hosta         hosta                foo.hosta.org
+sda*           /dev/sda1 
+               /dev/sda12 
+/opt/          opt (disk)           opt (host)
+.opt.          opt (host)           opt (disk)
+/              /                    any other disk
+/usr           /usr 
+               /usr/opt 
+/usr$          /usr                 /usr/opt
 
 DATESTAMP EXPRESSION
 
@@ -422,20 +438,31 @@ Leading ^ is removed. Trailing $ forces an exact match.
 |200010$____|match_only_200010____________________________________________|
 
 
+CONFIGURATION OVERWRITE
+
+Most command allow to overwrite any configuration parameter on the command line
+with the -o option.
+-o NAME=value
+eg. -o runtapes=2
+eg. -o DUMPTYPE:no-compress:compress="server fast"
+eg. -o TAPETYPE:HP-DAT:length=2000m
+eg. -o INTERFACE:local:use="2000 kbps"
+
 AUTHOR
 
 James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion, major update
 
 SEE ALSO
 
-amadmin(8), amanda.conf(5), amcheck(8), amcheckdb(8), amcleanup(8), amdd(8),
-amdump(8), amflush(8), amgetconf(8), amlabel(8), ammt(8), amoverview(8), amplot
-(8), amrecover(8), amreport(8), amrestore(8), amrmtape(8), amstatus(8), amtape
-(8), amtapetype(8), amtoc(8), amverify(8), amverifyrun(8)
+amadmin(8), amanda.conf(5), amanda-client.conf(5), amcheck(8), amcheckdb(8),
+amcleanup(8), amdd(8), amdump(8), amfetchdump(8) amflush(8), amgetconf(8),
+amlabel(8), ammt(8), amoverview(8), amplot(8), amrecover(8), amreport(8),
+amrestore(8), amrmtape(8), amstatus(8), amtape(8), amtapetype(8), amtoc(8),
+amverify(8), amverifyrun(8)
 -------------------------------------------------------------------------------
 
-Prev      Up          Next
-amadmin  Home  amanda.conf
+Prev        Up          Next
+amaespipe  Home  amanda.conf
 
index ecaf1caa6d025e1594a91cb65769393e964835eb..bf94e8706574f529058c9cbfe3650043f94a51c9 100644 (file)
@@ -1,23 +1,23 @@
 
                            amanda.conf
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amanda.conf \14 Main configuration file for AMANDA, the Advanced Maryland
+amanda.conf \14 Main configuration file for Amanda, the Advanced Maryland
 Automatic Network Disk Archiver
 
 DESCRIPTION
 
-amanda.conf is the main configuration file for AMANDA. This manpage lists the
+amanda.conf is the main configuration file for Amanda. This manpage lists the
 relevant sections and parameters of this file for quick reference.
 
 PARAMETERS
 
 There are a number of configuration parameters that control the behavior of the
-AMANDA programs. All have default values, so you need not specify the parameter
+Amanda programs. All have default values, so you need not specify the parameter
 in amanda.conf if the default is suitable.
 Lines starting with # are ignored, as are blank lines. Comments may be placed
 on a line with a directive by starting the comment with a #. The remainder of
@@ -73,325 +73,8 @@ PARAMETERS
 
 
 
-  org string
-      Default: daily. A descriptive name for the configuration. This string
-      appears in the Subject line of mail reports. Each AMANDA configuration
-      should have a different string to keep mail reports distinct.
-
-  mailto string
-      Default: operators. A space separated list of recipients for mail
-      reports.
-
-  dumpcycle int
-      Default: 10 days. The number of days in the backup cycle. Each disk will
-      get a full backup at least this often. Setting this to zero tries to do a
-      full backup each run.
-
-      Note
-
-      This parameter may also be set in a specific dumptype (see below). This
-      value sets the default for all dumptypes so must appear in amanda.conf
-      before any dumptypes are defined.
-
-  runspercycle int
-      Default: same as dumpcycle. The number of amdump runs in dumpcycle days.
-      A value of 0 means the same value as dumpcycle. A value of -1 means guess
-      the number of runs from the tapelist file, which is the number of tapes
-      used in the last dumpcycle days / runtapes.
-
-  tapecycle int
-      Default: 15 tapes. Typically tapes are used by AMANDA in an ordered
-      rotation. The tapecycle parameter defines the size of that rotation. The
-      number of tapes in rotation must be larger than the number of tapes
-      required for a complete dump cycle (see the dumpcycle parameter).
-      This is calculated by multiplying the number of amdump runs per dump
-      cycle (runspercycle parameter) times the number of tapes used per run
-      (runtapes parameter). Typically two to four times this calculated number
-      of tapes are in rotation. While AMANDA is always willing to use a new
-      tape in its rotation, it refuses to reuse a tape until at least
-      'tapecycle -1' number of other tapes have been used.
-      It is considered good administrative practice to set the tapecycle
-      parameter slightly lower than the actual number of tapes in rotation.
-      This allows the administrator to more easily cope with damaged or
-      misplaced tapes or schedule adjustments that call for slight adjustments
-      in the rotation order.
-
-  dumpuser string
-      Default: amanda. The login name AMANDA uses to run the backups. The
-      backup client hosts must allow access from the tape server host as this
-      user via .rhosts or .amandahosts, depending on how the AMANDA software
-      was built.
-
-  printer string
-      Printer to use when doing tape labels. See the lbl-templ tapetype option.
-
-  tapedev string
-      Default: /dev/nst0. The path name of the non-rewinding tape device. Non-
-      rewinding tape device names often have an 'n' in the name, e.g. /dev/rmt/
-      0mn, however this is operating system specific and you should consult
-      that documentation for detailed naming information.
-      If a tape changer is configured (see the tpchanger option), this option
-      might not be used.
-      If the null output driver is selected (see the section OUTPUT DRIVERS in
-      the amanda(8) manpage for more information), programs such as amdump will
-      run normally but all images will be thrown away. This should only be used
-      for debugging and testing, and probably only with the record option set
-      to no.
-
-  rawtapedev string
-      Default: /dev/null. The path name of the raw tape device. This is only
-      used if AMANDA is compiled for Linux machines with floppy tapes and is
-      needed for QIC volume table operations.
-
-  tpchanger string
-      Default: none. The name of the tape changer. If a tape changer is not
-      configured, this option is not used and should be commented out of the
-      configuration file.
-      If a tape changer is configured, choose one of the changer scripts (e.g.
-      chg-scsi) and enter that here.
-
-  changerdev string
-      Default: /dev/null. A tape changer configuration parameter. Usage depends
-      on the particular changer defined with the tpchanger option.
-
-  changerfile string
-      Default: /usr/adm/amanda/log/changer-status. A tape changer configuration
-      parameter. Usage depends on the particular changer defined with the
-      tpchanger option.
-
-  runtapes int
-      Default: 1. The maximum number of tapes used in a single run. If a tape
-      changer is not configured, this option is not used and should be
-      commented out of the configuration file.
-      If a tape changer is configured, this may be set larger than one to let
-      AMANDA write to more than one tape.
-      Note that this is an upper bound on the number of tapes, and AMANDA may
-      use less.
-      Also note that as of this release, AMANDA does not support true tape
-      overflow. When it reaches the end of one tape, the backup image AMANDA
-      was processing starts over again on the next tape.
-
-  maxdumpsize int
-      Default: runtapes*tape_length. Maximum number of bytes the planner will
-      schedule for a run.
-
-  taperalgo [first|firstfit|largest|largestfit|smallest|last]
-      Default: first. The algorithm used to choose which dump image to send to
-      the taper.
-
-
-        first
-            First in, first out.
-
-        firstfit
-            The first dump image that will fit on the current tape.
-
-        largest
-            The largest dump image.
-
-        largestfit
-            The largest dump image that will fit on the current tape.
-
-        smallest
-            The smallest dump image.
-
-        last
-            Last in, first out.
-
-
-  labelstr string
-      Default: .*. The tape label constraint regular expression. All tape
-      labels generated (see amlabel(8)) and used by this configuration must
-      match the regular expression. If multiple configurations are run from the
-      same tape server host, it is helpful to set their labels to different
-      strings (for example, "DAILY[0-9][0-9]*" vs. "ARCHIVE[0-9][0-9]*") to
-      avoid overwriting each other's tapes.
-
-  tapetype string
-      Default: EXABYTE. The type of tape drive associated with tapedev or
-      tpchanger. This refers to one of the defined tapetypes in the config file
-      (see below), which specify various tape parameters, like the length,
-      filemark size, and speed of the tape media and device.
-
-  ctimeout int
-      Default: 30 seconds. Maximum amount of time that amcheck will wait for
-      each client host.
-
-  dtimeout int
-      Default: 1800 seconds. Amount of idle time per disk on a given client
-      that a dumper running from within amdump will wait before it fails with a
-      data timeout error.
-
-  etimeout int
-      Default: 300 seconds. Amount of time per disk on a given client that the
-      planner step of amdump will wait to get the dump size estimates. For
-      instance, with the default of 300 seconds and four disks on client A,
-      planner will wait up to 20 minutes for that machine. A negative value
-      will be interpreted as a total amount of time to wait per client instead
-      of per disk.
-
-  netusage int
-      Default: 300 Kbps. The maximum network bandwidth allocated to AMANDA, in
-      Kbytes per second. See also the interface section.
-
-  inparallel int
-      Default: 10. The maximum number of backups that AMANDA will attempt to
-      run in parallel. AMANDA will stay within the constraints of network
-      bandwidth and holding disk space available, so it doesn't hurt to set
-      this number a bit high. Some contention can occur with larger numbers of
-      backups, but this effect is relatively small on most systems.
-
-  displayunit "k|m|g|t"
-      Default: "k". The unit used to print many numbers, k=kilo, m=mega,
-      g=giga, t=tera.
-
-  dumporder string
-      Default: tttTTTTTTT. The priority order of each dumper:
-
-      * s: smallest size
-      * S: largest size
-      * t: smallest time
-      * T: largest time
-      * b: smallest bandwidth
-      * B: largest bandwidth
-
-
-  maxdumps int
-      Default: 1. The maximum number of backups from a single host that AMANDA
-      will attempt to run in parallel. See also the inparallel option.
-      Note that this parameter may also be set in a specific dumptype (see
-      below). This value sets the default for all dumptypes so must appear in
-      amanda.conf before any dumptypes are defined.
-
-  bumpsize int
-      Default: 10 Mbytes. The minimum savings required to trigger an automatic
-      bump from one incremental level to the next, expressed as size. If AMANDA
-      determines that the next higher backup level will be this much smaller
-      than the current level, it will do the next level. The value of this
-      parameter is used only if the parameter bumppercent is set to 0.
-      The global setting of this parameter can be overwritten inside of a
-      dumptype-definition.
-      See also the options bumppercent, bumpmult and bumpdays.
-
-  bumppercent int
-      Default: 0 percent. The minimum savings required to trigger an automatic
-      bump from one incremental level to the next, expressed as percentage of
-      the current size of the DLE (size of current level 0). If AMANDA
-      determines that the next higher backup level will be this much smaller
-      than the current level, it will do the next level.
-      If this parameter is set to 0, the value of the parameter bumpsize is
-      used to trigger bumping.
-      The global setting of this parameter can be overwritten inside of a
-      dumptype-definition.
-      See also the options bumpsize, bumpmult and bumpdays.
-
-  bumpmult float
-      Default: 1.5. The bump size multiplier. AMANDA multiplies bumpsize by
-      this factor for each level. This prevents active filesystems from bumping
-      too much by making it harder to bump to the next level. For example, with
-      the default bumpsize and bumpmult set to 2.0, the bump threshold will be
-      10 Mbytes for level one, 20 Mbytes for level two, 40 Mbytes for level
-      three, and so on.
-      The global setting of this parameter can be overwritten inside of a
-      dumptype-definition.
-
-  bumpdays int
-      Default: 2 days. To insure redundancy in the dumps, AMANDA keeps
-      filesystems at the same incremental level for at least bumpdays days,
-      even if the other bump threshold criteria are met.
-      The global setting of this parameter can be overwritten inside of a
-      dumptype-definition.
-
-  diskfile string
-      Default: disklist. The file name for the disklist file holding client
-      hosts, disks and other client dumping information.
-
-  infofile string
-      Default: /usr/adm/amanda/curinfo. The file or directory name for the
-      historical information database. If AMANDA was configured to use DBM
-      databases, this is the base file name for them. If it was configured to
-      use text formated databases (the default), this is the base directory and
-      within here will be a directory per client, then a directory per disk,
-      then a text file of data.
-
-  logdir string
-      Default: /usr/adm/amanda. The directory for the amdump and log files.
-
-  indexdir string
-      Default /usr/adm/amanda/index. The directory where index files (backup
-      image catalogues) are stored. Index files are only generated for
-      filesystems whose dumptype has the index option enabled.
-
-  tapelist string
-      Default: tapelist. The file name for the active tapelist file. AMANDA
-      maintains this file with information about the active set of tapes.
-
-  tapebufs int
-      Default: 20. The number of buffers used by the taper process run by
-      amdump and amflush to hold data as it is read from the network or disk
-      before it is written to tape. Each buffer is a little larger than 32
-      KBytes and is held in a shared memory region.
-
-  reserve number
-      Default: 100. The part of holding-disk space that should be reserved for
-      incremental backups if no tape is available, expressed as a percentage of
-      the available holding-disk space (0-100). By default, when there is no
-      tape to write to, degraded mode (incremental) backups will be performed
-      to the holding disk. If full backups should also be allowed in this case,
-      the amount of holding disk space reserved for incrementals should be
-      lowered.
-
-  autoflush bool
-      Default: off. Whether an amdump run will flush the dump already on
-      holding disk to tape.
-
-  amrecover_do_fsf bool
-      Default: off. Amrecover will call amrestore with the -f flag for faster
-      positioning of the tape.
-
-  amrecover_check_label bool
-      Default: off. Amrecover will call amrestore with the -l flag to check the
-      label.
-
-  amrecover_changer string
-      Default: ''. Amrecover will use the changer if you use 'settape <string>'
-      and that string is the same as the amrecover_changer setting.
-
-  columnspec string
-      Defines the width of columns amreport should use. String is a comma (',')
-      separated list of triples. Each triple consists of three parts which are
-      separated by a equal sign ('=') and a colon (':') (see the example).
-      These three parts specify:
-
-      * the name of the column, which may be:
-
-        o Compress (compression ratio)
-        o Disk (client disk name)
-        o DumpRate (dump rate in KBytes/sec)
-        o DumpTime (total dump time in hours:minutes)
-        o HostName (client host name)
-        o Level (dump level)
-        o OrigKB (original image size in KBytes)
-        o OutKB (output image size in KBytes)
-        o TapeRate (tape writing rate in KBytes/sec)
-        o TapeTime (total tape time in hours:minutes)
-
-      * the amount of space to display before the column (used to get
-        whitespace between columns).
-      * the width of the column itself. If set to a negative value, the width
-        will be calculated on demand to fit the largest entry in this column.
-
-      Here is an example:
-
-        columnspec "Disk=1:18,HostName=0:10,OutKB=1:7"
-
-      The above will display the disk information in 18 characters and put one
-      space before it. The hostname column will be 10 characters wide with no
-      space to the left. The output KBytes column is seven characters wide with
-      one space before it.
-
   includefile string
-      Default: none. The name of an AMANDA configuration file to include within
+      Default: none. The name of an Amanda configuration file to include within
       the current file. Useful for sharing dumptypes, tapetypes and interface
       definitions among several configurations.
 
@@ -419,7 +102,7 @@ The options and values are:
   use int
       Default: 0 Gb. Amount of space that can be used in this holding disk
       area. If the value is zero, all available space on the file system is
-      used. If the value is negative, AMANDA will use all available space minus
+      used. If the value is negative, Amanda will use all available space minus
       that value.
 
   chunksize int
@@ -428,17 +111,15 @@ The options and values are:
       chunk will not exceed the specified value. However, even though dump
       images are split in the holding disk, they are concatenated as they are
       written to tape, so each dump image still corresponds to a single
-      continuous tape section.
-      If 0 is specified, AMANDA will create holding disk chunks as large as (
-      (INT_MAX/1024)-64) Kbytes.
-      Each holding disk chunk includes a 32 Kbyte header, so the minimum chunk
-      size is 64 Kbytes (but that would be really silly).
-      Operating systems that are limited to a maximum file size of 2 Gbytes
-      actually cannot handle files that large. They must be at least one byte
-      less than 2 Gbytes. Since AMANDA works with 32 Kbyte blocks, and to
-      handle the final read at the end of the chunk, the chunk size should be
-      at least 64 Kbytes (2 * 32 Kbytes) smaller than the maximum file size,
-      e.g. 2047 Mbytes.
+      continuous tape section. If 0 is specified, Amanda will create holding
+      disk chunks as large as ((INT_MAX/1024)-64) Kbytes. Each holding disk
+      chunk includes a 32 Kbyte header, so the minimum chunk size is 64 Kbytes
+      (but that would be really silly). Operating systems that are limited to a
+      maximum file size of 2 Gbytes actually cannot handle files that large.
+      They must be at least one byte less than 2 Gbytes. Since Amanda works
+      with 32 Kbyte blocks, and to handle the final read at the end of the
+      chunk, the chunk size should be at least 64 Kbytes (2 * 32 Kbytes)
+      smaller than the maximum file size, e.g. 2047 Mbytes.
 
 
 DUMPTYPE SECTION
@@ -470,11 +151,28 @@ The dumptype options and values are:
 
   auth string
       Default: bsd. Type of authorization to perform between tape server and
-      backup client hosts. May be krb4 to use Kerberos-IV authorization.
+      backup client hosts.
+      bsd, bsd authorization with udp initial connection and one tcp connection
+      by data stream.
+      bsdtcp, bsd authorization but use only one tcp connection.
+      bsdudp, like bsd, but will use only one tcp connection for all data
+      stream.
+      krb4 to use Kerberos-IV authorization.
+      krb5 to use Kerberos-V authorization.
+      rsh to use rsh authorization.
+      ssh to use OpenSSH authorization.
+
+  amandad_path string
+      Default: $libexec/amandad. Specify the amandad path of the client, only
+      use with rsh/ssh authentification.
+
+  client_username string
+      Default: CLIENT_LOGIN. Specify the username to connect on the client,
+      only use with rsh/ssh authentification.
 
   bumpsize int
       Default: 10 Mbytes. The minimum savings required to trigger an automatic
-      bump from one incremental level to the next, expressed as size. If AMANDA
+      bump from one incremental level to the next, expressed as size. If Amanda
       determines that the next higher backup level will be this much smaller
       than the current level, it will do the next level. The value of this
       parameter is used only if the parameter bumppercent is set to 0.
@@ -483,7 +181,7 @@ The dumptype options and values are:
   bumppercent int
       Default: 0 percent. The minimum savings required to trigger an automatic
       bump from one incremental level to the next, expressed as percentage of
-      the current size of the DLE (size of current level 0). If AMANDA
+      the current size of the DLE (size of current level 0). If Amanda
       determines that the next higher backup level will be this much smaller
       than the current level, it will do the next level.
       If this parameter is set to 0, the value of the parameter bumpsize is
@@ -491,7 +189,7 @@ The dumptype options and values are:
       See also the options bumpsize, bumpmult and bumpdays.
 
   bumpmult float
-      Default: 1.5. The bump size multiplier. AMANDA multiplies bumpsize by
+      Default: 1.5. The bump size multiplier. Amanda multiplies bumpsize by
       this factor for each level. This prevents active filesystems from bumping
       too much by making it harder to bump to the next level. For example, with
       the default bumpsize and bumpmult set to 2.0, the bump threshold will be
@@ -499,7 +197,7 @@ The dumptype options and values are:
       three, and so on.
 
   bumpdays int
-      Default: 2 days. To insure redundancy in the dumps, AMANDA keeps
+      Default: 2 days. To insure redundancy in the dumps, Amanda keeps
       filesystems at the same incremental level for at least bumpdays days,
       even if the other bump threshold criteria are met.
 
@@ -508,43 +206,73 @@ The dumptype options and values are:
 
   comprate float [, float ]
       Default: 0.50, 0.50. The expected full and incremental compression factor
-      for dumps. It is only used if AMANDA does not have any history
+      for dumps. It is only used if Amanda does not have any history
       information on compression rates for a filesystem, so should not usually
       need to be set. However, it may be useful for the first time a very large
       filesystem that compresses very little is backed up.
 
   compress [client|server] string
-      Default: client fast. If AMANDA does compression of the backup images, it
+      Default: client fast. If Amanda does compression of the backup images, it
       can do so either on the backup client host before it crosses the network
       or on the tape server host as it goes from the network into the holding
       disk or to tape. Which place to do compression (if at all) depends on how
       well the dump image usually compresses, the speed and load on the client
       or server, network capacity, holding disk capacity, availability of tape
       hardware compression, etc.
-      For either type of compression, AMANDA also allows the selection of two
+      For either type of compression, Amanda also allows the selection of three
       styles of compression. Best is the best compression available, often at
       the expense of CPU overhead. Fast is often not as good a compression as
-      best, but usually less CPU overhead.
+      best, but usually less CPU overhead. Or to specify Custom to use your own
+      compression method. (See dumptype custom-compress in example/amanda.conf
+      for reference)
       So the compress options line may be one of:
 
       * compress none
       * compress [client] fast
       * compress [client] best
+      * compress client custom
+        Specify client_custom_compress "PROG"
+        PROG must not contain white space and it must accept -d for uncompress.
       * compress server fast
       * compress server best
+      * compress server custom
+        Specify server_custom_compress "PROG"
+        PROG must not contain white space and it must accept -d for uncompress.
 
       Note that some tape devices do compression and this option has nothing to
       do with whether that is used. If hardware compression is used (usually
-      via a particular tape device name or mt option), AMANDA (software)
+      via a particular tape device name or mt option), Amanda (software)
       compression should be disabled.
 
   dumpcycle int
       Default: 10 days. The number of days in the backup cycle. Each disk using
-      this set of options will get a full backup at least this often. Setting
+      this set of options will get a full backup at least this of ten. Setting
       this to zero tries to do a full backup each run.
 
+  encrypt [none|client|server]
+      Default: none. To encrypt backup images, it can do so either on the
+      backup client host before it crosses the network or on the tape server
+      host as it goes from the network into the holding disk or to tape.
+      So the encrypt options line may be one of:
+
+      * encrypt none
+      * encrypt client
+        Specify client_encrypt "PROG"
+        PROG must not contain white space.
+        Specify client_decrypt_option "decryption-parameter" Default: "-d"
+        decryption-parameter must not contain white space.
+        (See dumptype server-encrypt-fast in example/amanda.conf for reference)
+      * encrypt server
+        Specify server_encrypt "PROG"
+        PROG must not contain white space.
+        Specify server_decrypt_option "decryption-parameter" Default: "-d"
+        decryption-parameter must not contain white space.
+        (See dumptype client-encrypt-nocomp in example/amanda.conf for
+        reference)
+
+
   estimate client|calcsize|server
-      Default: client. Determine the way AMANDA does it's estimate.
+      Default: client. Determine the way Amanda does it's estimate.
 
       * client:
         Use the same program as the dumping program, this is the most accurate
@@ -561,9 +289,13 @@ The dumptype options and values are:
       Default: file. There are two exclude lists, exclude file and exclude
       list. With exclude file , the string is a GNU-tar exclude expression.
       With exclude list , the string is a file name on the client containing
-      GNU-tar exclude expressions.
+      GNU-tar exclude expressions. The path to the specified exclude list file,
+      if present (see description of 'optional' below), must be readable by the
+      Amanda user.
       All exclude expressions are concatenated in one file and passed to GNU-
       tar as an --exclude-from argument.
+      Exclude expressions must always be specified as relative to the head
+      directory of the DLE.
       With the append keyword, the string is appended to the current list,
       without it, the string overwrites the list.
       If optional is specified for exclude list, then amcheck will not complain
@@ -579,7 +311,7 @@ The dumptype options and values are:
   holdingdisk boolean
       Default: yes. Whether a holding disk should be used for these backups or
       whether they should go directly to tape. If the holding disk is a portion
-      of another file system that AMANDA is backing up, that file system should
+      of another file system that Amanda is backing up, that file system should
       refer to a dumptype with holdingdisk set to no to avoid backing up the
       holding disk into itself.
 
@@ -594,9 +326,16 @@ The dumptype options and values are:
       list. With include file , the string is a glob expression. With include
       list , the string is a file name on the client containing glob
       expressions.
-      All include expressions are expanded by AMANDA, concatenated in one file
+      All include expressions are expanded by Amanda, concatenated in one file
       and passed to GNU-tar as a --files-from argument. They must start with
       "./" and contain no other "/".
+      Include expressions must always be specified as relative to the head
+      directory of the DLE.
+
+      Note
+
+      For globbing to work at all, even the limited single level, the top level
+      directory of the DLE must be readable by the Amanda user.
       With the append keyword, the string is appended to the current list,
       without it, the string overwrites the list.
       If optional is specified for include list, then amcheck will not complain
@@ -615,7 +354,7 @@ The dumptype options and values are:
       server host.
 
   maxdumps int
-      Default: 1. The maximum number of backups from a single host that AMANDA
+      Default: 1. The maximum number of backups from a single host that Amanda
       will attempt to run in parallel. See also the main section parameter
       inparallel.
 
@@ -625,7 +364,7 @@ The dumptype options and values are:
       overpromoted.
 
   priority string
-      Default: medium. When there is no tape to write to, AMANDA will do
+      Default: medium. When there is no tape to write to, Amanda will do
       incremental backups in priority order to the holding disk. The priority
       may be high (2), medium (1), low (0) or a number of your choice.
 
@@ -643,7 +382,7 @@ The dumptype options and values are:
   skip-full boolean
       Default: no. If true and planner has scheduled a full backup, these disks
       will be skipped, and full backups should be run off-line on these days.
-      It was reported that AMANDA only schedules level 1 incrementals in this
+      It was reported that Amanda only schedules level 1 incrementals in this
       configuration; this is probably a bug.
 
   skip-incr boolean
@@ -660,7 +399,7 @@ The dumptype options and values are:
 
 
         standard
-            The standard AMANDA schedule.
+            The standard Amanda schedule.
 
         nofull
             Never do full backups, only level 1 incrementals.
@@ -673,14 +412,38 @@ The dumptype options and values are:
 
         incronly
             Only do incremental dumps. amadmin force should be used to tell
-            AMANDA that a full dump has been performed off-line, so that it
+            Amanda that a full dump has been performed off-line, so that it
             resets to level 1. It is similar to skip-full, but with incronly
             full dumps may be scheduled manually. Unfortunately, it appears
-            that AMANDA will perform full backups with this configuration,
+            that Amanda will perform full backups with this configuration,
             which is probably a bug.
 
 
-The following dumptype entries are predefined by AMANDA:
+  tape_splitsize int
+      Default: none. Split dump file on tape into pieces of a specified size.
+      This allows dumps to be spread across multiple tapes, and can potentially
+      make more efficient use of tape space. Note that if this value is too
+      large (more than half the size of the average dump being split),
+      substantial tape space can be wasted. If too small, large dumps will be
+      split into innumerable tiny dumpfiles, adding to restoration complexity.
+      A good rule of thumb, usually, is 1/10 of the size of your tape.
+
+  split_diskbuffer string
+      Default: none. When dumping a split dump in PORT-WRITE mode (usually
+      meaning "no holding disk"), buffer the split chunks to a file in the
+      directory specified by this option.
+
+  fallback_splitsize int
+      Default: 10M. When dumping a split dump in PORT-WRITE mode, if no
+      split_diskbuffer is specified (or if we somehow fail to use our
+      split_diskbuffer), we must buffer split chunks in memory. This specifies
+      the maximum size split chunks can be in this scenario, and thus the
+      maximum amount of memory consumed for in-memory splitting. The size of
+      this buffer can be changed from its (very conservative) default to a
+      value reflecting the amount of memory that each taper process on the dump
+      server may reasonably consume.
+
+The following dumptype entries are predefined by Amanda:
 
   define dumptype no-compress {
       compress none
@@ -727,7 +490,7 @@ record option:
       record no
   }
 
-AMANDA provides a dumptype named global in the sample amanda.conf file that all
+Amanda provides a dumptype named global in the sample amanda.conf file that all
 dumptypes should reference. This provides an easy place to make changes that
 will affect every dumptype.
 
@@ -757,8 +520,8 @@ The tapetype options and values are:
 
   length int
       Default: 2000 kbytes. How much data will fit on a tape.
-      Note that this value is only used by AMANDA to schedule which backups
-      will be run. Once the backups start, AMANDA will continue to write to a
+      Note that this value is only used by Amanda to schedule which backups
+      will be run. Once the backups start, Amanda will continue to write to a
       tape until it gets an error, regardless of what value is entered for
       length (but see the section OUTPUT DRIVERS in the amanda(8) manpage for
       exceptions).
@@ -767,12 +530,12 @@ The tapetype options and values are:
       Default: 32. How much data will be written in each tape record expressed
       in KiloBytes. The tape record size (= blocksize) can not be reduced below
       the default 32 KBytes. The parameter blocksize can only be raised if
-      AMANDA was compiled with the configure option --with-maxtapeblocksize=N
+      Amanda was compiled with the configure option --with-maxtapeblocksize=N
       set with "N" greater than 32 during configure.
 
   file-pad boolean
       Default: true. If true, every record, including the last one in the file,
-      will have the same length. This matches the way AMANDA wrote tapes prior
+      will have the same length. This matches the way Amanda wrote tapes prior
       to the availability of this parameter. It may also be useful on devices
       that only support a fixed blocksize.
       Note that the last record on the tape probably includes trailing null
@@ -786,11 +549,11 @@ The tapetype options and values are:
 
   speed int
       Default: 200 bps. How fast the drive will accept data, in bytes per
-      second. This parameter is NOT currently used by AMANDA.
+      second. This parameter is NOT currently used by Amanda.
 
   lbl-templ string
       A PostScript template file used by amreport to generate labels. Several
-      sample files are provided with the AMANDA sources in the example
+      sample files are provided with the Amanda sources in the example
       directory. See the amreport(8) man page for more information.
 
 In addition to options, another tapetype name may be entered, which makes this
@@ -825,11 +588,11 @@ name is the name of this type of network interface. It is referenced from the
 disklist file.
 Note that these sections define network interface characteristics, not the
 actual interface that will be used. Nor do they impose limits on the bandwidth
-that will actually be taken up by AMANDA. AMANDA computes the estimated
+that will actually be taken up by Amanda. Amanda computes the estimated
 bandwidth each file system backup will take based on the estimated size and
 time, then compares that plus any other running backups with the limit as
 another of the criteria when deciding whether to start the backup. Once a
-backup starts, AMANDA will use as much of the network as it can leaving
+backup starts, Amanda will use as much of the network as it can leaving
 throttling up to the operating system and network hardware.
 The interface options and values are:
 
@@ -848,14 +611,14 @@ little use.
 AUTHOR
 
 James da Silva, <jds@amanda.org>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion, major update, splitting
 
 SEE ALSO
 
-amanda(8),
+amanda(8), amanda-client.conf(5), amcrypt(8), aespipe(1),
 -------------------------------------------------------------------------------
 
-Prev     Up      Next
-amanda  Home  amcheck
+Prev     Up                 Next
+amanda  Home  amanda-client.conf
 
index c3c06165fed63e8c2cae22e267a91dc9923103ef..91bcb328b89d276ef8e6397052e400c0c0804924 100644 (file)
@@ -1,21 +1,22 @@
 
                               amcheck
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amcheck \14 run AMANDA self-checks
+amcheck \14 run Amanda self-checks
 
 Synopsis
 
-amcheck [-mwsclt ] [-Maddress ] config [ host [disk...]...]
+amcheck [-am] [-w] [-sclt] [ -M | address ]* config [ host | [disk]*]* [ -o |
+configoption ]*
 
 DESCRIPTION
 
-Amcheck runs a number of self-checks on both the AMANDA tape server host and
-the AMANDA client hosts.
+Amcheck runs a number of self-checks on both the Amanda tape server host and
+the Amanda client hosts.
 On the tape server host, amcheck can go through the same tape checking used at
 the start of the nightly amdump run to verify the correct tape for the next run
 is mounted.
@@ -23,7 +24,7 @@ Amcheck can also do a self-check on all client hosts to make sure each host is
 running and that permissions on filesystems to be backed up are correct.
 You can specify many host/disk expressions, only disks that match an expression
 will be checked. All disks are checked if no expressions are given.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 OPTIONS
 
@@ -42,12 +43,12 @@ OPTIONS
       Run the tape tests on the server host.
 
   -w
-      Enables a destructive check for write-protection on the tape (which would
+      Enables a DESTRUCTIVE check for write-protection on the tape (which would
       otherwise cause the subsequent amdump to fail). If the tape is writable,
-      this check causes all data after the tape label to be erased (actually
-      depends on the device driver: there is no portable non-destructive way to
-      check for write-protection). The check implies -t and is only made if the
-      tape is otherwise correct.
+      this check causes all data after the tape label to be erased. If the
+      label_new_tapes option is enabled, this check may ERASE any non-Amanda
+      tape in the drive or changer. The check enable the tape tests on the
+      server host and is only made if the tape is otherwise correct.
 
   -m
       Nothing is printed, but mail is sent if any errors are detected. The mail
@@ -57,10 +58,16 @@ OPTIONS
   -a
       Like -m but the mail is always sent.
 
-  -Maddress
+  -M address
       Mail the report to address instead of the mailto value from amanda.conf.
       Implies -m.
 
+  host [disk]*
+      Specify the host and disk on which the command will work.
+
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
 The default is -cs.
 
 EXAMPLES
@@ -69,21 +76,21 @@ In this example, both the tape server and client tests are run. The results are
 displayed on standard output.
 
   % amcheck daily
-  AMANDA Tape Server Host Check
+  Amanda Tape Server Host Check
   -----------------------------
   /amanda2/amanda/work: 911475 KB disk space available, that's plenty.
   NOTE: skipping tape-writable test.
   Tape VOL10 label ok.
   Server check took 34.966 seconds.
 
-  AMANDA Backup Client Hosts Check
+  Amanda Backup Client Hosts Check
   --------------------------------
   WARNING: northstar: selfcheck request timed out.  Host down?
   WARNING: drinkme: selfcheck request timed out.  Host down?
   WARNING: scruffy: selfcheck request timed out.  Host down?
   Client check: 136 hosts checked in 51.945 seconds, 3 problems found.
 
-  (brought to you by AMANDA 2.4.5)
+  (brought to you by Amanda 2.5.0)
 
 In this example, if the line mailto csd-amanda is in amanda.conf, mail will be
 sent to csd-amanda if the server check returns an error.
@@ -143,7 +150,7 @@ MESSAGES
       instead of runuser.
 
   ERROR: program dir directory: not accessible
-      (error) The directory AMANDA expects to find its auxiliary programs in,
+      (error) The directory Amanda expects to find its auxiliary programs in,
       directory, is not accessible.
 
   ERROR: program program: does not exist
@@ -169,21 +176,21 @@ MESSAGES
 
 
         log
-            for the AMANDA log directory (see logdir in amanda.conf)
+            for the Amanda log directory (see logdir in amanda.conf)
 
         oldlog
             for the directory that holds the old log files (see logdir in
             amanda.conf)
 
         info
-            for an AMANDA database information directory (see curinfo in
+            for an Amanda database information directory (see curinfo in
             amanda.conf) or
 
         index
-            for an AMANDA index directory (see indexdir in amanda.conf)
+            for an Amanda index directory (see indexdir in amanda.conf)
 
         tapelist
-            for the AMANDA tapelist directory (see tapelist in amanda.conf)
+            for the Amanda tapelist directory (see tapelist in amanda.conf)
 
 
   NOTE: XXX dir directory: does not exist
@@ -216,16 +223,16 @@ MESSAGES
       not allow search permission.
 
   ERROR: tape list tapelist: not writable
-      (error) AMANDA tape list file tapelist (see tapelist in amanda.conf) is
+      (error) Amanda tape list file tapelist (see tapelist in amanda.conf) is
       not writable or was not found.
 
   ERROR: tape list tapelist: parse error
-      (error) AMANDA tape list file tapelist (see tapelist in amanda.conf)
+      (error) Amanda tape list file tapelist (see tapelist in amanda.conf)
       could not be read or parsed.
 
   WARNING: tapedev is /dev/null, dumps will be thrown away
       (warning) The tapedev parameter in amanda.conf is set to /dev/null and
-      AMANDA uses that when debugging to throw all the dump images away.
+      Amanda uses that when debugging to throw all the dump images away.
 
   WARNING: hold file file exists
       (info) Hold file file exists and will cause amdump to pause at the
@@ -265,7 +272,7 @@ MESSAGES
       enough for what is requested in amanda.conf.
 
   Holding disk disk: F KB disk space available, using U KB
-      (info) Holding disk disk has F KBytes of free space and AMANDA will be
+      (info) Holding disk disk has F KBytes of free space and Amanda will be
       using up to U Kbytes.
 
   WARNING: if a tape changer is not available, runtapes must be set to 1.
@@ -302,7 +309,7 @@ MESSAGES
       (info) The tape write test (see the -w option) was not enabled.
 
   WARNING: skipping tape test because amdump or amflush seem to be running,
-  WARNING: if they are not, you must run amcleanup,
+  WARNING: if they are not, you must run amcleanup
       (warning) It looked to amcheck like either amdump or amflush were running
       because a log file or amdump file exists. If they are not running, you
       probably need to run amcleanup to clear up a previous failure. Otherwise,
@@ -341,7 +348,7 @@ MESSAGES
 
   ERROR: host NAK: [NAK parse failed]
       (error) Amcheck could not parse the negative acknowledgment error from
-      host. There might be an AMANDA version mismatch between the host running
+      host. There might be an Amanda version mismatch between the host running
       amcheck and host.
 
   ERROR: host [mutual-authentication failed]
@@ -354,7 +361,7 @@ MESSAGES
 AUTHOR
 
 James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
@@ -362,6 +369,6 @@ SEE ALSO
 amanda(8), amdump(8)
 -------------------------------------------------------------------------------
 
-Prev          Up        Next
-amanda.conf  Home  amcheckdb
+Prev                 Up        Next
+amanda-client.conf  Home  amcheckdb
 
index c5b7ef3ee4933f94ecdd0c11461a8557f99aa712..8821ca600a73b2e9b42d311b37a5b12e3c1925b4 100644 (file)
@@ -1,12 +1,12 @@
 
                              amcheckdb
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amcheckdb \14 check AMANDA database for tape consistency
+amcheckdb \14 check Amanda database for tape consistency
 
 Synopsis
 
@@ -14,9 +14,9 @@ amcheckdb config
 
 DESCRIPTION
 
-Amcheckdb verifies that every tape mentioned in the AMANDA database is still
+Amcheckdb verifies that every tape mentioned in the Amanda database is still
 valid in the tapelist file.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 EXAMPLE
 
@@ -36,7 +36,7 @@ in the tapelist file:
 AUTHOR
 
 Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
index 6ad14edda2900c26011a254f41f97cf1d21294c2..8bb79bc4a71097fc586e5d77050cba022a1e6a29 100644 (file)
@@ -1,12 +1,12 @@
 
                              amcleanup
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amcleanup \14 run the AMANDA cleanup process after a failure
+amcleanup \14 run the Amanda cleanup process after a failure
 
 Synopsis
 
@@ -14,21 +14,21 @@ amcleanup config
 
 DESCRIPTION
 
-Amcleanup generates the AMANDA Mail Report and updates the AMANDA databases
+Amcleanup generates the Amanda Mail Report and updates the Amanda databases
 after a system failure on a tape server host. This cleanup process is normally
 done automatically as part of the amdump program, but if amdump cannot complete
 for some reason (usually because of a tape server host crash), amcleanup must
 be run some time later (usually during system boot).
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 EXAMPLES
 
-This example runs the AMANDA cleanup process by hand after a failure.
+This example runs the Amanda cleanup process by hand after a failure.
 
   % amcleanup daily
 
 Putting the following line in a system boot script (e.g. /etc/rc.local) runs
-the AMANDA cleanup process as part of the reboot, eliminating the need to run
+the Amanda cleanup process as part of the reboot, eliminating the need to run
 it by hand.
 
   /usr/local/sbin/amcleanup daily
@@ -41,7 +41,7 @@ If nothing needs to be done, amcleanup exits normally with the message:
 AUTHOR
 
 James da Silva, <jds@amanda.org>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
@@ -49,6 +49,6 @@ SEE ALSO
 amanda(8), amdump(8)
 -------------------------------------------------------------------------------
 
-Prev        Up   Next
-amcheckdb  Home  amdd
+Prev        Up      Next
+amcheckdb  Home  amcrypt
 
diff --git a/docs/amcrypt-asym-ossl.8.txt b/docs/amcrypt-asym-ossl.8.txt
new file mode 100644 (file)
index 0000000..5d287b4
--- /dev/null
@@ -0,0 +1,86 @@
+
+                       amcrypt-ossl-asym
+Prev  Chapter 36. The Amanda Manual Pages.  Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amcrypt-ossl-asym \14 crypt program for Amanda asymmetric data encryption using
+OpenSSL
+
+Synopsis
+
+amcrypt-ossl-asym [-d]
+
+DESCRIPTION
+
+amcrypt-ossl-asym uses OpenSSL to encrypt and decrypt data. OpenSSL is
+available from www.openssl.org. OpenSSL offers a wide variety of cipher choices
+( amcrypt-ossl-asym defaults to 256-bit AES) and can use hardware cryptographic
+accelerators on several platforms.
+amcrypt-ossl-asym will search for the OpenSSL program in the following
+directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+
+GENERATING PUBLIC AND PRIVATE KEYS
+
+RSA keys can be generated with the standard OpenSSL commands, e.g.:
+
+  $ cd /var/lib/amanda
+  $ openssl genrsa -aes128 -out backup-key.pem 1024
+  Generating RSA private key, 1024 bit long modulus
+  [...]
+  Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE
+  Verifying - Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE
+
+  $ openssl rsa -in backup-key.pem -pubout -out backup-pubkey.pem
+  Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE
+  Writing RSA key
+
+To generate a private key without a passphrase, omit the -aes128 option. See
+openssl_genrsa(1) for more key generation options.
+Note that it is always possible to generate the public key from the private
+key.
+
+KEY AND PASSPHRASE MANAGEMENT
+
+amcrypt-ossl-asym uses the public key to encrypt data. The security of the data
+does not depend on the confidentiality of the public key. The private key is
+used to decrypt data, and must be protected. Encrypted backup data cannot be
+recovered without the private key. The private key may optionally be encrypted
+with a passphrase.
+While the public key must be online at all times to perorm backups, the private
+key and optional passphrase are only needed to restore data. It is recommended
+that the latter be stored offline all other times. For example, you could keep
+the private key on removable media, and copy it into place for a restore; or
+you could keep the private key online, encrypted with a passphrase that is
+present only for a restore.
+OpenSSL's key derivation routines use a salt to guard against dictionary
+attacks on the pass phrase; still it is important to pick a pass phrase that is
+hard to guess. The Diceware method (see www.diceware.com) can be used to create
+passphrases that are difficult to guess and easy to remember.
+
+FILES
+
+
+
+  /var/lib/amanda/backup-privkey.pem
+      File containing the RSA private key. It should not be readable by any
+      user other than the Amanda user.
+
+  /var/lib/amanda/backup-pubkey.pem
+      File containing the RSA public key.
+
+  /var/lib/amanda/.pass
+      File containing the pass phrase. It should not be readable by any user
+      other than the Amanda user.
+
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), openssl(1), amcrypt-ossl(8)
+-------------------------------------------------------------------------------
+
+Prev           Up   Next
+amcrypt-ossl  Home  amdd
+
diff --git a/docs/amcrypt-ossl.8.txt b/docs/amcrypt-ossl.8.txt
new file mode 100644 (file)
index 0000000..c3eb0b6
--- /dev/null
@@ -0,0 +1,50 @@
+
+                           amcrypt-ossl
+Prev  Chapter 36. The Amanda Manual Pages.  Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amcrypt-ossl \14 crypt program for Amanda symmetric data encryption using OpenSSL
+
+Synopsis
+
+amcrypt-ossl [-d]
+
+DESCRIPTION
+
+amcrypt-ossl uses OpenSSL to encrypt and decrypt data. OpenSSL is available
+from www.openssl.org. OpenSSL offers a wide variety of cipher choices
+( amcrypt-ossl defaults to 256-bit AES) and can use hardware cryptographic
+accelerators on several platforms.
+amcrypt-ossl will search for the OpenSSL program in the following directories:
+/bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+
+PASSPHRASE MANAGEMENT
+
+amcrypt-ossl uses the same pass phrase to encrypt and decrypt data. It is very
+important to store and protect the pass phrase properly. Encrypted backup data
+can only be recovered with the correct passphrase.
+OpenSSL's key derivation routines use a salt to guard against dictionary
+attacks on the pass phrase; still it is important to pick a pass phrase that is
+hard to guess. The Diceware method (see www.diceware.com) can be used to create
+passphrases that are difficult to guess and easy to remember.
+
+FILES
+
+
+
+  /var/lib/amanda/.am_passphrase
+      File containing the pass phrase. It should not be readable by any user
+      other than the Amanda user.
+
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), openssl(1), amcrypt-ossl-asym(8)
+-------------------------------------------------------------------------------
+
+Prev      Up                Next
+amcrypt  Home  amcrypt-ossl-asym
+
diff --git a/docs/amcrypt.8.txt b/docs/amcrypt.8.txt
new file mode 100644 (file)
index 0000000..1282fd3
--- /dev/null
@@ -0,0 +1,56 @@
+
+                              amcrypt
+Prev  Chapter 36. The Amanda Manual Pages.  Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amcrypt \14 reference crypt program for Amanda symmetric data encryption
+
+Synopsis
+
+amcrypt
+
+DESCRIPTION
+
+amcrypt requires aespipe, uuencode and gpg to work. Aespipe is available from
+http://loop-aes.sourceforge.net
+amcrypt will search for the aespipe program in the following directories: /usr/
+bin:/usr/local/bin:/sbin:/usr/sbin.
+amcrypt calls amaespipe and pass the passphrase through file descriptor 3. The
+passphrase should be stored in ~amanda/.am_passphrase.
+
+How to create encryption keys for amcrypt
+
+1. Create 65 random encryption keys and encrypt those keys using gpg. Reading
+from /dev/random may take indefinitely long if kernel's random entropy pool is
+empty. If that happens, do some other work on some other console (use keyboard,
+mouse and disks).
+head -c 2925 /dev/random | uuencode -m - | head -n 66 | tail -n 65 \ | gpg --
+symmetric -a > ~amanda/.gnupg/am_key.gpg
+This will ask for a passphrase. Remember this passphrase as you will need it in
+the next step.
+2. Store the passphrase inside the home-directory of the AMANDA-user and
+protect it with proper permissions:
+
+  echo my_secret_passphrase > ~amanda/.am_passphrase
+  chown amanda:disk ~amanda/.am_passphrase
+  chmod 700 ~amanda/.am_passphrase
+
+
+Key and Passphrase
+
+amcrypt uses the same key to encrypt and decrypt data.
+It is very important to store and protect the key and the passphrase properly.
+Encrypted backup data can only be recovered with the correct key and
+passphrase.
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), aespipe(1), amaespipe(8), gpg(1)
+-------------------------------------------------------------------------------
+
+Prev        Up           Next
+amcleanup  Home  amcrypt-ossl
+
index 149d464f4f9a8a78a9b29f0202db59072b431147..13ea42b44dd368e0e5493592e07b497063b41ac3 100644 (file)
@@ -1,12 +1,12 @@
 
                                  amdd
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amdd \14 AMANDA version of dd
+amdd \14 Amanda version of dd
 
 Synopsis
 
@@ -15,13 +15,13 @@ amdd [-d ] [if=input] [of=output] [bs=blocksize] [skip=count] [count=count]
 DESCRIPTION
 
 Amdd provides just enough of the standard UNIX dd command for the needs of
-AMANDA. This is handy when doing a full restore and the standard dd program has
+Amanda. This is handy when doing a full restore and the standard dd program has
 not yet been found.
-Amdd also provides access to the AMANDA output drivers that support various
+Amdd also provides access to the Amanda output drivers that support various
 tape simulations. This may be used for debugging or to convert from one format
 to another.
-See the amanda(8) man page for more details about AMANDA. See the OUTPUT
-DRIVERS section of amanda(8) for more information on the AMANDA output drivers.
+See the amanda(8) man page for more details about Amanda. See the OUTPUT
+DRIVERS section of amanda(8) for more information on the Amanda output drivers.
 
 OPTIONS
 
@@ -72,7 +72,7 @@ OPTIONS
 AUTHOR
 
 Marc Mengel <mengel@fnal.gov>, John R. Jackson <jrj@purdue.edu> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
@@ -80,6 +80,6 @@ SEE ALSO
 amanda(8)
 -------------------------------------------------------------------------------
 
-Prev        Up     Next
-amcleanup  Home  amdump
+Prev                Up     Next
+amcrypt-ossl-asym  Home  amdump
 
index 9b03ee8af4011fc6e9b48e80e8e0a9a5ba32fdf0..6a0b299f2b5f8a2ef87e02c7bc185fe5db03573f 100644 (file)
@@ -1,20 +1,20 @@
 
                                amdump
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amdump \14 back up all disks in an AMANDA configuration
+amdump \14 back up all disks in an Amanda configuration
 
 Synopsis
 
-amdump config [ host [disk...]...]
+amdump config [ host | [disk]*]* [ -o | configoption ]*
 
 DESCRIPTION
 
-Amdump switches to the appropriate AMANDA configuration directory, e.g. /usr/
+Amdump switches to the appropriate Amanda configuration directory, e.g. /usr/
 local/etc/amanda/config, then attempts to back up every disk specified by the
 amanda.conf file. Amdump is normally run by cron.
 You can specify many host/disk expressions, only disks that match an expression
@@ -24,7 +24,18 @@ is removed before starting the backups. This allows scheduled backups to be
 delayed when circumstances warrant, for example, if the tape device is being
 used for some other purpose. While waiting, amdump checks for the hold file
 every minute.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
+
+OPTIONS
+
+
+
+  host [disk]*
+      Specify the host and disk on which the command will work.
+
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
 
 EXAMPLE
 
@@ -54,7 +65,7 @@ MESSAGES
 AUTHOR
 
 James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
@@ -62,6 +73,6 @@ SEE ALSO
 amanda(8), amcheck(8), amcleanup(8), amrestore(8), amflush(8), cron(8)
 -------------------------------------------------------------------------------
 
-Prev   Up      Next
-amdd  Home  amflush
+Prev   Up          Next
+amdd  Home  amfetchdump
 
diff --git a/docs/amfetchdump.8.txt b/docs/amfetchdump.8.txt
new file mode 100644 (file)
index 0000000..639c09d
--- /dev/null
@@ -0,0 +1,147 @@
+
+                           amfetchdump
+Prev  Chapter 36. The Amanda Manual Pages.  Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amfetchdump \14 extract backup images from multiple Amanda tapes.
+
+Synopsis
+
+amfetchdump [-pcClawns] [-d device] [-O directory] [-i logfile] [-b blocksize]
+config hostname [ disk [ date [ level [ hostname [...] ] ] ] ] [ -o |
+configoption ]*
+
+DESCRIPTION
+
+Amfetchdump 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.
+It will automatically use the logs created by amdump(8) to locate available
+dumps on tape, in the same way that the find feature of amadmin(8) lists
+available dumps. If these logs are unavailable, it can search tape-by-tape to
+find what it needs, and can generate new logs to serve as an emergency tape
+inventory.
+The hostname, diskname, datestamp, and level dump pattern-matching works as in
+amrestore(8), with the added requirement that at minimum a hostname must be
+specified when not in inventory mode.
+Unless -p is used, backup images are extracted to files in the current
+directory named:
+hostname.diskname.datestamp.dumplevel
+
+OPTIONS
+
+
+
+  -p
+      Pipe exactly one complete dump file to stdout, instead of writing the
+      file to disk. This will restore only the first matching dumpfile (where
+      "first" is determined by the dump log search facility).
+
+  -d device
+      Restore from this tape device instead of the default.
+
+  -O directory
+      Output restored files to this directory, instead of to the current
+      working directory.
+
+  -c
+      Compress output, fastest method available.
+
+  -C
+      Compress output, smallest file size method available.
+
+  -l
+      Leave dumps in the compressed/uncompressed state in which they were found
+      on tape. By default, amfetchdump will automatically uncompress when
+      restoring.
+
+  -a
+      Assume that all tapes are already available, via tape changer or
+      otherwise, instead of prompting the operator to ensure that all tapes are
+      loaded.
+
+  -i filename
+      Generate an inventory of all dumps "seen" on the tapes we search, for
+      later use as a log.
+
+  -w
+      Wait to put split dumps together until all chunks have been restored.
+      Normally, amfetchdump will attempt to read pieces of a split file from
+      tape in order, so that it can assemble them simply by appending each file
+      to the first. This option disables the appending behavior, and instead
+      restores each piece as an individual file and reassembles them only after
+      all have been restored.
+
+      Note
+
+      This requires at least double the size of your dump in free disk space,
+      in order to build the final assembled dumpfile.
+      This behavior is implicitly invoked in circumstances where knowing the
+      location of all dumps on tape in advance is not possible, such as when
+      you are restoring without log files.
+
+  -n
+      Do not reassemble split dump files at all, just restore each piece as an
+      individual file.
+
+  -s
+      Do not fast-forward straight to needed files on tape. This will slow down
+      most restores substantially. Only use this option if your tape drive does
+      not properly support the fast-forward operation.
+
+  -b blocksize
+      Force a particular block size when reading from tapes. This value will
+      usually be autodetected, and should not normally need to be set.
+
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
+
+EXAMPLES
+
+All the examples here assume your configuration is called SetA.
+Here's a simple case, restoring all known dumps of the host vanya to the
+current working directory.
+
+$ amfetchdump SetA vanya
+A more likely scenario involves restoring a particular dump from a particular
+date. We'll pipe this one to GNU-tar as well, to automatically extract the
+dump.
+
+$ amfetchdump -p SetA vanya /home 20051020 | gtar -xvpf -
+In a situation where all of our dump logs have been wiped out, we could also
+use amfetchdump to inventory our tapes and recreate an imitation of those logs,
+which we'll send to stdout for casual perusal.
+
+$ amfetchdump -i - SetA
+Note that you can specify a restore while in inventory mode, and amfetchdump
+will continue searching for more dumps from this host even after successfully
+restoring a dump, inventorying all the while. If your backup searcher has been
+trashed, this is a handy way to recover what you have.
+
+$ amfetchdump -i /var/amanda/log SetA backupserver
+
+CAVEATS
+
+Amfetchdump is dependent on accessing your server's config, tape changer, and
+(normally) dump logs. As such, it's not necessarily the most useful tool when
+those have all been wiped out and you desperately need to pull things from your
+tape. Pains have been taken to make it as capable as possible, but for
+seriously minimialist restores, look to amrestore(8) or dd(8) instead.
+
+AUTHOR
+
+John Stange, <building@nap.edu>, National Academies Press
+Ian Turner, <ian@zmanda.com>: XML-conversion
+
+SEE ALSO
+
+amanda(8), amadmin(8), amrestore(8), tar(1) restore(8)
+-------------------------------------------------------------------------------
+
+Prev     Up      Next
+amdump  Home  amflush
+
index 399bf06be980e7d525f4103be09b96b3019e2f31..8135968ed099dd88bb72d6e40a6d9f61da738af2 100644 (file)
@@ -1,21 +1,22 @@
 
                               amflush
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amflush \14 flush AMANDA backup files from holding disk to tape
+amflush \14 flush Amanda backup files from holding disk to tape
 
 Synopsis
 
-amflush [-b ] [-f ] [-s ] [ -D datestamp ...] config [ host [disk...]...]
+amflush [-b] [-f] [-s] [ -D | datestamp ]* config [ host | [disk]*]* [ -o |
+configoption ]*
 
 DESCRIPTION
 
-Amflush writes AMANDA backups from the holding disks to tape, and updates the
-AMANDA info database and tapelist accordingly. Backups may stay in a holding
+Amflush writes Amanda backups from the holding disks to tape, and updates the
+Amanda info database and tapelist accordingly. Backups may stay in a holding
 disk when something is wrong with the tape at the time amdump is run. When this
 happens, the problem must be corrected and amflush run by hand.
 
@@ -42,15 +43,21 @@ OPTIONS
       EXPRESSION" section of amanda(8) for a description. -D 20001225-7 will
       flush all dumps from 25 december 2000 to 27 december 2000.
 
+  host [disk]*
+      Specify the host and disk on which the command will work.
+
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
 You can specify many host/disk expressions, only disks that match an expression
 will be flushed. All disks are flushed if no expressions are given. see the
 "HOST & DISK EXPRESSION" section of amanda(8) for a description.
 Amflush will look in the holding disks specified by the amanda.conf file in /
-usr/local/etc/amanda/config for any non-empty AMANDA work directories. It then
+usr/local/etc/amanda/config for any non-empty Amanda work directories. It then
 prompts you to select a directory or to process all of the directories. The
 work directories in the holding disks are named by the date at the time amdump
 was run, e.g. 19910215.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 EXAMPLE
 
@@ -60,10 +67,10 @@ updates the databases and sends a mail report similar to amdump(8).
 
   % amflush daily
   Scanning /amanda-hold...
-    20001113: found AMANDA directory.
-    20001114: found AMANDA directory.
+    20001113: found Amanda directory.
+    20001114: found Amanda directory.
 
-  Multiple AMANDA directories, please pick one by letter:
+  Multiple Amanda directories, please pick one by letter:
     A. 20001113
     B. 20001114
   Select directories to flush [A..B]: [ALL] all
@@ -80,7 +87,7 @@ updates the databases and sends a mail report similar to amdump(8).
 AUTHOR
 
 James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
@@ -88,6 +95,6 @@ SEE ALSO
 amanda(8), amdump(8)
 -------------------------------------------------------------------------------
 
-Prev     Up        Next
-amdump  Home  amgetconf
+Prev          Up        Next
+amfetchdump  Home  amgetconf
 
index 46a380558c819df9a74317f058f58b256b085733..2282127ae1167e8defcbfa3e6edc783331e3386c 100644 (file)
@@ -1,6 +1,6 @@
 
                              amgetconf
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
@@ -10,11 +10,11 @@ amgetconf \14 look up amanda.conf variables
 
 Synopsis
 
-amgetconf [config] parameter
+amgetconf [config] parameter [ -o | configoption ]*
 
 DESCRIPTION
 
-Amgetconf looks up parameters in amanda.conf, the AMANDA configuration file, or
+Amgetconf looks up parameters in amanda.conf, the Amanda configuration file, or
 from the build and runtime environment, and returns their corresponding value.
 If config is not specified, amgetconf assumes it is being run from the
 configuration directory and that amanda.conf is present.
@@ -25,12 +25,20 @@ error and will return an empty string as the value. Flag variables (e.g.
 USE_AMANDAHOSTS) will return 1 if the flag is set or an empty string if it is
 not.
 If parameter begins with dbopen., the string following the period is a program
-name and an AMANDA debug file will be created for the caller. The name of the
+name and an Amanda debug file will be created for the caller. The name of the
 file is returned.
 If parameter begins with dbclose., the string following the period is a program
 name previously used with dbopen., followed by a colon (:) and the previously
 opened file name.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
+
+OPTIONS
+
+
+
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
 
 EXAMPLE
 
index 6fb8d17617c50d115dfcdc5b30db7dccbd2ee545..51709a08b2b200409d59921cba6cbd4fc046bc27 100644 (file)
@@ -1,41 +1,49 @@
 
                               amlabel
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amlabel \14 label an AMANDA tape
+amlabel \14 label an Amanda tape
 
 Synopsis
 
-amlabel [-f ] config label [ slot slot ]
+amlabel [-f ] config label [ slot | slot ] [ -o | configoption ]*
 
 DESCRIPTION
 
-All AMANDA tapes must be pre-labeled before they are used. AMANDA verifies the
+All Amanda tapes must be pre-labeled before they are used. Amanda verifies the
 label in amdump and amflush before writing to make sure the proper tape is
 loaded.
-Amlabel writes an AMANDA label on the tape in the device specified by the
+Amlabel writes an Amanda label on the tape in the device specified by the
 amanda.conf file in /usr/local/etc/amanda/config. Label may be any string that
 does not contain whitespace and that matches the amanda.conf labelstr regular
 expression option. It is up to the system administrator to define a naming
 convention.
-Amlabel appends the new tape to the tapelist file so it will be used by AMANDA
+Amlabel appends the new tape to the tapelist file so it will be used by Amanda
 before it reuses any other tapes. When you amlabel multiple tapes, they will be
 used in the order you amlabel them.
-Amlabel will not write the label if the tape contains an active AMANDA tape or
+Amlabel will not write the label if the tape contains an active Amanda tape or
 if the label specified is on an active tape. The -f (force) flag bypasses these
 verifications.
 An optional slot may be specified after the tape label. If a tape changer is in
 use, amlabel will label the tape in the specified slot instead of the currently
 loaded tape.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
+
+OPTIONS
+
+
+
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
 
 EXAMPLE
 
-Write an AMANDA label with the string "DMP000" on the tape loaded in the device
+Write an Amanda label with the string "DMP000" on the tape loaded in the device
 named in the tapedev option in /usr/local/etc/amanda/daily/amanda.conf:
 
   % amlabel daily DMP000
@@ -55,31 +63,31 @@ MESSAGES
       expression str from amanda.conf.
 
   label label already on a tape
-      Label label is already listed as an active AMANDA tape.
+      Label label is already listed as an active Amanda tape.
 
   no tpchanger specified in path , so slot command invalid
       The command line has the slot parameter but the amanda.conf file in path
       does not have a tape changer configured.
 
   reading label label, tape is in another amanda configuration
-      This tape appears to be a valid AMANDA tape, but label does not match
+      This tape appears to be a valid Amanda tape, but label does not match
       labelstr for this configuration so it is probably part of a different
-      AMANDA configuration.
+      Amanda configuration.
 
   reading label label, tape is active
-      Tape label appears to already be part of this AMANDA configuration and
+      Tape label appears to already be part of this Amanda configuration and
       active, i.e. has valid data on it.
 
   no label found, are you sure tape is non-rewinding?
       While checking that the label was written correctly, amlabel got an error
-      that might be caused by mis-configuring AMANDA with a rewinding tape
+      that might be caused by mis-configuring Amanda with a rewinding tape
       device name instead of a non-rewinding device name for tape.
 
 
 AUTHOR
 
 James da Silva, <jds@amanda.org>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
index 5b437edaab3aa373631ab19c19fd947622288446..353ef27f16f7e47492f0b441ec6d5ed72328ad95 100644 (file)
@@ -1,12 +1,12 @@
 
                                  ammt
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-ammt \14 AMANDA version of mt
+ammt \14 Amanda version of mt
 
 Synopsis
 
@@ -15,12 +15,12 @@ ammt [-d ] [ -f | -t | device ] command [count]
 DESCRIPTION
 
 Ammt provides just enough of the standard UNIX mt command for the needs of
-AMANDA. This is handy when doing a full restore and the standard mt program has
+Amanda. This is handy when doing a full restore and the standard mt program has
 not yet been found.
-Ammt also provides access to the AMANDA output drivers that support various
+Ammt also provides access to the Amanda output drivers that support various
 tape simulations.
-See the amanda(8) man page for more details about AMANDA. See the OUTPUT
-DRIVERS section of amanda(8) for more information on the AMANDA output drivers.
+See the amanda(8) man page for more details about Amanda. See the OUTPUT
+DRIVERS section of amanda(8) for more information on the Amanda output drivers.
 
 OPTIONS
 
@@ -105,7 +105,7 @@ Many systems only report good data when a tape is in the drive and ready.
 AUTHOR
 
 Marc Mengel <mengel@fnal.gov>, John R. Jackson <jrj@purdue.edu>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
index ccd7964cf9276f53febd98737b5cd26b86087e8e..a5f93e6dd78398c774aafd7846087fbb0eb4e08d 100644 (file)
@@ -1,23 +1,23 @@
 
                             amoverview
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amoverview \14 display file systems processed by AMANDA over time
+amoverview \14 display file systems processed by Amanda over time
 
 Synopsis
 
 amoverview [[-config ] config ] [-hostwidth width] [-diskwidth width] [-
-skipmissed] [-verbose]
+skipmissed] [-last] [-num0] [-togo0] [-verbose]
 
 DESCRIPTION
 
-Amoverview displays a chart showing hosts and file systems processed by AMANDA
+Amoverview displays a chart showing hosts and file systems processed by Amanda
 along with the backup level performed each day.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 OPTIONS
 
@@ -33,9 +33,19 @@ OPTIONS
       Set disk field column width to width characters instead of 20.
 
   -skipmissed
-      Compacts the output by only printing stats for the days AMANDA actually
+      Compacts the output by only printing stats for the days Amanda actually
       ran.
 
+  -last
+      Outputs the last status of each disk at the start. Useful for long
+      tapecycles and/or sparse reports.
+
+  -num0
+      Outputs the number of level 0 dumps for each disk.
+
+  -togo0
+      Outputs the number of runs until the last level 0 dump is overwritten.
+
   -verbose
       Amoverview can take a long while on large systems. This option reports
       intermediate steps while it is working.
@@ -53,7 +63,7 @@ You can have an "E" followed by a number if a filesystem ran into end-of-tape
 once (gives an "E", and later that day, you flush it to a second tape (a
 number: the level, indicating success). If the flush failed too, you get a
 double "EE" for that day.
-You can also have a double code if you have two tapes in the changer and AMANDA
+You can also have a double code if you have two tapes in the changer and Amanda
 failed to write to tape the first time because it hit end of tape (resulting in
 "E0", for a full, "E1" for an incremental etc.) or twice with error ("EE"), and
 may a successful flush afterwards giving maybe "EE0". (Only the latest 2
index 1f71f57ab3e59e09e2b5f284f8182a0122c2c61f..bba73ea083aa201d63965c8ead207607538d1452 100644 (file)
@@ -1,12 +1,12 @@
 
                                amplot
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amplot \14 visualize the behavior of AMANDA
+amplot \14 visualize the behavior of Amanda
 
 Synopsis
 
@@ -14,7 +14,7 @@ amplot [-b ] [-c ] [-e ] [-g ] [-l ] [-p ] [ -t T ] amdump_files
 
 DESCRIPTION
 
-Amplot reads an amdump output file that AMANDA generates each run (e.g.
+Amplot reads an amdump output file that Amanda generates each run (e.g.
 amdump.1) and translates the information into a picture format that may be used
 to determine how your installation is doing and if any parameters need to be
 changed. Amplot also prints out amdump lines that it either does not understand
@@ -26,7 +26,7 @@ the graph. The awk program is written in an enhanced version of awk, such as
 GNU awk (gawk version 2.15 or later) or nawk.
 During execution, amplot generates a few temporary files that gnuplot uses.
 These files are deleted at the end of execution.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 OPTIONS
 
@@ -80,7 +80,7 @@ AUTHOR
 
 Olafur Gudmundsson <ogud@tis.com>, Trusted Information Systems, formerly at
 University of Maryland, College Park: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 BUGS
index f957e7de39b2d361fbbf242ff6893a30a9947785..0833bc8301edbc7bd044e6127b239ec1794f203c 100644 (file)
@@ -1,47 +1,53 @@
 
                              amrecover
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amrecover \14 AMANDA index database browser
+amrecover \14 Amanda index database browser
 
 Synopsis
 
-amrecover [[-C ] config ] [ -s index-server ] [ -t tape-server ] [ -d tape-
-device ]
+amrecover [[-C ] | config ] [ -s | index-server ] [ -t | tape-server ] [ -d |
+tape-device ] [ -o | clientconfigoption ]*
 
 DESCRIPTION
 
-Amrecover browses the database of AMANDA index files to determine which tapes
+Amrecover browses the database of Amanda index files to determine which tapes
 contain files to recover. Furthermore, it is able to recover files.
 In order to restore files in place, you must invoke amrecover from the root of
 the backed up filesystem, or use lcd to move into that directory, otherwise a
 directory tree that resembles the backed up filesystem will be created in the
 current directory. See the examples below for details.
-See the amanda(8) man page for more details about AMANDA.
+Amrecover will read the amanda-client.conf file and the config/amanda-
+client.conf file.
+See the amanda(8) man page for more details about Amanda.
 
 OPTIONS
 
 
 Note
 
-The listed defaults map to the values you ran the configure-script with.
+The Default values are those set at compile-time. Use amrestore to recover
+client-encrypted or client-custom-compressed tapes.
 
 
   [ -C ] config
-      AMANDA configuration (default: daily).
+      Amanda configuration.
 
   -s index-server
-      Host that runs the index daemon (default: oops).
+      Host that runs the index daemon.
 
   -t tape-server
-      Host that runs the tape server daemon (default: 192.168.0.10).
+      Host that runs the tape server daemon.
 
   -d tape-device
-      Tape device to use on the tape server host (default: /dev/nst0).
+      Tape device to use on the tape server host.
+
+  -o clientconfigoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
 
 
 COMMANDS
@@ -57,8 +63,8 @@ be extracted from the backup system. The following commands are available:
       Specifies which host to look at backup files for (default: the local
       host).
 
-  setdate YYYY-MM-DD
-      Set the date (default: today). File listing commands only return
+  setdate YYYY-MM-DD-HH-MM[-SS] | YYYY-MM-DD
+      Set the restore time (default: now). File listing commands only return
       information on backup images for this day, for the day before with the
       next lower dump level, and so on, until the most recent level 0 backup on
       or before the specified date is encountered.
@@ -67,8 +73,8 @@ be extracted from the backup system. The following commands are available:
       1996-07-01 was a level 0 backup
       1996-07-02 through 1996-07-05 were level 1 backups
       1996-07-06 through 1997-07-08 were level 2 backups
-      then if 1997-07-08 is the requested date, files from the following days
-      would be used:
+      then the command setdate 1997-07-08-00 would yield files from the
+      following days:
 
       1997-07-08 (the latest level 2 backup)
       1997-07-05 (the latest level 1 backup)
@@ -86,7 +92,7 @@ be extracted from the backup system. The following commands are available:
 
 
 
-  setdisk diskname mountpoint
+  setdisk diskname [mountpoint]
       Specifies which disk to consider (default: the disk holding the working
       directory where amrecover is started). It can only be set after the host
       is set with sethost. Diskname is the device name specified in the
@@ -94,17 +100,20 @@ be extracted from the backup system. The following commands are available:
       host. If mountpoint is not specified, all pathnames will be relative to
       the (unknown) mount point instead of full pathnames.
 
+  listhost [diskdevice]
+      List all host
+
   listdisk [diskdevice]
       List all diskname
 
   settape [[server]:][tapedev|default]
       Specifies the host to use as the tape server, and which of its tape
       devices to use. If the server is omitted, but the colon is not, the
-      server name reverts to 192.168.0.10, the configure-time default. If the
-      tape device is omitted, it remains unchanged. To use the default tape
-      device selected by the tape server, the word default must be specified.
-      If no argument is specified, or the argument is an empty string, no
-      changes occur, and the current settings are displayed.
+      server name reverts to the configure-time default. If the tape device is
+      omitted, it remains unchanged. To use the default tape device selected by
+      the tape server, the word default must be specified. If no argument is
+      specified, or the argument is an empty string, no changes occur, and the
+      current settings are displayed.
       If you want amrecover to use your changer, the tapedev must be equal to
       the amrecover_changer setting on the server.
       If you need to change the protocol (tape:, rait:, file:, null:) then you
@@ -181,7 +190,7 @@ be extracted from the backup system. The following commands are available:
   list file
       Display the contents of the restore list. If a file name is specified,
       the restore list is written to that file. This can be used to manually
-      extract the files from the AMANDA tapes with amrestore.
+      extract the files from the Amanda tapes with amrestore.
 
   clear
       Clear the restore list.
@@ -211,7 +220,7 @@ The following shows the recovery of an old syslog file.
   syslog.7: No such file or directory
   # amrecover
   AMRECOVER Version 2.4.2. Contacting server on oops ...
-  220 oops AMANDA index server (2.4.2) ready.
+  220 oops Amanda index server (2.4.2) ready.
   Setting restore date to today (1997-12-09)
   200 Working date set to 1997-12-09.
   200 Config set to daily.
@@ -336,16 +345,22 @@ ENVIRONMENT
 
 PAGER The ls and list commands will use $PAGER to display the file lists.
 Defaults to more if PAGER is not set.
+AMANDA_SERVER If set, $AMANDA_SERVER will be used as index-server. The value
+will take precedence over the compiled default, but will be overridden by the -
+s switch.
+AMANDA_TAPE_SERVER If set, $AMANDA_TAPE_SERVER will be used as tape-server. The
+value will take precedence over the compiled default, but will be overridden by
+the -t switch.
 
 AUTHOR
 
 Alan M. McIvor <alan@kauri.auck.irl.cri.nz> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
 
-amanda(8), amrestore(8), readline(3)
+amanda(8), amanda-client.conf(5), amrestore(8), amfetchdump(8), readline(3)
 -------------------------------------------------------------------------------
 
 Prev     Up       Next
index 3f27de1b8825eac50c1f5b869668084a899ee600..cb176caa89369b25fc9f8f4370ff5c0f3f6f2c75 100644 (file)
@@ -1,23 +1,24 @@
 
                               amreport
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amreport \14 generate a formatted output of statistics for an AMANDA run
+amreport \14 generate a formatted output of statistics for an Amanda run
 
 Synopsis
 
-amreport [config] [ -l logfile ] [ -f outputfile ] [ -p postscriptfile ]
+amreport [config] [-i] [ -M | address ] [ -l | logfile ] [ -f | outputfile ]
+[ -p | postscriptfile ] [ -o | configoption ]*
 
 DESCRIPTION
 
 Amreport generates a summary report of an amanda(8) backup run. If no
 configuration name is specified, amanda.conf is read from the current
 directory.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 OPTIONS
 
@@ -26,6 +27,12 @@ OPTIONS
   config
       Name of the configuration to process.
 
+  -i
+      Don't email the report.
+
+  -M address
+      Mail the report to address instead of the mailto value from amanda.conf.
+
   -l logfile
       Name of the log file to parse to generate the report. If a log file is
       not specified, it defaults to the file:
@@ -44,10 +51,13 @@ where logdir is the log directory defined in amanda.conf.
       lpr(1) command. This option has an effect only if the lbl-templ directive
       is specified in amanda.conf.
 
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
 
 LABEL PRINTING
 
-AMANDA can print postscript labels describing the contents of tape(s) written
+Amanda can print postscript labels describing the contents of tape(s) written
 in a run. The labels are designed to be folded and inserted into the tape case
 along with the tape or hole punched and put in a 3-ring binder. Various label
 templates are provided to format data for different tape sizes.
@@ -63,7 +73,7 @@ the system default printer.
 
 TEMPLATES
 
-AMANDA provides label templates for the following tape types. These are pretty
+Amanda provides label templates for the following tape types. These are pretty
 generic labels and should be easy to customize for other tape types or
 particular site needs.
 
index 61603ea77af1efbb09ca278807280df9d7e626b8..2b5f66d2cb5a2251c2fee20d7092de292e4e5b2a 100644 (file)
@@ -1,18 +1,18 @@
 
                              amrestore
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amrestore \14 extract backup images from an AMANDA tape
+amrestore \14 extract backup images from an Amanda tape
 
 Synopsis
 
-amrestore [ -r | -c | -C ] [ -b blocksize ] [ -f fileno ] [ -l label ] [-p ] [-
-h ] tapedevice | holdingfile | [ hostname [ diskname [ datestamp [ hostname
-[ diskname [datestamp...]]]]]]
+amrestore [ -r | -c | -C ] [ -b | blocksize ] [ -f | fileno ] [ -l | label ] [-
+p] [-h] tapedevice | holdingfile [ hostname [ diskname [ datestamp [ hostname
+[ diskname [ datestamp | ... ]]]]]]
 
 DESCRIPTION
 
@@ -94,6 +94,11 @@ block size, and you should set it to 2. See the example below.
 If a header is written (-r or -h), only 32 KBytes are output regardless of the
 tape blocksize. This makes the resulting image usable as a holding file.
 
+
+  -o configoption
+      See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
+
 EXAMPLES
 
 The following does an interactive restore of disk rz3g from host seine, to
@@ -132,7 +137,7 @@ AUTHOR
 
 James da Silva, <jds@amanda.org>, University of Maryland, College Park:
 Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
index fd37e97fce5367cbe839bc9ea633e48f40dd3efc..ffe340a14a4357143f0075ad4590cfc43957b96e 100644 (file)
@@ -1,12 +1,12 @@
 
                               amrmtape
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amrmtape \14 remove a tape from the AMANDA database
+amrmtape \14 remove a tape from the Amanda database
 
 Synopsis
 
@@ -18,7 +18,7 @@ Amrmtape invalidates the contents of an existing backup tape in the
 configuration database. This is meant as a recovery mechanism when a good
 backup is damaged either by faulty hardware or user error, e.g. the tape is
 eaten by the drive or is overwritten.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 OPTIONS
 
@@ -49,7 +49,7 @@ Remove tape labeled DAILY034 from the DailySet1 configuration.
 AUTHOR
 
 Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
index fdb9d9a1873e6ccaff8544052e48d23bb5ab2214..2f0e1c323faae164cd57cdb2c522ccb98d2bf885 100644 (file)
@@ -1,12 +1,12 @@
 
                               amstatus
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amstatus \14 display the state of an AMANDA run
+amstatus \14 display the state of an Amanda run
 
 Synopsis
 
@@ -16,11 +16,11 @@ waitdumping ] [--waittaper ] [--dumpingtape ] [--writingtape ] [--finished ] [-
 
 DESCRIPTION
 
-Amstatus gives the current state of the AMANDA run specified by the config
-configuration. If there is no active AMANDA running, it summarizes the result
+Amstatus gives the current state of the Amanda run specified by the config
+configuration. If there is no active Amanda running, it summarizes the result
 of the last run. It may also be used to summarize the results of a previous
 run.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 OPTIONS
 
@@ -29,7 +29,7 @@ options are given, everything is displayed.
 
 
   [--config] config
-      Specify the AMANDA configuration you want to display the state for.
+      Specify the Amanda configuration you want to display the state for.
 
   --file amdumpfile
       Specify an alternate file instead of the amdump or amflush file.
index 232cc339d34256a9ffafbf4958df97a831912bc3..b8f930e4595b6e24902992480cae58cc99e0d048 100644 (file)
@@ -1,12 +1,12 @@
 
                                amtape
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amtape \14 user interface to AMANDA tape changer controls
+amtape \14 user interface to Amanda tape changer controls
 
 Synopsis
 
@@ -15,14 +15,14 @@ amtape config command [ command options ]
 DESCRIPTION
 
 Amtape performs tape changer control operations. It uses the underlying tape
-changer script defined by the tpchanger option for a particular AMANDA
+changer script defined by the tpchanger option for a particular Amanda
 configuration as specified by the config argument.
 Tape changers maintain a notion of the current and next slot for each
 configuration. These may or may not correspond to an actual physical state of
 the device, but do tend to minimize searching through the tape storage slots.
 If the desired tape is in the current slot, it is likely the next tape needed
 is in the next slot rather than at some random position in the storage slots.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
 
 COMMANDS
 
@@ -32,7 +32,7 @@ COMMANDS
       Reset the tape changer to a known state. The current slot is set to the
       first slot. Other device-specific side effects may occur. Some gravity
       stackers need to be reset to the top position by hand. This command
-      notifies AMANDA the stacker is back in that position.
+      notifies Amanda the stacker is back in that position.
 
   eject
       If a tape is loaded in the drive, it is ejected and returned to the slot
@@ -46,7 +46,7 @@ COMMANDS
       Show the contents of all slots. This can be slow.
 
   label label
-      Search for and load the AMANDA tape with label label.
+      Search for and load the Amanda tape with label label.
 
   taper
       Perform the taper scan algorithm. Load the next tape in the
@@ -91,7 +91,7 @@ COMMANDS
       tape, but do not load it.
 
 This is useful with non-gravity stackers to unload the last tape used and set
-up AMANDA for the next run. If you just use eject, the current tape will be
+up Amanda for the next run. If you just use eject, the current tape will be
 mounted again in the next run, where it will be rejected as being still in use,
 ejected and the next tape requested. Using slot next followed by eject does an
 unnecessary mount.
@@ -101,7 +101,7 @@ it is the one being requested.
 AUTHOR
 
 James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
index 0e482db202f9501736f0e0d84d4f9abbc94d97de..4e726a4b418bb28f99c9ea3ca6667030bc30a075 100644 (file)
@@ -1,6 +1,6 @@
 
                             amtapetype
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
@@ -15,7 +15,7 @@ t typename]
 
 DESCRIPTION
 
-amtapetype generates a tapetype entry for AMANDA.
+amtapetype generates a tapetype entry for Amanda.
 
 OPTIONS
 
@@ -29,7 +29,7 @@ OPTIONS
       takes a few minutes only.
 
   -o
-      Overwrite the tape, even if it's an AMANDA tape.
+      Overwrite the tape, even if it's an Amanda tape.
 
   -bblocksize
       record block size (default: 32k)
index 5d475b6402a256907de81685a92af2ebe06f5c88..4260b7fb2aab441636735bd6d98aaa18c1f0f5dc 100644 (file)
@@ -1,12 +1,12 @@
 
                                 amtoc
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amtoc \14 generate TOC (Table Of Contents) for an AMANDA run
+amtoc \14 generate TOC (Table Of Contents) for an Amanda run
 
 Synopsis
 
@@ -14,7 +14,7 @@ amtoc [-a ] [-i ] [-t ] [ -f file ] [ -s subs ] [-w ] [-- ] logfile
 
 DESCRIPTION
 
-Amtoc generates a table of contents for an AMANDA run. It's a perl script (if
+Amtoc generates a table of contents for an Amanda run. It's a perl script (if
 you don't have perl, install it first!).
 
 OPTIONS
@@ -89,7 +89,7 @@ AUTHOR
 
 Nicolas Mayencourt <Nicolas.Mayencourt@cui.unige.ch>, University of Geneva/
 Switzerland : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 -------------------------------------------------------------------------------
 
index fcee013ac60dc5868f88b17abe4fd55ef9c81e85..c4e11f5607ebb01cd8818c92e22d5351cee23346 100644 (file)
@@ -1,6 +1,6 @@
 
                               amverify
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
@@ -34,7 +34,7 @@ See the amanda(8) man page for more details about Amanda.
 AUTHOR
 
 Axel Zinser <fifi@icem.de> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
 XML-conversion
 
 SEE ALSO
index 0f542417d32a5192b891f82d332ac2881c55198a..59a3bfe49a7e5369419843716b5fe59f2464fe29 100644 (file)
@@ -1,12 +1,12 @@
 
                            amverifyrun
-Prev  Chapter 35. The AMANDA Manual Pages.  Next
+Prev  Chapter 36. The Amanda Manual Pages.  Next
 
 -------------------------------------------------------------------------------
 
 Name
 
-amverifyrun \14 check the tapes written by the last AMANDA run
+amverifyrun \14 check the tapes written by the last Amanda run
 
 Synopsis
 
@@ -14,7 +14,7 @@ amverifyrun config
 
 DESCRIPTION
 
-Amverifyrun read the log from the last AMANDA run to find the slot of the first
+Amverifyrun read the log from the last Amanda run to find the slot of the first
 tape used and the number of tapes used. It call amverify with these argument.
 
 SEE ALSO
@@ -23,5 +23,5 @@ amanda(8), amverify(8)
 -------------------------------------------------------------------------------
 
 Prev       Up                         Next
-amverify  Home  Chapter 36. Web Ressources
+amverify  Home  Chapter 37. Web Ressources
 
index eb50c21fc59d01c55308ee83c71d23492cd77ffa..f0d523be3644953f883e3f6e4c85d28ac495c547 100644 (file)
@@ -23,7 +23,7 @@ Table of Contents
 
   Notes_about_changer.conf
 
-  AMANDA's_actual_usage_of_chg-scsi
+  Amanda's_actual_usage_of_chg-scsi
 
   Configuration_notes
 
@@ -37,7 +37,7 @@ this document.
 Jason's new and improved chg-scsi documentation.
 This documentation will also include an occasional reference to the mtx suite
 as I have attempted to use chg-zd-mtx. I use mtx often as a fast query tool.
-Please also refer to AMANDA_Tape_Changer_Support for additional details.
+Please also refer to Amanda_Tape_Changer_Support for additional details.
 My equipment list is as follows:
 
 * Redhat 7.0 machine
@@ -53,7 +53,7 @@ My equipment list is as follows:
 I base this documentation on the following:
 
 * mtx version 1.2.16rel
-* AMANDA version 2.4.3b3
+* Amanda version 2.4.3b3
 * SCSI2 specification: X3T9.2/375R revision 10L
 * Quantum/ATL Field Service Manual 6321101-03 Ver.3, rel.0
 * Quantum DLT800 Tape system product manual 02 April, 2001 81-60118-04
@@ -62,8 +62,8 @@ I base this documentation on the following:
 
 Note that Quantum/ATL's L-series changers follow the SCSI command set, and do
 not use any proprietary commands. Thus, it was fairly simple to make this work.
-I had to install AMANDA --with-suffixes and setup my server's client side of
-things using AMANDA-2.4.2p2 --with-suffixes.
+I had to install Amanda --with-suffixes and setup my server's client side of
+things using Amanda-2.4.2p2 --with-suffixes.
 Please note that my usage of "barcode" and "barcode reader" throughout this
 document really refers to "physical tape identification system". for example:
 the EEPROM in the AIT cartridge.
@@ -86,9 +86,9 @@ chg-scsi's command line options:
   -scan
   -genconf
 
-Note that chg-scsi is called by AMANDA in the context of whatever AMANDA
-configuration AMANDA is currently using. In short, to call chg-scsi by hand,
-change to your AMANDA configuration directory, then run chg-scsi.
+Note that chg-scsi is called by Amanda in the context of whatever Amanda
+configuration Amanda is currently using. In short, to call chg-scsi by hand,
+change to your Amanda configuration directory, then run chg-scsi.
 -slot <param> command:
 this command takes either a slot number, or any one of the following: current,
 next, prev, first, last, advance
@@ -114,7 +114,7 @@ labelfile with the given parameter as it's tape header. I have not tested this.
 -search <param> command:
 this only should be used if a barcode reader is present, or emulate barcode is
 turned on.
-the required parameter is an AMANDA tape label. The label searched in the
+the required parameter is an Amanda tape label. The label searched in the
 labelfile. If a barcode is found, then that tape is loaded directly.
 I believe the fallback is to search the entire magazine.
 -status command:
@@ -128,7 +128,7 @@ present only for a particular type of changer.
 -inventory: (this takes a LONG time to do)
 unloads tape back to its slot issues command to changer to do an inventory of
 itself (read all barcodes...)
-loads each tape, retrieves the barcode, and reads the AMANDA
+loads each tape, retrieves the barcode, and reads the Amanda
 label off of the tape itself stores/updates the label database file
 -dumpdb:
 prints out in human readable form the label database contents from the
@@ -139,7 +139,7 @@ name and the device types. I found that linux didn't classify either of my tape
 devices as generic, but this facility did.
 USE THIS FOR FINDING VALUE OF SCSItapedev. Be certain though you have the
 correct tape drive: I came close to wreaking havoc with my DDS3 drive while it
-was flushing AMANDA data...and my changer has a DLT drive! Please refer to my
+was flushing Amanda data...and my changer has a DLT drive! Please refer to my
 configuration notes below.
 -genconf:
 prints out a SAMPLE changer.conf file. Note that I said sample. except for that
@@ -206,12 +206,12 @@ other values are (taken from the code)
 cleanmax cleancart cleanfile I have my changer set to autoclean, and the slot
 the cleaning cartridge is in is not available for any other use.
 
- AMANDA's actual usage of chg-scsi
+ Amanda's actual usage of chg-scsi
 
-this should be brief: AMANDA really only issues "slot next" type commands.
-Currently AMANDA doesn't ask chg-scsi to load "tape x with label Daily_set023".
+this should be brief: Amanda really only issues "slot next" type commands.
+Currently Amanda doesn't ask chg-scsi to load "tape x with label Daily_set023".
 the chg-scsi mechanism is there for use, and functions quite well for the user
-to load a particular tape. I understand they (the AMANDA team) are working on
+to load a particular tape. I understand they (the Amanda team) are working on
 this.
 
  Configuration notes
@@ -227,7 +227,7 @@ tapedev to 0 set changerdev to /dev/<changer generic device>
 
 in changer.conf: set number_configs to 1 set dev to <non-rewinding tape device
 eg: /dev/nst1> set debug to 9:0
-run "chg-scsi -scan" from your AMANDA configuration directory I get: name /dev/
+run "chg-scsi -scan" from your Amanda configuration directory I get: name /dev/
 sg0 Tape Count 1 name /dev/sg1 Changer Count 2 name /dev/sg2 Tape Count 3
 I set SCSItapedev to /dev/sg0 to test with, then ran chg-scsi -info. Check the
 chg-scsi debug file for tapeidentification details. This is where I discoverd
@@ -261,6 +261,6 @@ My desires are:
 -------------------------------------------------------------------------------
 
 Prev                            Up                                   Next
-Chapter 8. AMANDA Tape Changer Home  Chapter 10. RAIT (Redundant Array of
+Chapter 8. Amanda Tape Changer Home  Chapter 10. RAIT (Redundant Array of
 Support                                         Inexpensive Tape) Support
 
index 72c68efc6a801d87f7a3e49c6d8dee8b29986f46..770e1d585a9dfa6b849f2dddc3933203e4692c30 100644 (file)
@@ -1,10 +1,10 @@
 
-        Chapter 22. AMANDA dumper API
+        Chapter 23. Amanda dumper API
 Prev  Part V. Technical Background  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 22. AMANDA dumper API
+Chapter 23. Amanda dumper API
 
 
 Alexandre Oliva
@@ -53,23 +53,23 @@ this document.
 
  Introduction
 
-This is a proposal of a mechanism for AMANDA to support arbitrary backup
+This is a proposal of a mechanism for Amanda to support arbitrary backup
 programs, that relies on a generic backup driver and scripts or programs that
 interface with backup programs such as dump, tar, smbclient, and others. It can
 also be used to introduce pre- and post-backup commands.
 The interface is simple, but supports everything that is currently supported by
-AMANDA, and it can be consistently extended to support new abstractions that
+Amanda, and it can be consistently extended to support new abstractions that
 may be introduced in the backup driver in the future.
-This proposal does not imply any modification in the AMANDA protocol or in
-AMANDA servers; only AMANDA clients have to be modified. By AMANDA clients, we
-refer to hosts whose disks are to be backed up; an AMANDA server is a host
+This proposal does not imply any modification in the Amanda protocol or in
+Amanda servers; only Amanda clients have to be modified. By Amanda clients, we
+refer to hosts whose disks are to be backed up; an Amanda server is a host
 connected to a tape unit.
-Currently (as of release 2.4.1 of AMANDA), AMANDA clients support three
+Currently (as of release 2.4.1 of Amanda), Amanda clients support three
 operations: selfcheck, estimate and backup.
 Selfcheck is used by the server program amcheck, to check whether a client is
 responding or if there are configuration or permission problems in the client
 that might prevent the backup from taking place.
-Estimates are requested by the AMANDA planner, that runs on the server and
+Estimates are requested by the Amanda planner, that runs on the server and
 collects information about the expected sizes of backups of each disk at
 several levels. Given this information and the amount of available tape space,
 the planner can select which disks and which levels it should tell dumper to
@@ -78,7 +78,7 @@ dumper is yet another server-side program; it requests clients to perform
 dumps, as determined by planner, and stores these dumps in holding disks or
 sends them directly to the taper program. The interaction between dumper and
 taper is beyond the scope of this text.
-We are going to focus on the interaction between the AMANDA client program and
+We are going to focus on the interaction between the Amanda client program and
 wrappers of dump programs. These wrappers must implement the DUMPER API. The
 dumptype option `program' should name the wrapper that will be used to back up
 filesystems of that dumptype. One wrapper may call another, so as to extend its
@@ -106,13 +106,13 @@ on the last backup, be it a full or an incremental backup (0-inf++). Some
 support incrementals based on a timestamp (incr/date); whereas others are based
 on a limited number of incremental levels, but incrementals of the same level
 can be repeated, such as dump (0-9).
-AMANDA was originally built upon DUMP incremental levels, so this is the only
+Amanda was originally built upon DUMP incremental levels, so this is the only
 model it currently supports. Backup programs that use other incremental
 management mechanisms had to be adapted to this policy. Wrapper scripts are
 responsible for this adaptation.
 Another important issue has to do with index generation. Some backup programs
 can generate indexes, but each one lists files in its own particular format,
-but they must be stored in a common format, so that the AMANDA server can
+but they must be stored in a common format, so that the Amanda server can
 manipulate them.
 The DUMPER API must accomodate for all these variations.
 
@@ -128,16 +128,16 @@ should be printed to stderr, and the program should terminate with exit status
 
  The `support' command
 
-As a general mechanism for AMANDA to probe for features provided by a backup
+As a general mechanism for Amanda to probe for features provided by a backup
 program, a wrapper script must support at least the `support' command. Some
-features must be supported, and AMANDA won't ever ask about them. Others will
-be considered as extensions, and AMANDA will ask the wrapper whether they are
+features must be supported, and Amanda won't ever ask about them. Others will
+be considered as extensions, and Amanda will ask the wrapper whether they are
 supported before issuing the corresponding commands.
 
  The `level-incrementals' subcommand
 
 For example, before requesting for an incremental backup of a given level,
-AMANDA should ask the wrapper whether the backup program supports level-based
+Amanda should ask the wrapper whether the backup program supports level-based
 incrementals. We don't currently support backup programs that don't, but we may
 in the future, so it would be nice if wrappers already implemented the command
 `support level-incrementals', by returning a 0 exit status, printing, say, the
@@ -217,7 +217,7 @@ implying that the inquired feature is not supported.
  The `selfcheck' command
 
 We should support commands to perform self-checks, run estimates, backups and
-restores (for future extensions of the AMANDA protocol so as to support
+restores (for future extensions of the Amanda protocol so as to support
 restores)
 A selfcheck request would go like this:
 DUMP selfcheck hda0 option option=value ...
@@ -229,7 +229,7 @@ Errors should be printed as:
 ERROR [/etc/dumpdates is not writable]
 A wrapper script will certainly have to figure out either the disk device name
 or its mount point, given a filesystem name such as `hda0', as specified in the
-disklist. In order to help these scripts, AMANDA provides a helper program that
+disklist. In order to help these scripts, Amanda provides a helper program that
 can guess device names, mount points and filesystem types, when given disklist
 entries.
 The filesystem type can be useful on some operation systems, in which more than
@@ -255,7 +255,7 @@ to stdout the informations needed by the `estimate-parse' command, that should
 extract from its input the estimated size.
 The syntax of `estimate-parse' is identical to that of `estimate'.
 Both `estimate' and `estimate-parse' can output the word `KILL', after printing
-the estimate. In this case, AMANDA will send a SIGTERM signal to the process
+the estimate. In this case, Amanda will send a SIGTERM signal to the process
 group of the `estimate' process. If it does not die within a few seconds, a
 SIGKILL will be issued.
 If `estimate' or `estimate-parse' succeed, they should exit 0, otherwise exit
@@ -320,6 +320,6 @@ and/or the API. Some help on its implementation would be welcome, too.
 -------------------------------------------------------------------------------
 
 Prev                                     Up                           Next
-Chapter 21. How AMANDA uses UDP and TCP Home  Chapter 23. AMANDA Internals
+Chapter 22. How Amanda uses UDP and TCP Home  Chapter 24. Amanda Internals
 ports 
 
index f36daa33c08bb2087f3aa1e82fd6bf8b4c010876..dd8e2821f000bb32d689d3e792a02701c6e76746 100644 (file)
@@ -1,10 +1,10 @@
 
-         Chapter 24. AMANDA Event API
+         Chapter 25. Amanda Event API
 Prev  Part V. Technical Background  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 24. AMANDA Event API
+Chapter 25. Amanda Event API
 
 
 Mike Grupenhoff
@@ -32,6 +32,8 @@ Table of Contents
 
         event_loop
 
+        event_wait
+
         event_wakeup
 
 
@@ -101,6 +103,12 @@ until all events have been released. If the argument is nonzero, this will do
 one pass over all pending events, and fire the ones that are immediately ready,
 and then return.
 
+ event_wait
+
+void event_wait(event_id_t id);
+Like event_loop(0), except that it will stop as soon as the event id is
+serviced.
+
  event_wakeup
 
 int event_wakeup(event_id_t id);
@@ -163,5 +171,5 @@ argument equal to the argument this event was registered with.
 -------------------------------------------------------------------------------
 
 Prev                           Up                              Next
-Chapter 23. AMANDA Internals  Home  Chapter 25. AMANDA Security API
+Chapter 24. Amanda Internals  Home  Chapter 26. Amanda Security API
 
index 239e5cbcd62c8854370af2c17aa03dcaa7ff1225..16a953077c64f8a37cd0fd4e6925b2736975f73d 100644 (file)
@@ -52,14 +52,14 @@ this document.
  Introduction
 
 There are times when data needs to be excluded from a backup. When these times
-arise be confident that AMANDA has this capability. (Actually it's not AMANDA,
-it's tar.) There are three ways of excluding data in an AMANDA backup:
+arise be confident that Amanda has this capability. (Actually it's not Amanda,
+it's tar.) There are three ways of excluding data in an Amanda backup:
 
 * Exclude an individual item explicitly in the dumptype
 * Utilize an "Exclude List"
 * Do not include the data in the disklist
 
-This document is based on AMANDA 2.4.2 and some of this might not work with
+This document is based on Amanda 2.4.2 and some of this might not work with
 older versions. This was compiled from my personal experience and with help
 from the members of the amanda-users mailing list (mailto://amanda-
 users@amanda.org) when I was originally setting this up, to whom I wish to
@@ -68,7 +68,7 @@ thank for all of their support.
  Please Read
 
 As far as I am able to tell the only way to exclude files or directories with
-AMANDA is to use GNU-tar as the dump program (others?). The file system dump
+Amanda is to use GNU-tar as the dump program (others?). The file system dump
 programs provided with unix systems (e.g. dump, ufsdump) get data at a raw
 drive level and generally do not allow exclusion of specific files or
 directories.
@@ -83,7 +83,7 @@ The only exception that I am aware of is to just not include the data in
 question in the disklist. This option may not be suitable for everyone's needs
 and can confuse the issue some, so I have elected to include this mechanism in
 its own section named Do_not_include_the_data_in_the_disklist.
-For the purpose of this document an AMANDA backup configuration named "exclude-
+For the purpose of this document an Amanda backup configuration named "exclude-
 test" will be used. The machine that contains the tape drive which receives
 data to be archived will be referred to as "SERVER". The machine that data is
 being archived from will be referred to as "CLIENT". These two systems are
@@ -92,7 +92,7 @@ machine. Parts of this setup are on the server and some are on the client.
 
 Note
 
-When AMANDA attempts to exclude a file or directory it does so relative to the
+When Amanda attempts to exclude a file or directory it does so relative to the
 area being archived. For example if /var is in your disklist and you want to
 exclude /var/log/somefile, then your exclude file would contain ./log/somefile.
 You may use one exclude file in multiple dumptypes without any restriction.
@@ -100,18 +100,18 @@ You may use one exclude file in multiple dumptypes without any restriction.
  Before We Begin
 
 The first step that should be taken is to verify that backups are currently
-working. Connect to SERVER and run amcheck as your AMANDA user, to verify that
+working. Connect to SERVER and run amcheck as your Amanda user, to verify that
 there are no errors in the current setup.
 
   $ amcheck -cl CLIENT
 
 Output should look something like below for success:
 
-       AMANDA Tape Server Host Check
+       Amanda Tape Server Host Check
        -----------------------------
 
        /path/to/holding-disk: 4771300 KB disk space available, that's plenty.
-       AMANDA Backup Client Hosts Check
+       Amanda Backup Client Hosts Check
        --------------------------------
        Client check: 1 host checked in 0.084 seconds, 0 problems found.
 
@@ -148,12 +148,12 @@ the need is to exclude multiple files or directories then use an Exclude List.
 
 The easiest way to exclude a file or directory is to specify it with the
 "exclude" option in the dumptype. This option accepts an argument of the file
-or directory to be excluded. AMANDA allows only one exclude option in any
+or directory to be excluded. Amanda allows only one exclude option in any
 dumptype at a time.
 
 Note
 
-UPDATE: Recent AMANDA-releases bring the option "exclude append" which enables
+UPDATE: Recent Amanda-releases bring the option "exclude append" which enables
 the administrator to define more than one exclusion-pattern within one dumptype
 without using a exclude-list. Please look at the amanda.conf.5-manpage for
 details.
@@ -169,7 +169,7 @@ above, the dumptype would now look like:
   }
 
 Next run amcheck again to verify that there are no problems with the revised
-AMANDA configuration. If the data is not being excluded as expected please see
+Amanda configuration. If the data is not being excluded as expected please see
 the Troubleshooting section below. This completes the setup of excluding an
 individual item in the dumptype.
 
@@ -189,7 +189,7 @@ Connect to CLIENT and create the exclude directory as root. For example:
   $ mkdir -p /usr/local/etc/amanda/exclude
   $ cd /usr/local/etc/amanda/exclude
 
-Next create the exclude list for AMANDA to use. You can name the exclude file
+Next create the exclude list for Amanda to use. You can name the exclude file
 anything you wish it to be. Create a file, and in this file place all paths to
 files and directories that are to be excluded. Keeping with the /var example,
 assume that /var/log/XFree86.0.log, and /var/log/maillog need to be excluded.
@@ -205,8 +205,8 @@ example:
   $ chmod 644 /usr/local/etc/amanda/exclude/exclude-filename
 
 This concludes the necessary configuration on the client.
-Connect to SERVER and cd to the exclude-test AMANDA configuration directory.
-Edit the AMANDA configuration file e.g. amanda.conf. Add an entry similar to
+Connect to SERVER and cd to the exclude-test Amanda configuration directory.
+Edit the Amanda configuration file e.g. amanda.conf. Add an entry similar to
 the following line, to the dumptype for the client in question, where the
 exclude-filename is the file that was created on CLIENT in the step above
 including the quotes. For example:
@@ -223,14 +223,14 @@ The new dumptype should look something like:
   }
 
 Save the file. Run amcheck again to verify that there are no problems with the
-revised AMANDA configuration. If amcheck succeeds then run amdump to verify the
+revised Amanda configuration. If amcheck succeeds then run amdump to verify the
 data is being excluded correctly. If the data is not being excluded as expected
 please see the Troubleshooting section below. This completes the setup of an
 exclude list.
 
  Do not include the data in the disklist
 
-AMANDA uses disklist entries to define which directories or partitions should
+Amanda uses disklist entries to define which directories or partitions should
 be archived. This allows us to exclude data by just not placing the data in
 question in the disklist. Assume that there is a disk mounted on /example. The
 directory /example has five subdirectories "a", "b", "c", "d", and "e". The
@@ -243,7 +243,7 @@ contain:
   CLIENT /examples/b   exclude-test
   CLIENT /examples/c   exclude-test
 
-Run amcheck to verify that AMANDA is working correctly. If the data is not
+Run amcheck to verify that Amanda is working correctly. If the data is not
 being excluded as expected please see the Troubleshooting section below. This
 completes the setup of using a disklist to exclude data.
 
@@ -261,7 +261,7 @@ backup image but nothing below it.
 
  Wildcard Expansion
 
-AMANDA has the ability to use wildcard expansion while excluding data as
+Amanda has the ability to use wildcard expansion while excluding data as
 implemented by tar(1). The only places that wildcard expansion is allowed is in
 the "exclude" option in the dumptype, or in the exclude list. Some simple
 examples:
@@ -297,7 +297,7 @@ the script.
  Broken gnutar?
 
 There are versions of GNU-tar that do not correctly exclude data. Version 1.12
-(plus the AMANDA patches from http://www.amanda.org) are known to work
+(plus the Amanda patches from http://www.amanda.org) are known to work
 correctly, as does version 1.13.19 (and later). Anything else is questionable.
 
 Note
@@ -335,5 +335,5 @@ Subscription information is available at http://www.amanda.org.
 -------------------------------------------------------------------------------
 
 Prev                                   Up                              Next
-Chapter 2. AMANDA Installation Notes  Home  Chapter 4. Indexing with AMANDA
+Chapter 2. Amanda Installation Notes  Home  Chapter 4. Indexing with Amanda
 
index 560862a0d5572e6974407703021ed39fe25023bc..82fb691b6787a9e238a22af0b1518698cfa19bf3 100644 (file)
@@ -1,13 +1,13 @@
 
-             Chapter 17. AMANDA FAQ
+             Chapter 19. Amanda FAQ
 Prev  Part IV. Various Information  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 17. AMANDA FAQ
+Chapter 19. Amanda FAQ
 
 
-AMANDA Core Team
+Amanda Core Team
 
 AMANDA Core Team
 
@@ -22,22 +22,22 @@ Note
 Refer to http://www.amanda.org/docs/faq.html for the current version of this
 document.
 This file contains answers to some questions that are frequently asked in the
-AMANDA mailing lists, specially by new users. Please take a look at this file
-before posting, this can save us time that could be spent improving AMANDA and
+Amanda mailing lists, specially by new users. Please take a look at this file
+before posting, this can save us time that could be spent improving Amanda and
 its documentation.
 New entries and modifications are welcome; send them to mailto://amanda-
 users@amanda.org or mailto://amanda-hackers@amanda.org.
-You may also want to take a look at the AMANDA FAQ-O-Matic http://
+You may also want to take a look at the Amanda FAQ-O-Matic http://
 www.amanda.org/fom-serve/cache/1.html.
 
 
-  Why_does_AMANDA_fail_to_build_on_my_system?
+  Why_does_Amanda_fail_to_build_on_my_system?
 
   Why_does_amdump_report_that_all_disks_failed?
 
   Why_does_amcheck_say_"port_NNN_is_not_secure"?
 
-  Why_does_amcheck_claim_that_the_tape_is_"not_an_AMANDA_tape"?
+  Why_does_amcheck_claim_that_the_tape_is_"not_an_Amanda_tape"?
 
   Why_does_amcheck_report_"selfcheck_request_timed_out"?
 
@@ -54,19 +54,21 @@ www.amanda.org/fom-serve/cache/1.html.
 
   Which_tape_changer_configuration_should_I_use_in_amanda.conf?
 
+  Where_do_I_get_my_tapetype-definition_from?_Do_I_have_to_run_amtapetype?
+
   Should_I_use_software_or_hardware_compression?
 
-  How_can_I_configure_AMANDA_so_that_it_performs_full_backups_on_the_week-end
+  How_can_I_configure_Amanda_so_that_it_performs_full_backups_on_the_week-end
   and_incrementals_on_weekdays?
 
   What_if_my_tape_unit_uses_expensive_tapes,_and_I_don't_want_to_use_one_tape
-  per_day?_Can't_AMANDA_append_to_tapes?
+  per_day?_Can't_Amanda_append_to_tapes?
 
-  How_can_I_configure_AMANDA_for_long-term_archiving?
+  How_can_I_configure_Amanda_for_long-term_archiving?
 
   Can_I_backup_separate_disks_of_the_same_host_in_different_configurations?
 
-  Can_AMANDA_span_large_filesystems_across_multiple_tapes?
+  Can_Amanda_span_large_filesystems_across_multiple_tapes?
 
   What's_the_difference_between_option_"skip-full"_and_"strategy_nofull"?
 
@@ -78,24 +80,31 @@ www.amanda.org/fom-serve/cache/1.html.
 
   amdump_reported_"infofile_update_failed"._What_should_I_do?
 
-  Why_does_AMANDA_sometimes_promote_full_dumps?
+  Why_does_Amanda_sometimes_promote_full_dumps?
 
   Why_does_amrecover_report_"no_index_records"_or_"disk_not_found"?
 
-  Ok,_I'm_done_with_testing_AMANDA,_now_I_want_to_put_it_in_production._How_can
+  Ok,_I'm_done_with_testing_Amanda,_now_I_want_to_put_it_in_production._How_can
   I_reset_its_databases_so_as_to_start_from_scratch?
 
   The_man-page_of_dump_says_that_active_filesystems_may_be_backed_up
-  inconsistently._What_does_AMANDA_do_to_prevent_inconsistent_backups?
+  inconsistently._What_does_Amanda_do_to_prevent_inconsistent_backups?
 
   Which_version_of_GNU-tar_should_I_use?
 
-  What_does_"bumping"bumping_mean?
+  What_does_"bumping"_mean?
 
   How_do_I_backup_a_Windows_server?
 
+  How_do_I_tell_my_iptables-based_firewall_to_allow_Amanda_through?
+
+  How_do_I_get_rid_of_pressing_"q"_to_get_rid_of_a_pager_prompt_when_using
+  amrecover?
+
+  Is_there_a_way_to_tell_the_pager_that_my_terminal_has_"y"_lines?
+
 
- Why does AMANDA fail to build on my system?
+ Why does Amanda fail to build on my system?
  One of the most common reasons for compile-time errors is stale information in
  config.cache, after a build on a different platform using the same build tree.
  In order to avoid this problem, make sure you don't ever reuse build trees
@@ -105,34 +114,34 @@ www.amanda.org/fom-serve/cache/1.html.
  in libtool that causes it to search for symbols in already-installed amanda
  libraries, instead of in the just-built ones. This problem is known to affect
  SunOS 4.1.3 and FreeBSD. You can usually work around it by specifying a
- different prefix when you configure the new version of AMANDA. However, it may
- not work if the previous version of AMANDA was installed in /usr/local and gcc
+ different prefix when you configure the new version of Amanda. However, it may
+ not work if the previous version of Amanda was installed in /usr/local and gcc
  searches this directory by default; in this case, you must either remove the
  old libraries (which you don't want to do, right? :-) or call configure with
- the flag --disable-libtool. In this case, AMANDA won't create shared
+ the flag --disable-libtool. In this case, Amanda won't create shared
  libraries, so binaries will be larger, but you may worry about that later.
- You may also want to take a look at AMANDA_2.4.x_-_System-Specific
- Installation_Notes, as well as to the AMANDA Patches Page (http://
+ You may also want to take a look at Amanda_2.5.0_-_System-Specific
+ Installation_Notes, as well as to the Amanda Patches Page (http://
  www.amanda.org/patches/) for other known problems. If everything fails, you
  should read the manual, but since we don't have one yet, just post a help
  request to the amanda-users mailing list (mailto://amanda-users@amanda.org),
  showing the last few lines of the failed build.
  Why does amdump report that all disks failed?
- Probably because the AMANDA clients are not properly configured. Before you
+ Probably because the Amanda clients are not properly configured. Before you
  ever run amdump, make sure amcheck succeeds. When it does, so should amdump.
  Make sure you run amcheck as the same user that is supposed to start amdump,
  otherwise you may get incorrect results.
  Why does amcheck say "port NNN is not secure"?
- Because amcheck, as some other AMANDA programs, must be installed as setuid-
- root. Run make install as "root", or chown all AMANDA setuid programs to
+ Because amcheck, as some other Amanda programs, must be installed as setuid-
+ root. Run make install as "root", or chown all Amanda setuid programs to
  "root", then chown u+s them again, if chown drops the setuid bit.
- Why does amcheck claim that the tape is "not an AMANDA tape"?
- Because AMANDA requires you to label tapes before it uses them. Run amlabel in
+ Why does amcheck claim that the tape is "not an Amanda tape"?
+ Because Amanda requires you to label tapes before it uses them. Run amlabel in
  order to label a tape.
  If, even after labeling a tape, amcheck still complains about it, make sure
  the regular expression specified in amanda.conf matches the label you have
  specified, and check whether you have configured non-rewinding tape devices
- for AMANDA to use. For example, use /dev/nrst0 instead of /dev/rst0, /dev/rmt/
+ for Amanda to use. For example, use /dev/nrst0 instead of /dev/rst0, /dev/rmt/
  0bn instead of /dev/rmt/0b, or some other system-dependent device name that
  contains an "n", instead of one that does not. The "n" stands for non-
  rewinding.
@@ -140,8 +149,8 @@ www.amanda.org/fom-serve/cache/1.html.
  have to label them again.
  Why does amcheck report "selfcheck request timed out"?
  This can occur under several different situations. First, make sure this
- problem is repeatable; if AMANDA programs are NFS-auto-mounted, some clients
- may fail to mount the AMANDA binaries in time.
+ problem is repeatable; if Amanda programs are NFS-auto-mounted, some clients
+ may fail to mount the Amanda binaries in time.
  If the error is repeatable, log into the client, and check whether the
  directory /tmp/amanda exists, and a file named amandad.debug exists in there:
  amandad will create this file whenever it starts. If this file does not exist,
@@ -149,7 +158,7 @@ www.amanda.org/fom-serve/cache/1.html.
  amanda/amandad.debug.
  In the latter case, wipe out /tmp/amanda, and amandad should create it next
  time it runs. In the former case, check your inetd configuration. Make sure
- you have added the AMANDA services to /etc/services (or the NIS services map),
+ you have added the Amanda services to /etc/services (or the NIS services map),
  that /etc/inetd.conf was properly configured, and that you have signalled
  inetd to reread this file (some systems may need rebooting). Check section 2.2
  from in the Amanda_Installation_Notes for details. Check the inetd man-page
@@ -161,7 +170,7 @@ www.amanda.org/fom-serve/cache/1.html.
  specified at configure-time (configure --with-user=<USERNAME>) is listed in /
  etc/inetd.conf. Check whether this user has permission to run amandad, as well
  as any shared libraries amandad depends upon, by running the specified amandad
- command by hand, as the AMANDA user. It should just time-out after 30 seconds
+ command by hand, as the Amanda user. It should just time-out after 30 seconds
  waiting for a UDP packet. If you type anything, it will abort immediately,
  because it can't read a UDP packet from the keyboard.
  As soon as you have properly configured /etc/inetd.conf so as to run amandad,
@@ -174,8 +183,8 @@ www.amanda.org/fom-serve/cache/1.html.
  try to read a UDP packet from the keyboard, and this was reported not to work
  on most keyboards :-). However, if you have run amandad as any user other than
  the one listed in /etc/inetd.conf, it may have created a /tmp/amanda directory
- that the AMANDA user cannot write to, so you should wipe it out.
- Another possibility is that the AMANDA service was not properly configured as
+ that the Amanda user cannot write to, so you should wipe it out.
+ Another possibility is that the Amanda service was not properly configured as
  a UDP service; check /etc/services and /etc/inetd.conf.
  Why does amcheck say "access as <username> not allowed..."?
  There must be something wrong with .amandahosts configuration (or .rhosts, if
@@ -189,27 +198,27 @@ www.amanda.org/fom-serve/cache/1.html.
  names.
  Why does amcheck report "ip address #.#.#.#" is not in the ip list list for
  <hostname>'?
- Check your DNS configuration tables. In order to avoid DNS-spoofing, AMANDA
+ Check your DNS configuration tables. In order to avoid DNS-spoofing, Amanda
  double-checks hostname<->IP address mapping. If the IP address the request
  comes from maps to a hostname, but this hostname does not map back to the
  incoming IP address, the request is denied.
  Why does amcheck say "cannot overwrite active tape"?
- Because, if you configure AMANDA to use N tapes, by setting tapecycle to N in
- amanda.conf, before AMANDA overwrites a tape, it must write to at least other
- N-1 tapes. Of course, AMANDA will always refuse to overwrite a tape marked for
- `noreuse' with amadmin. Furthermore, such tapes are not counted when AMANDA
+ Because, if you configure Amanda to use N tapes, by setting tapecycle to N in
+ amanda.conf, before Amanda overwrites a tape, it must write to at least other
+ N-1 tapes. Of course, Amanda will always refuse to overwrite a tape marked for
+ `noreuse' with amadmin. Furthermore, such tapes are not counted when Amanda
  computes `N-1' tapes.
- If, for some reason, you want to tell AMANDA to overwrite a particular tape,
+ If, for some reason, you want to tell Amanda to overwrite a particular tape,
  regardless of its position in the cycle, use amrmtape. This command will
  remove this tape from the tapelist file, that is used to manage the tape
  cycle, and will delete information about backups stored in that tape from the
- AMANDA database.
+ Amanda database.
  Why does amcheck tell me "DUMP program not available"?
  Because configure could not find dump when it was first run. This is a common
  problem on Linux hosts, because most Linux distributions do not install dump
  by default.
  If you don't have a DUMP program installed, install it, remove config.cache,
- run configure again and rebuild AMANDA. While configure is running, make sure
+ run configure again and rebuild Amanda. While configure is running, make sure
  it can find the installed DUMP program. If it cannot, you may have to set the
  environment variables DUMP and RESTORE by hand, before running configure.
  If you can't or don't want to install DUMP, you may use GNU tar, but make sure
@@ -236,22 +245,39 @@ www.amanda.org/fom-serve/cache/1.html.
  mtx, for example, is available for several platforms. However, even if you
  find it for your platform, beware that there exist several different programs
  named mtx, that require different command line arguments, and print different
- output, and AMANDA's chg-mtx does not support them all. You may have to edit
+ output, and Amanda's chg-mtx does not support them all. You may have to edit
  the script, which shouldn't be hard to do.
- In section BUILT-IN TAPE CHANGERS of AMANDA_Tape_Changer_Support you will find
- details about the tape changer interfacing programs provided with AMANDA, that
+ In section BUILT-IN TAPE CHANGERS of Amanda_Tape_Changer_Support you will find
+ details about the tape changer interfacing programs provided with Amanda, that
  can interact with common tape changer programs and with tape changer-related
  system calls provided by some operating system. If none of them matches your
  needs, you may have to develop your own tape changer interface script.
- Before posting a question to the AMANDA mailing lists, *please* search the
+ Before posting a question to the Amanda mailing lists, *please* search the
  archives, and try to obtain as much information about driving your tape
  changer hardware from the vendor of the changer hardware and of the operating
- system, rather than from the AMANDA mailing lists. We usually don't have much
+ system, rather than from the Amanda mailing lists. We usually don't have much
  to say about tape changer units, and several questions about them remain
  unanswered. :-(
  Anyway, if you decide to post a question, make sure you specify both the tape
  changer hardware *and* the OS/platform that is going to interface with it.
  Good luck! :-)
+ Where do I get my tapetype-definition from? Do I have to run amtapetype?
+ It is not mandatory to run amtapetype at installation-time. It is very likely
+ that your tapedrive or -changer is one of the devices that are already covered
+ by one of the existing tapetype-definitions.
+ You may find tapetype-definitions in the example amanda.conf, in the
+ mailinglist-archives of the amanda-users-mailinglist at http://
+ marc.theaimsgroup.com/?l=amanda-users or in the Amanda-FAQ-O-Matic at http://
+ www.amanda.org/fom-serve/cache/1.html.
+ Reasons to run amtapetype for your device:
+
+ * You want to generate your own tapetype-definition because you can't find any
+   suitable tapetype-definition for your device.
+ * You want to determine the performance of your device.
+ * You want to determine if your device has hardware-compression enabled.
+
+ If you decide to run amtapetype, please refer to the chapter Tapetypes and the
+ manpage amtapetype(8).
  Should I use software or hardware compression?
  When you enable software compression, you drastically reduce the compression
  that might be achieved by hardware. In fact, tape drives will usually use
@@ -259,28 +285,30 @@ www.amanda.org/fom-serve/cache/1.html.
  data.
  Thus, you must choose whether you're going to use software or hardware
  compression; don't ever enable both unless you want to waste tape space.
- Since AMANDA prefers to have complete information about tape sizes and
+ Since Amanda prefers to have complete information about tape sizes and
  compression rates, it can do a better job if you use software compression.
- However, if you can't afford the extra CPU usage, AMANDA can live with the
+ However, if you can't afford the extra CPU usage, Amanda can live with the
  unpredictability of hardware compression, but you'll have to be very
  conservative about the specified tape size, specially if there are filesystems
  that contain mostly uncompressible data.
- How can I configure AMANDA so that it performs full backups on the week-end
+ You might want to run amtapetype to determine if you have hardware-compression
+ enabled for your tape-drive.
+ How can I configure Amanda so that it performs full backups on the week-end
  and incrementals on weekdays?
- You can't. AMANDA doesn't work this way. You just have to tell AMANDA how many
+ You can't. Amanda doesn't work this way. You just have to tell Amanda how many
  tapes you have (tapecycle), and how often you want it to perform full backups
  of each filesystem (dumpcycle). If you don't run it once a daily (including
- Saturdays and Sundays :-), you'll also want to tell AMANDA how many times
+ Saturdays and Sundays :-), you'll also want to tell Amanda how many times
  you'll run it per dumpcycle (runspercycle). It will spread full backups along
  the dumpcycle, so you won't have any full-only or incremental-only runs.
  Please also refer to "the friday-tape-question" in Collection_of_the_top_ten
- AMANDA_questions._And_answers..
+ Amanda_questions._And_answers..
  What if my tape unit uses expensive tapes, and I don't want to use one tape
- per day? Can't AMANDA append to tapes?
+ per day? Can't Amanda append to tapes?
  It can't, and this is good. Tape drives and OS drivers are (in)famous for
  rewinding tapes at unexpected times, without telling the program that's
  writing to them. If you have a month's worth of backups in that tape, you
- really don't want them to be overwritten, so AMANDA has taken the safe
+ really don't want them to be overwritten, so Amanda has taken the safe
  approach of requiring tapes to be written from the beginning on every run.
  This can be wasteful, specially if you have a small amount of data to back up,
  but expensive large-capacity tapes. One possible approach is to run amdump
@@ -293,12 +321,12 @@ www.amanda.org/fom-serve/cache/1.html.
  backs up the holding disk only, always as a full backup. You'd run this
  configuration always after your regular backup, so you always have a complete
  image of the holding disk on tape, just in case it fails.
- How can I configure AMANDA for long-term archiving?
+ How can I configure Amanda for long-term archiving?
  The best approach is to create a separate configuration for your archive
  backups. It should use a separate set of tapes, and have all dumptypes
  configured with `record no', so it doesn't interfere with regular backups.
  Can I backup separate disks of the same host in different configurations?
- Yes, but you have to be careful. AMANDA uses UDP to issue estimate and backup
+ Yes, but you have to be careful. Amanda uses UDP to issue estimate and backup
  requests and, although replies to backup requests are immediate (so that TCP
  connections for the actual backup can be established), replies to estimate
  requests are not and, while one request is being processed, any other request
@@ -312,14 +340,14 @@ www.amanda.org/fom-serve/cache/1.html.
  So, there are two easy ways out:
 
    i. Ensure that the configurations never run concurrently, or
-  ii. set up two different installations of the AMANDA server, using different
+  ii. set up two different installations of the Amanda server, using different
       services names to contact the clients, i.e., different port numbers. This
-      can be attained with the configure flag --with-testing=<service-suffix>i.
+      can be attained with the configure flag --with-testing=<service-suffix>.
       Yes, the flag name is not appropriate, but so what?
 
- If you don't want to set up two installations of AMANDA (I agree, it's
+ If you don't want to set up two installations of Amanda (I agree, it's
  overkill), but you still want to back up disks of the same host in separate
- configurations, you can set up AMANDA so that one configuration only starts
+ configurations, you can set up Amanda so that one configuration only starts
  after the first one has already finished its One possible way to work-around
  this limitation is to start one configuration only after you know the
  estimates for the first one have already finished (modifying the crontab
@@ -327,10 +355,10 @@ www.amanda.org/fom-serve/cache/1.html.
  (a dumptype option) of the disks in the first configuration, so that they
  don't start backing up before the estimates of the second configuration
  finish.
- Can AMANDA span large filesystems across multiple tapes?
+ Can Amanda span large filesystems across multiple tapes?
  Not yet :-(
  This is an open project, looking for developers. If you'd like to help, please
- take a look at the AMANDA Ongoing Projects Page (http://www.amanda.org/
+ take a look at the Amanda Ongoing Projects Page (http://www.amanda.org/
  ongoing.php), where more up-to-date information is likely to be found about
  this project.
  Update September 2004: Refer to the archive of the amanda-hackers mailinglist
@@ -342,14 +370,14 @@ www.amanda.org/fom-serve/cache/1.html.
  What's the difference between option "skip-full" and "strategy nofull"?
  "strategy nofull" is supposed to handle the following situation: you run a
  full dump off-line once a millenium :-), because that disk isn't supposed to
- change at all and, if it does, changes are minimal. AMANDA will run only level
+ change at all and, if it does, changes are minimal. Amanda will run only level
  1 backups of that filesystem, to avoid the risk of overwriting a level 1
  backup needed to do a restore. Remember, you run full dumps once a millenium,
  and your tape cycle probably won't last that long :-)
  "skip-full", OTOH, is supposed to let the user run full dumps off-line
- regularly (i.e., as often as specified in the dumpcycle), while AMANDA takes
- care of the incrementals. Currently, AMANDA will tell you when you're supposed
- to run the level 0 backups but, if you fail to do so, AMANDA will not only
+ regularly (i.e., as often as specified in the dumpcycle), while Amanda takes
+ care of the incrementals. Currently, Amanda will tell you when you're supposed
+ to run the level 0 backups but, if you fail to do so, Amanda will not only
  skip a full day's worth of valuable backups of the filesystem, on the day it
  told you to the full backup manually, but it will also run a level 1 backup on
  the next day, even if you have not performed the full backup yet. Worse yet:
@@ -359,7 +387,7 @@ www.amanda.org/fom-serve/cache/1.html.
  Why does amdump report "results missing"?
  One of the possible reasons is that you have requested too many backups of the
  host. In this case, the estimate request or the reply may not fit in a UDP
- packet. This will cause AMANDA not to perform some of the backups. Fixing this
+ packet. This will cause Amanda not to perform some of the backups. Fixing this
  problem involves modifying the way estimate requests are issued, so that no
  packet exceeds the maximum packet size, and issuing additional requests that
  did not fit in a UDP packet after a reply for the previous set is obtained.
@@ -392,39 +420,39 @@ www.amanda.org/fom-serve/cache/1.html.
  DUMP to crash before it estimates the backup size; a fsck may help.
  Yet another possibility is that the filesystem is so large that the backup
  program is incorrectly reporting the estimated size, for example, by printing
- a negative value that AMANDA will not accept as a valid estimate. If you are
+ a negative value that Amanda will not accept as a valid estimate. If you are
  using dump, contact your vendor and request a patch for dump that fixes this
  bug. If you are using GNU-tar, make sure it is release 1.12 or newer; 1.11.8
  won't do! Even release 1.12 may require a patch to correctly report estimates
  and dump sizes, as well as to handle sparse files correctly and quickly
  instead of printing error messages like `Read error at byte 0, reading 512
  bytes, in file ./var/log/lastlog: Bad file number' in sendsize.debug and being
- very slow. Check the patches directory of the AMANDA distribution.
+ very slow. Check the patches directory of the Amanda distribution.
  What if amdump reports "dumps way too big, must skip incremental dumps"?
- It means AMANDA couldn't back up some disk because it wouldn't fit in the tape
- (s) you have configured AMANDA to use. It considered performing some
+ It means Amanda couldn't back up some disk because it wouldn't fit in the tape
+ (s) you have configured Amanda to use. It considered performing some
  incrementals instead of full dumps, so that all disks would fit, but this
  wouldn't be enough, so the disk really had to be dropped in this run.
  In general, you can just ignore this message if it happens only once in a
  while. Low-priority disks are discarded first, so you'll hardly miss really
  important data.
- One real work-around is to configure AMANDA to use more tapes: increase
+ One real work-around is to configure Amanda to use more tapes: increase
  `runtapes' in amanda.conf. Even if you don't have a real tape changer, you can
  act yourself as a changer (`chg-manual'; more details in the question about
  tape changer configuration), or use `chg-multi' with a single tape unit, and
- lie to AMANDA that it will have two tapes to use. If you have a holding disk
- as large as a tape, and configure AMANDA (2.4.1b1 or newer) not to reserve any
+ lie to Amanda that it will have two tapes to use. If you have a holding disk
+ as large as a tape, and configure Amanda (2.4.1b1 or newer) not to reserve any
  space for degraded dumps, dumps that would be stored in the second tape of a
  run will be performed to the holding disk, so you can flush them to tape in
  the morning.
  amdump reported "infofile update failed". What should I do?
- Make sure all directories and files are readable and writable by the AMANDA
+ Make sure all directories and files are readable and writable by the Amanda
  user, within the directory you specified as `infofile' in amanda.conf. From
  then on, only run amanda server commands ( amadmin, amdump, amflush,
- amcleanup) as the AMANDA user, not as root.
- Why does AMANDA sometimes promote full dumps?
+ amcleanup) as the Amanda user, not as root.
+ Why does Amanda sometimes promote full dumps?
  To spread the full dumps along the dumpcycle, so that daily runs take roughly
- the same amount of tape and time. As soon as you start using AMANDA, it will
+ the same amount of tape and time. As soon as you start using Amanda, it will
  run full dumps of all filesystems. Then, on the following runs, it will
  promote some backups, so as to adjust the balance. After one or two
  dumpcycles, it should stop promoting dumps. You can see how well it is doing
@@ -437,12 +465,12 @@ www.amanda.org/fom-serve/cache/1.html.
  Another possibility is that amrecover is not selecting the configuration name
  that contains the backups for the selected disk. You may specify a
  configuration name with the `-C' switch, when you invoke amrecover. The
- default configuration name can only be specified at AMANDA configure time
+ default configuration name can only be specified at Amanda configure time
  (configure --with-config=<name>).
  Indexes are currently generated at backup-time only, so, if a backup was
  performed without creating an index, you won't be able to use amrecover to
  restore it, you'll have to use amrestore.
- Ok, I'm done with testing AMANDA, now I want to put it in production. How can
+ Ok, I'm done with testing Amanda, now I want to put it in production. How can
  I reset its databases so as to start from scratch?
  First, remove the `curinfo' database. By default, it is a directory, but, if
  you have selected any other database format (don't, they're deprecated), they
@@ -453,16 +481,16 @@ www.amanda.org/fom-serve/cache/1.html.
  on the tape changer you have selected, you may also want to reset its state
  file.
  The man-page of dump says that active filesystems may be backed up
- inconsistently. What does AMANDA do to prevent inconsistent backups?
+ inconsistently. What does Amanda do to prevent inconsistent backups?
  Nothing. When you back up an active filesystem, there are two possibilities:
  dump may print strange error messages about invalid blocks, then fail; in this
- case, AMANDA will retry the backup on the next run.
+ case, Amanda will retry the backup on the next run.
  Files that are modified while dump runs may be backed up inconsistently. But
  then, they will be included in the next incremental backup, which should
  usually be enough.
  Large, critical files such as databases should be locked somehow, to avoid
- inconsistent backups, but there's no direct support for that in AMANDA. The
- best bet is to configure AMANDA to use a wrapper to dump, that locks and
+ inconsistent backups, but there's no direct support for that in Amanda. The
+ best bet is to configure Amanda to use a wrapper to dump, that locks and
  unlocks the database when appropriate.
  Which version of GNU-tar should I use?
  (This answer was slightly adapted from a posting by Paul Bijnens
@@ -470,7 +498,7 @@ www.amanda.org/fom-serve/cache/1.html.
 
  * 1.13.19 is good.
    However it still sets return code 2 for some infrequent conditions even with
-   --ignore-failed-read option. This results in AMANDA thinking the total
+   --ignore-failed-read option. This results in Amanda thinking the total
    archive is bad, and drops the complete archive. Those conditions are very
    rare on a quiet filesystem.
  * 1.13.25 is good: no problems found (yet).
@@ -488,7 +516,7 @@ www.amanda.org/fom-serve/cache/1.html.
 
  What does "bumping" mean?
  The term "bumping" is used to describe the change from one backup-level to the
- next higher level. If AMANDA changes from Level 0 to Level 1 for a specific
+ next higher level. If Amanda changes from Level 0 to Level 1 for a specific
  DLE, it "bumps".
  The basic goal of "bumping" is to save precious space on the backup media as
  higher level incremental backups are smaller in size than lower level
@@ -499,17 +527,57 @@ www.amanda.org/fom-serve/cache/1.html.
  of tape-errors and similar problems during the process of restore. So in
  general it is recommended to keep the levels as low as possible with the given
  hardware and data.
- There are various amanda.conf parameters to control and fine-tune AMANDA's
+ There are various amanda.conf parameters to control and fine-tune Amanda's
  behavior when it comes to "bumping":
  Please refer to the amanda-manpage and the example amanda.conf for details on
  the parameters bumppercent, bumpsize, bumpdays and bumpmult.
  How do I backup a Windows server?
- AMANDA is able to use smbclient to dump SMB/CIFS-shares. Refer to the Backup
+ Amanda is able to use smbclient to dump SMB/CIFS-shares. Refer to the Backup
  PC_hosts_using_Samba for details.
+ How do I tell my iptables-based firewall to allow Amanda through?
+ posted by Matt Hyclak <hyclak@math.ohiou.edu>:
+ Use something like
+
+        iptables -A INPUT -p udp -s $AMANDA_SERVER -d $AMANDA_CLIENT --dport
+   10080 -j ACCEPT
+
+ and load the ip_conntrack_amanda kernel module. I use the following in /etc/
+ modprobe.conf:
+
+        options ip_conntrack_amanda master_timeout=2400
+        install ip_tables /sbin/modprobe --ignore-install ip_tables && /sbin/
+   modprobe ip_conntrack_amanda
+
+ This sets the UDP timeout for Amanda packets to 2400 seconds, up from the
+ default 300 (don't hold me to that, it might be 600). I was getting estimate
+ timeouts since they were taking longer than 300/600 seconds and the firewall
+ would close the port.
+ Makes things a little more secure than opening up everything > 1024 ;-)
+ How do I get rid of pressing "q" to get rid of a pager prompt when using
+ amrecover?
+ compiled from postings by Paul Bijnens <paul.bijnens@xplanation.com> and Jon
+ LaBadie <jon@jgcomp.com>
+ Paul Bijnens wrote:
+ If you have to press "q" all the time in amrecover this is related to the
+ pager-binary you use. If you use Linux this will be most likely less. To teach
+ less to quit when hitting EOF, you need to set something like LESS=--QUIT-AT-
+ EOF; export LESS, for example in your .profile. Refer to the manpage of less
+ for details.
+ Jon LaBadie wrote:
+ If you don't like the quit at EOF behavior "except" when in amrecover create
+ an alias or a wrapper; something like:
+ alias amrecov='LESS="$LESS -E" _pathto_your_amrecover'
+ Is there a way to tell the pager that my terminal has "y" lines?
+ Jon LaBadie <jon@jgcomp.com> wrote:
+ The pager normally does it's best to find out how many lines your terminal
+ has, given the right TERM-variable. Even terminals with elastic boundaries
+ (e.g. xterms) work. But I have to admit that on Solaris the settings are not
+ always correct. You can fix it quickly by setting an environment variable to
+ e.g. LINES=24 (and export it).
 
 -------------------------------------------------------------------------------
 
 Prev                       Up                                           Next
-Chapter 16. Using AMANDA  Home  Chapter 18. Collection of the top ten AMANDA
+Chapter 18. Using Amanda  Home  Chapter 20. Collection of the top ten Amanda
                                                      questions. And answers.
 
index b483bdb5be6a695aa64d27c46cd66407c607e3bd..c97fc9ecb1688c630abea87537da13dea25b1064 100644 (file)
@@ -5,24 +5,24 @@ Prev                 Next
 -------------------------------------------------------------------------------
 
 
-Historical files
+Part VI. Historical files
 
 
 
 Old and outdated material, proposals and drafts.
 
 Here you find some chapters which contain outdated informations. These chapters
-nonetheless can help to get a more complete picture of AMANDA.
+nonetheless can help to get a more complete picture of Amanda.
 
 Note
 
 Please realize that the following does not necessarily describe current
-features of AMANDA. There are also features described which were never added to
-AMANDA.
+features of Amanda. There are also features described which were never added to
+Amanda.
 Table of Contents
 
 
-  28._Response_to_CPIO_Security_Notice_Issue_11:
+  29._Response_to_CPIO_Security_Notice_Issue_11:
 
 
         Affected_Versions
@@ -32,12 +32,12 @@ Table of Contents
         Acknowledgements
 
 
-  29._Upgrade_Issues
+  30._Upgrade_Issues
 
-  30._What_once_was_new
+  31._What_once_was_new
 
 
-        What's_new_in_AMANDA_2.3
+        What's_new_in_Amanda_2.3
 
 
               Indexing_backups_for_easier_restore
@@ -57,7 +57,7 @@ Table of Contents
               amadmin_import/export
 
 
-        What's_new_in_AMANDA_2.2
+        What's_new_in_Amanda_2.2
 
 
               Client_side_setup_has_changed
@@ -94,7 +94,7 @@ Table of Contents
 
 
 
-  31._Multitape_support_in_AMANDA_2.2
+  32._Multitape_support_in_Amanda_2.2
 
 
         Introduction
@@ -124,15 +124,15 @@ Table of Contents
 
 
 
-  32._Thoughts_about_a_Strategy_API
+  33._Thoughts_about_a_Strategy_API
 
-  33._Y2K_Compliancy
+  34._Y2K_Compliancy
 
-  34._Usage_of_floppy_tape_drives_on_Linux
+  35._Usage_of_floppy_tape_drives_on_Linux
 
 -------------------------------------------------------------------------------
 
-Prev                             Up                                    Next
-Chapter 27. Using Kerberos with Home  Chapter 28. Response to CPIO Security
-AMANDA                                                     Notice Issue 11:
+Prev                                                                   Next
+Chapter 28. Using Kerberos with Home  Chapter 29. Response to CPIO Security
+Amanda                                                     Notice Issue 11:
 
index d409c123e9e25939999c76fbc4d73a4669f9f43c..4554e4f7a08336c17f2f70575e4db785a60dcb53 100644 (file)
@@ -7,7 +7,7 @@ Prev  Part III. HOWTOs  Next
 Chapter 14. AFS HOWTO
 
 
-AMANDA Core Team
+Amanda Core Team
 
 AMANDA Core Team
 
@@ -26,10 +26,10 @@ with amanda:
 ftp://ftp.ccmr.cornell.edu/pub/amanda-afs/amanda-afs.tar.gz
 or anonymous cvs from :pserver:anonymous@cvs.ccmr.cornell.edu:/usr/common/cvs
 and checkout project 'amanda-afs'
-The patch to AMANDA is already included in this distribution.
+The patch to Amanda is already included in this distribution.
 -------------------------------------------------------------------------------
 
 Prev                                     Up                               Next
-Chapter 13. How to use the AMANDA file- Home  Chapter 15. How to use a wrapper
+Chapter 13. How to use the Amanda file- Home  Chapter 15. How to use a wrapper
 driver 
 
diff --git a/docs/howto-auth.txt b/docs/howto-auth.txt
new file mode 100644 (file)
index 0000000..9699de6
--- /dev/null
@@ -0,0 +1,197 @@
+
+Chapter 17. How to use different auth with Amanda
+Prev  Part III. HOWTOs                       Next
+
+-------------------------------------------------------------------------------
+
+Chapter 17. How to use different auth with Amanda
+
+
+Jean-Louis Martineau
+
+Original text;XML-conversion;Updates
+AMANDA Core Team
+<martinea@iro.umontreal.ca>
+Table of Contents
+
+
+  Introduction
+
+  BSD
+
+  BSDTCP
+
+  BSDUDP
+
+  KRB4
+
+  KRB5
+
+  RSH
+
+  SSH
+
+
+        For_amdump:
+
+        For_amrecover:
+
+
+
+Note
+
+Refer to http://www.amanda.org/docs/howto-auth.html for the current version of
+this document.
+This document covers the use of the auth in Amanda 2.5.1 and higher.
+
+Introduction
+
+
+ BSD
+
+You must configure amanda with --with-bsd-security and --with-amandahosts.
+The xinetd.d/amanda file on the client:
+
+  service amanda
+  {
+        only_from               = 127.0.0.1
+        socket_type             = dgram
+        protocol                = udp
+        wait                    = yes
+        user                    = amanda
+        group                   = amanda
+        groups                  = yes
+        server                  = /path/to/amandad
+        server_args             = -auth=bsd amdump
+        disable                 = no
+  }
+
+The only_from line should list your tape server ip address.
+The ~amanda/.amandahosts file on the client:
+
+  tapeserver.fqdn amanda amdump
+
+If you want to also enable amindexd and amidxtaped, you must change the
+server_args line in the xinetd.d/amanda file on the tape server:
+
+        server_args             = -auth=bsd amdump amindexd amidxtaped
+
+The only_from line should list all machine that can use amdump/amrecover. It's
+the .amandahosts that will limit which client can use amdump/amindexd/
+amidxtaped.
+The ~amanda/.amandahosts file on the tape server must have a line for each
+machi ne:
+
+  clientmachine1 amanda amindexd amidxtaped
+  clientmachine2 amanda amindexd amidxtaped
+
+
+ BSDTCP
+
+Like bsd but you must configure amanda with --with-bsdtcp-security and --with-
+amandahosts and do 4 changes in the xinetd.d/amanda file:
+
+        socket_type             = stream
+        protocol                = tcp
+        wait                    = no
+        server_args             = -auth=bsdtcp amdump
+
+
+ BSDUDP
+
+Like bsd but you must configure amanda with --with-bsdudp-security and --with-
+amandahosts and do 1 change in the xinetd.d/amanda file:
+
+        server_args             = -auth=bsdudp amdump
+
+
+ KRB4
+
+You must configure amanda with --with-krb4-security.
+
+ KRB5
+
+You must configure amanda with --with-krb5-security.
+
+ RSH
+
+You must configure amanda with --with-rsh-security.
+It's your system that should allow your server user to rsh to your client user.
+If your server username and client username are different, you must add the
+client_username option in all DLE for that host.
+
+  client_username "client_username"
+
+If your server amandad path and client amandad path are different, you must set
+the amandad_path option in all DLE for that hosts.
+
+  amandad_path "client/amandad/path"
+
+
+ SSH
+
+You must configure amanda with --with-ssh-security.
+
+ For amdump:
+
+You must create an ssh key for your server. In this example, the key is put in
+the id_rsa_amdump file:
+
+  ssh-keygen -t rsa
+  Enter file in which to save the key (/home/amanda/.ssh/id_rsa)? /home/
+  amanda/.ssh/id_rsa_amdump
+
+You must set the ssh_keys option in all DLE for that host:
+
+  ssh_keys "/home/amanda/.ssh/id_rsa_amdump"
+
+You mush append the /home/amanda/.ssh/id_rsa_amdump.pub file to the .ssh/
+authorized_keys file of all client host.
+For security reason, you must prepend the line with the following:
+
+  from="tape_server_fqdn_name",no-port-forwarding,no-X11-forwarding,no-agent-
+  forwarding,command="/path/to/amandad -auth=ssh amdump"
+
+That will limit that key to connect only from your server and only be able to
+execute amandad.
+Like rsh if your server username and client username are different, you must
+add the client_username option in all DLE for that
+host:
+
+  client_username "client_username"
+
+Like rsh, if your server amandad path and client amandad path are different,
+you must set the amandad_path option in all DLE for that hosts:
+
+  amandad_path "client/amandad/path"
+
+
+ For amrecover:
+
+You must create an ssh key for root on all clients that can use amrecover. In
+this example, the key is put in the /root/.ssh/id_ rsa_amrecover file:
+Log in as root:
+
+  ssh-keygen -t rsa
+  Enter file in which to save the key (/root/.ssh/id_rsa)? /root/.ssh/
+  id_rsa_amrecover
+
+You must set the ssh_keys option in the amanda_client.conf file
+
+  ssh_keys "/root/.ssh/id_rsa_amrecover"
+
+You mush append all client /home/root/.ssh/id_rsa_amrecover.pub file to the /
+home/amanda/.ssh/authorized_keys of the server.
+For security reason, you must prefix all lines with the following:
+
+  from="aclient_fqdn_name",no-port-forwarding,no-X11-forwarding,no-agent-
+  forwarding,command="/path/to/amandad -auth=ssh amindexd amidxtaped"
+
+That will limit every client key to connect from the client and only be able to
+execute amandad.
+-------------------------------------------------------------------------------
+
+Prev                                      Up                           Next
+Chapter 16. How to do Amanda-server-side Home  Part IV. Various Information
+gpg-encrypted backups. 
+
index 5f762c564128f3b68658a9b6c7448daea6e2d858..5daa0d158238d32b2d32e5a70ad1f6d81b4d9291 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 12. AMANDA on Cygwin HOWTO
+Chapter 12. Amanda on Cygwin HOWTO
 Prev  Part III. HOWTOs        Next
 
 -------------------------------------------------------------------------------
 
-Chapter 12. AMANDA on Cygwin HOWTO
+Chapter 12. Amanda on Cygwin HOWTO
 
 
 Doug Kingston
@@ -23,7 +23,7 @@ Table of Contents
 
   Other_Preparation
 
-  Compile_AMANDA
+  Compile_Amanda
 
   Configure_Cygwin_files
 
@@ -35,7 +35,7 @@ Table of Contents
 
   Windows_NT/2000/XP
 
-  Notes_on_AMANDA_backup_options
+  Notes_on_Amanda_backup_options
 
 
         Compression
@@ -50,11 +50,11 @@ Note
 
 Refer to http://www.amanda.org/docs/howto-cygwin.html for the current version
 of this document.
-by Doug Kingston, 30 January 2003. Based on Cygwin 1.3.18, and AMANDA 2.4.3-
+by Doug Kingston, 30 January 2003. Based on Cygwin 1.3.18, and Amanda 2.4.3-
 20021027 and some fixes which will be in the official release by the time you
 see this.
 With thanks to Enrico Bernardini from whom I have borrowed some material from
-an earlier attempt at documenting the installation of AMANDA on Cygwin in 2001.
+an earlier attempt at documenting the installation of Amanda on Cygwin in 2001.
 Please send annotations and corrections to mailto://amanda-hackers@amanda.org.
 I can be reached as dpk (at) randomnotes.org (do the obvious).
 
@@ -79,7 +79,7 @@ a more specific list of what is required. If someone has a more definitive
 list, I would appreciate and email to mailto://amanda-hackers@amanda.org.
 One user reported some problems with access rights when running under Cygwin,
 which he solved by setting the CYGWIN environment variable to nontsec. I do not
-believe this is necessary if you run the AMANDA daemon as System (see below).
+believe this is necessary if you run the Amanda daemon as System (see below).
 
  Other Preparation
 
@@ -87,7 +87,7 @@ When doing backups on a NT, Windows 2000 or Windows XP system, the choice of
 user and group will be important if you are to properly interact with the
 security mechanisms of these more modern Microsoft product. For Windows 95/98/
 ME this is probably a non-issue. The most privileged account on the Windows
-systems is 'System', and I have chosen to use this account for AMANDA backups
+systems is 'System', and I have chosen to use this account for Amanda backups
 to ensure that I can access the widest set of files. On Unix we would run as
 root, with equivalent access permissions. I have also chose to run under the
 'Administrators' group, another standard Windows group. Ensure these exist
@@ -105,10 +105,10 @@ relevant lines from my file /etc/passwd are:
   root:*:18:18:,S-1-5-18:/home/root:
 
 
- Compile AMANDA
+ Compile Amanda
 
-After installing Cygwin, unpack the AMANDA sources, typically in /usr/src/
-AMANDA or something similar. In the AMANDA directory, you will need to execute:
+After installing Cygwin, unpack the Amanda sources, typically in /usr/src/
+Amanda or something similar. In the Amanda directory, you will need to execute:
 
   automake  # this may not be necessary in the official release
   autoconf  # this may not be necessary in the official release
@@ -150,7 +150,7 @@ You have to modify some config files:
 * create _/home/root/.amandahosts_ (or whereever System's home directory is):
   <amanda server> <amanda user>
 
-Then create the following AMANDA directories and the file amandates:
+Then create the following Amanda directories and the file amandates:
 
        mkdir -p /usr/local/var/amanda/gnutar-lists
 
@@ -165,9 +165,9 @@ Update the Windows services list
 
 * WINDIR\Services: add
 
-               amanda  10080/udp       # AMANDA backup services
-               amandaidx       10082/tcp       # AMANDA backup services
-               amidxtape       10083/tcp       # AMANDA backup services
+               amanda  10080/udp       # Amanda backup services
+               amandaidx       10082/tcp       # Amanda backup services
+               amidxtape       10083/tcp       # Amanda backup services
 
 
 where WINDIR is C:\WINNT\system32\drivers\etc or something similar. The last
@@ -220,7 +220,7 @@ Then, to start/stop the inetd service use the Services control panel or the
 following Windows command:
 net start/stop inetd
 
- Notes on AMANDA backup options
+ Notes on Amanda backup options
 
 
  Compression
@@ -229,15 +229,15 @@ Currently, client side compression does not work, probably due to problems in
 pipe emulation in Cygwin. I have not tried to debug this yet. This may be
 addressed in a subsequent release, or it could be fixed in later releases of
 Cygwin. Due to this issue, we recommend that if you want compressed dumps from
-Windows clients, you configure AMANDA for server compression in amanda.conf on
-your AMANDA server:
+Windows clients, you configure Amanda for server compression in amanda.conf on
+your Amanda server:
 
   define dumptype srv-comp-tar {
       global
       comment "partitions dumped via tar with server compression"
       program "GNUTAR"
       compress server fast
-      exclude list ".AMANDA.exclude"
+      exclude list ".Amanda.exclude"
   }
 
 
@@ -252,10 +252,10 @@ something similar if you want to get the Windows files and the Cygwin files. '/
 
  Debugging Files
 
-AMANDA will leave debugging files in /tmp/amanda if it exists. I have
+Amanda will leave debugging files in /tmp/amanda if it exists. I have
 recommended to create this directory above.
 -------------------------------------------------------------------------------
 
 Prev               Up                                            Next
-Part III. HOWTOs  Home  Chapter 13. How to use the AMANDA file-driver
+Part III. HOWTOs  Home  Chapter 13. How to use the Amanda file-driver
 
index 6d16a6598bfb806885f4ba26281f660eeb540892..b6ba1df80977efb32d7034d16441f221405e83b8 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 13. How to use the AMANDA file-driver
+Chapter 13. How to use the Amanda file-driver
 Prev  Part III. HOWTOs                   Next
 
 -------------------------------------------------------------------------------
 
-Chapter 13. How to use the AMANDA file-driver
+Chapter 13. How to use the Amanda file-driver
 
 
 Stefan G. Weichinger
@@ -32,33 +32,33 @@ Note
 
 Refer to http://www.amanda.org/docs/howto-filedriver.html for the current
 version of this document.
-This document covers the use of the file-driver in AMANDA 2.4.3 and higher.
+This document covers the use of the file-driver in Amanda 2.4.3 and higher.
 Examples given here have been taken from a SuSE-Linux-8.2-Pro-environment,
-using AMANDA 2.4.4p1 and the snapshot 2.4.4p1-20031202. Please adjust paths,
+using Amanda 2.4.4p1 and the snapshot 2.4.4p1-20031202. Please adjust paths,
 configuration names and other parameters to your system.
 Stefan G. Weichinger, November - December, 2003 ; minor updates in April, 2005.
 
 Introduction
 
-Since release 2.4.3 AMANDA supports the usage of a output driver called "file".
+Since release 2.4.3 Amanda supports the usage of a output driver called "file".
 See man amanda, section OUTPUT DRIVERS, for more information on its
 implementation. As the name suggests, this driver uses files as virtual (or
 file) tapes. Once created and labeled, these file tapes can be selected and
-changed with the standard tape-changer-interface of the AMANDA server.
+changed with the standard tape-changer-interface of the Amanda server.
 
  Possible Uses
 
 
 * test installations
-  You can easily explore the rich features of AMANDA on systems without tape
+  You can easily explore the rich features of Amanda on systems without tape
   drives.
 * cheap installations
-  Without buying a tape drive you can enjoy the benefits of AMANDA and backup
+  Without buying a tape drive you can enjoy the benefits of Amanda and backup
   to a bunch of harddisks. You can create CD/DVD-sized backups which you can
   burn onto optical disks later.
 * disk-based installations
   You can use the file-driver to backup onto a set of file tapes hosted on a
-  bunch of hard-disks or a RAID-system. Combined with another AMANDA-
+  bunch of hard-disks or a RAID-system. Combined with another Amanda-
   configuration that dumps the file tapes to real tapes, you can provide
   reliable backup with faster tapeless recovery. This is called "disk-to-disk-
   to-tape"-backup by some people today.
@@ -69,7 +69,7 @@ changed with the standard tape-changer-interface of the AMANDA server.
 
  Basics
 
-This guide assumes you have setup the basic AMANDA-services as described in
+This guide assumes you have setup the basic Amanda-services as described in
 Amanda_Installation_Notes
 The configuration in this HOWTO is called "daily". The file tapes are also
 called  vtapes in this document, which stands for "virtual tapes".
@@ -82,7 +82,7 @@ disk(s) for your file tape storage. While this space could be spread among
 several file systems and hard disks, I recommend to dedicate at least a
 specific partition, better a specific physical harddisk to the task of keeping
 your vtapes. The use of a dedicated disk will speed things up definitely.
-The disk space you dedicate for your vtapes should NOT be backed up by AMANDA.
+The disk space you dedicate for your vtapes should NOT be backed up by Amanda.
 Also, for performance reasons there should be NO holding disks on the same
 partition as the vtapes, preferably not even on the same physical drive.
 If you only have one harddisk, it will work out, too, but you will suffer low
@@ -120,7 +120,7 @@ Steps
      (Available Space * 0.9) >= tapelength * tapecycle
      This is a very conservative approach to make sure you don´t suffer any
      performance drop due to a nearly-full-filesystem.
-     As it is uncommon for AMANDA to fill, or almost fill an entire tape you
+     As it is uncommon for Amanda to fill, or almost fill an entire tape you
      may also wish to use more space than that.
      So you could determine possible combinations of tapelength/tapecycle with
      the more general formula:
@@ -156,15 +156,15 @@ Steps
                
 
      You don´t have to specify the parameter speed (as it is commonly listed in
-     tapetype definitions and reported by the program amtapetype). AMANDA does
+     tapetype definitions and reported by the program amtapetype). Amanda does
      not use this parameter right now.
      There is also an optional parameter filemark, which indicates the amount
-     of space "wasted" after each tape-listitem. Leave it blank and AMANDA uses
+     of space "wasted" after each tape-listitem. Leave it blank and Amanda uses
      the default of 1KB.
   4. Think about tapechangers.
      As you will use a set of vtapes, you have to also use a kind of vtape-
-     changer. There are several tape-changer-scripts included in the AMANDA-
-     tarball. Read more about tape-changer-scripts in AMANDA_Tape_Changer
+     changer. There are several tape-changer-scripts included in the Amanda-
+     tarball. Read more about tape-changer-scripts in Amanda_Tape_Changer
      Support.
      Right now there are two scripts that can be used with vtapes. These
      scripts take different approaches to the handling of tapes.
@@ -174,13 +174,13 @@ Steps
      chg-multi simulates multiple tape drives with one tape in each drive. chg-
      disk simulates one tape-library with multiple tapes in.
      As chg-multi exists for a much longer time than chg-disk, it is still used
-     in many AMANDA-vtape-installations.
+     in many Amanda-vtape-installations.
      chg-disk was introduced with the snapshot 20031202. Contrary to chg-multi,
      which is a generic changer-script that must be somewhat adjusted to the
      use of the file-driver, chg-disk offers exactly the behavior needed for
      handling vtapes
      IMHO the approach is much more logical, so I recommend to use chg-disk in
-     new AMANDA-vtape-installations.
+     new Amanda-vtape-installations.
 
      Note
 
@@ -204,11 +204,11 @@ Steps
                
 
      This reflects the use of your defined tapetype.
-     The parameter tapecycle tells AMANDA how much tapes can be used, Set this
+     The parameter tapecycle tells Amanda how much tapes can be used, Set this
      value according to the number of tapes you want to use.
      The parameter tapetype , points to the tapetype definition you have
      created before.
-     The parameter tpchanger tells AMANDA to use the generic tape-changer-
+     The parameter tpchanger tells Amanda to use the generic tape-changer-
      script to handle the vtapes. You can think of it as a virtual tape-
      changer-device.
      The parameter changerfile is used to give chg-disk the "prefix" for the
@@ -280,7 +280,7 @@ Steps
                $ ln -s /amandatapes/daily/slot1 /amandatapes/daily/data
                
 
-     Make sure the AMANDA-user has write-permissions on these directories:
+     Make sure the Amanda-user has write-permissions on these directories:
 
                $ chown -R amanda_user /amandatapes
                $ chgrp -R amanda_group /amandatapes
@@ -288,7 +288,7 @@ Steps
                
 
   7. Label the virtual tapes.
-     As the virtual tapes are handled just like physical tapes by the AMANDA-
+     As the virtual tapes are handled just like physical tapes by the Amanda-
      Server they have to be labeled before use.
 
                Usage: amlabel [-f] <conf> <label> [slot <slot-number>]
@@ -315,7 +315,7 @@ Steps
      amanda.conf. Consult the amlabel-man-page for details.
   8. Test your setup with amcheck.
      Run amcheck daily (or, more general, amcheck <config>) and look for
-     anything AMANDA complains about.
+     anything Amanda complains about.
      A proper output looks like:
 
                $ amcheck daily
@@ -343,7 +343,7 @@ of chg-disk):
 
   # /usr/local/amanda/sbin/amrecover woo
   AMRECOVER Version 2.4.4p3. Contacting server on backupserver.local ...
-  220 backupserver AMANDA index server (2.4.4p3) ready.
+  220 backupserver Amanda index server (2.4.4p3) ready.
   200 Access OK
   Setting restore date to today (2004-10-08)
   200 Working date set to 2004-10-08.
@@ -382,7 +382,7 @@ of chg-disk):
   200 Good bye.
 
 Nothing spectacular? The trick is this:
-When AMANDA asks you
+When Amanda asks you
 
   Load tape B3_14 now Continue [?/Y/n/s/t]?
 
@@ -430,5 +430,5 @@ when restoring data shared accross multiple tapes...) "
 -------------------------------------------------------------------------------
 
 Prev                                 Up                    Next
-Chapter 12. AMANDA on Cygwin HOWTO  Home  Chapter 14. AFS HOWTO
+Chapter 12. Amanda on Cygwin HOWTO  Home  Chapter 14. AFS HOWTO
 
index c5eaf8e6191baf3c30e04ba30a53ccdf339327dc..bb8641e0c9339acb6b5b6099fa82b10e30935032 100644 (file)
@@ -11,11 +11,22 @@ Bert de Ridder
 
 Original text
 
+Paul Bijnens
+
+Original text
+
 Stefan G. Weichinger
 
 XML-conversion; Updates
 AMANDA Core Team
 <sgw@amanda.org>
+Table of Contents
+
+
+  Bert_de_Ridder's_suggestions
+
+  Paul_Bijnens's_suggestions
+
 
 Note
 
@@ -24,10 +35,13 @@ of this document.
 
 Note
 
-The script used in this document is not part of the official AMANDA release.
-The AMANDA core team does not take any responsibility for this script.
+The script used in this document is not part of the official Amanda release.
+The Amanda core team does not take any responsibility for this script.
+
+Bert de Ridder's suggestions
+
 This is a mini-howto explaining how to control other running tasks on a server
-where the AMANDA software is used to backup data.
+where the Amanda software is used to backup data.
 Problem : Lots of software is picky about their datafiles being backed up while
 the files are in use. It sometimes is even necessary to know the state of the
 datafiles at the moment of backup so that when restoring you know exactly
@@ -144,7 +158,7 @@ course is just an example, anything you can do in a shell script can be done.
        # End script
 
      On some systems it may be necessary to setuid root the script.
-  2. Rebuild AMANDA so that it uses your newly created script.
+  2. Rebuild Amanda so that it uses your newly created script.
      Download the sources, untar them to a directory. I'm sure there are lots
      of documents already available on how to do this, so I won't go into too
      much detail. (Refer to Amanda_Installation_Notes).
@@ -178,8 +192,110 @@ course is just an example, anything you can do in a shell script can be done.
 
      Now proceed as with a "normal" installation.
 
+
+Paul Bijnens's suggestions
+
+How do I run pre- and post dump programs, e.g. database stop/start?
+Currently (Amanda 2.4.5) there is no direct support to run a program before or
+after a backup on a client. But there is an easy workaround by using a wrapper
+for GNU-tar that does the additional tasks.
+Let's suppose you want to stop a database before the backup, and start it up
+again when the backup is finished. You have already two scripts "shutdb" and
+"startdb" to shutdown and startup the database.
+First you have to configure Amanda on the client to use the gnutar-wrapper
+instead of the real GNU-tar:
+
+  ./configure ... --with-gnutar=/usr/local/bin/amgtar ...
+
+and re-compile Amanda. The program "amgtar" can be a simple link to the real
+GNU-tar-binary on clients that don't need special handling, or it can be a
+script.
+Amanda expects that the bytestream on stdout is the backup image, and the
+bytestream on stderr are messages. The stderr messages are filtered against a
+known set of strings, and anything unexpected is flagged as "STRANGE" in the
+Amanda report. The return-codes of the program should be the same as the
+return-codes of GNU-tar:
+
+* 0 = ok (backup image will be put on tape)
+* 1 = not ok (backup image will not be put on tape, same level will be tried
+  next time).
+
+The arguments passed to the program are pretty static (see in the sources
+client-src/sendbackup-gnutar.c, line 483). To decide if you need to stop/start
+the database you have to check if:
+
+* this run makes a backup and not a restore: look for "--create"
+* this it is not an estimate run: look for "--file /dev/null" (estimate) or "--
+  file -" (real run)
+* this run is for the database directory: look for "--directory /my/data/base"
+
+In all other cases, we just pass the args and run the real GNU-tar.
+Here is an example script in Bourne shell:
+Example 15.1. 
+
+  #!/bin/sh
+
+  # # uncomment next block to follow the flow
+  # LOG=/tmp/amanda/mytar.debug
+  # date >> $LOG
+  # echo "$@" >> $LOG
+  # if [ "$3" = "/dev/null" ]
+  # then echo "Estimate only" >> $LOG
+  # else echo "Real backup" >> $LOG
+  # fi
+
+  # - Avoid output to stdout! (the backup stream by tar)
+  # - Any output to stderr is flagged as "strange" by amanda
+  #   and may be used to pass error messages into the report
+
+  if [ "$1" = "--create"  -a  "$3" = "-"  -a  "$5" = "/my/dir" ]
+  then
+      # echo "/my/dir: want to execute some progs first" >>$LOG
+      /usr/local/bin/shutdb thedb >&2
+      /usr/local/bin/gtar "$@"
+      rc=$?
+      # echo "Finished the real backup; some postprocessing" >>$LOG
+      /usr/local/bin/startdb thedb >&2
+      exit $rc
+  else
+      /usr/local/bin/gtar "$@"
+  fi
+
+Here is an example script in perl:
+Example 15.2. 
+
+  #!/usr/bin/perl -w
+
+  use Getopt::Long qw(:config pass_through);
+
+  my @saveopts = @ARGV;
+  GetOptions (
+          'create' => \$create,
+          'directory=s' => \$dir,
+          'file=s' => \$file,
+  );
+  @ARGV = @saveopts;
+
+  my $postproc = 0;
+  if ($create  &&  $dir eq '/my/data/base' &&  $file ne '/dev/null') {
+      system '/usr/local/bin/dbshut thedb >/tmp/amanda/dbshut.debug 2>&1';
+      $postproc = 1;
+  }
+
+  unshift(@ARGV, "/usr/local/bin/gtar");
+  system @ARGV;
+
+  my $rc = $? >> 8;
+
+  if ($postproc) {
+      system '/usr/local/bin/dbstart thedb >/tmp/amanda/dbstart.debug 2>&1';
+  }
+
+  exit $rc;
+
 -------------------------------------------------------------------------------
 
-Prev                    Up                           Next
-Chapter 14. AFS HOWTO  Home  Part IV. Various Information
+Prev                    Up                                            Next
+Chapter 14. AFS HOWTO  Home  Chapter 16. How to do Amanda-server-side gpg-
+                                                        encrypted backups.
 
index cfc9e6caa49370c07612b3f269d3965b9e0f0543..bd0a5a3879e3dc8e6966d54cb2c54dc1bbb9ca85 100644 (file)
@@ -5,25 +5,25 @@ Prev        Next
 -------------------------------------------------------------------------------
 
 
-HOWTOs
+Part III. HOWTOs
 
 
 
 How to do this?
 
 This section contains some HOWTO-style-documents which should help you to get
-AMANDA up and going with Cygwin, AFS or chg-disk ...
+Amanda up and going with Cygwin, AFS or chg-disk ...
 Table of Contents
 
 
-  12._AMANDA_on_Cygwin_HOWTO
+  12._Amanda_on_Cygwin_HOWTO
 
 
         Install_Cygwin
 
         Other_Preparation
 
-        Compile_AMANDA
+        Compile_Amanda
 
         Configure_Cygwin_files
 
@@ -35,7 +35,7 @@ Table of Contents
 
         Windows_NT/2000/XP
 
-        Notes_on_AMANDA_backup_options
+        Notes_on_Amanda_backup_options
 
 
               Compression
@@ -46,7 +46,7 @@ Table of Contents
 
 
 
-  13._How_to_use_the_AMANDA_file-driver
+  13._How_to_use_the_Amanda_file-driver
 
 
         Introduction
@@ -66,8 +66,50 @@ Table of Contents
 
   15._How_to_use_a_wrapper
 
+
+        Bert_de_Ridder's_suggestions
+
+        Paul_Bijnens's_suggestions
+
+
+  16._How_to_do_Amanda-server-side_gpg-encrypted_backups.
+
+
+        Setup
+
+        Test
+
+        Plans
+
+
+  17._How_to_use_different_auth_with_Amanda
+
+
+        Introduction
+
+        BSD
+
+        BSDTCP
+
+        BSDUDP
+
+        KRB4
+
+        KRB5
+
+        RSH
+
+        SSH
+
+
+              For_amdump:
+
+              For_amrecover:
+
+
+
 -------------------------------------------------------------------------------
 
-Prev                             Up                                 Next
-Chapter 11. Printing of Labels  Home  Chapter 12. AMANDA on Cygwin HOWTO
+Prev                                                                Next
+Chapter 11. Printing of Labels  Home  Chapter 12. Amanda on Cygwin HOWTO
 
index e51b1cd16eb3f85a922cebbeff60981c83f39160..edd1a52926ad1eeddabe532a240962d0d4fe0e00 100644 (file)
@@ -14,7 +14,7 @@ Edited by
 Stefan G. Weichinger
 
 
-AMANDA Core Team
+Amanda Core Team
 
 -------------------------------------------------------------------------------
 Table of Contents
@@ -29,11 +29,13 @@ Table of Contents
   I._Installation
 
 
-        1._AMANDA_2.4.x_-_System-Specific_Installation_Notes
+        1._Amanda_2.5.0_-_System-Specific_Installation_Notes
 
 
               Solaris_2.6
 
+              Solaris
+
               Trusted_Solaris
 
               SunOS_4.x
@@ -69,14 +71,14 @@ Table of Contents
               Mac_OS_X
 
 
-        2._AMANDA_Installation_Notes
+        2._Amanda_Installation_Notes
 
 
               Before_doing_anything
 
-              Compiling_the_AMANDA_sources
+              Compiling_the_Amanda_sources
 
-              Setting_up_your_AMANDA_Configuration
+              Setting_up_your_Amanda_Configuration
 
 
                     Setting_up_the_Tape_Server_Host
@@ -113,7 +115,7 @@ Table of Contents
 
 
 
-        4._Indexing_with_AMANDA
+        4._Indexing_with_Amanda
 
 
               Database_Format
@@ -161,7 +163,7 @@ Table of Contents
 
         7._Tapetypes
 
-        8._AMANDA_Tape_Changer_Support
+        8._Amanda_Tape_Changer_Support
 
 
               Introduction
@@ -217,7 +219,7 @@ Table of Contents
 
               Notes_about_changer.conf
 
-              AMANDA's_actual_usage_of_chg-scsi
+              Amanda's_actual_usage_of_chg-scsi
 
               Configuration_notes
 
@@ -250,14 +252,14 @@ Table of Contents
   III._HOWTOs
 
 
-        12._AMANDA_on_Cygwin_HOWTO
+        12._Amanda_on_Cygwin_HOWTO
 
 
               Install_Cygwin
 
               Other_Preparation
 
-              Compile_AMANDA
+              Compile_Amanda
 
               Configure_Cygwin_files
 
@@ -269,7 +271,7 @@ Table of Contents
 
               Windows_NT/2000/XP
 
-              Notes_on_AMANDA_backup_options
+              Notes_on_Amanda_backup_options
 
 
                     Compression
@@ -280,7 +282,7 @@ Table of Contents
 
 
 
-        13._How_to_use_the_AMANDA_file-driver
+        13._How_to_use_the_Amanda_file-driver
 
 
               Introduction
@@ -301,32 +303,74 @@ Table of Contents
         15._How_to_use_a_wrapper
 
 
+              Bert_de_Ridder's_suggestions
+
+              Paul_Bijnens's_suggestions
+
+
+        16._How_to_do_Amanda-server-side_gpg-encrypted_backups.
+
+
+              Setup
+
+              Test
+
+              Plans
+
+
+        17._How_to_use_different_auth_with_Amanda
+
+
+              Introduction
+
+              BSD
+
+              BSDTCP
+
+              BSDUDP
+
+              KRB4
+
+              KRB5
+
+              RSH
+
+              SSH
+
+
+                    For_amdump:
+
+                    For_amrecover:
+
+
+
+
   IV._Various_Information
 
 
-        16._Using_AMANDA
+        18._Using_Amanda
 
 
               An_Introduction
 
-              AMANDA_Features
+              Amanda_Features
 
-              Future_Capabilities_of_AMANDA
+              Future_Capabilities_of_Amanda
 
-              AMANDA_Resources
+              Amanda_Resources
 
-              Installing_AMANDA
+              Installing_Amanda
 
 
                     Install_Related_Packages
 
                     Perform_Preliminary_Setup
 
-                    Configure_the_AMANDA_Build
+                    Configure_the_Amanda_Build
 
-                    Build_and_Install_AMANDA
+                    Build_and_Install_Amanda
 
-                    Configuring_AMANDA
+                    Configuring_Amanda
 
                     Decide_on_a_Tape_Server
 
@@ -354,7 +398,7 @@ Table of Contents
 
                     Run_amdump
 
-                    Read_AMANDA's_Reports
+                    Read_Amanda's_Reports
 
                     Monitor_Tape_and_Holding_Disk_Status
 
@@ -363,7 +407,7 @@ Table of Contents
                     Miscellanous_Operational_Notes
 
 
-              Advanced_AMANDA_Configuration
+              Advanced_Amanda_Configuration
 
 
                     Adjust_the_Backup_Cycle
@@ -375,20 +419,20 @@ Table of Contents
                     Excluding_Files
 
 
-              Restoring_with_AMANDA
+              Restoring_with_Amanda
 
 
                     Configuring_and_Using_amrecover
 
                     Using_amrestore
 
-                    Restoring_Without_AMANDA
+                    Restoring_Without_Amanda
 
 
 
-        17._AMANDA_FAQ
+        19._Amanda_FAQ
 
-        18._Collection_of_the_top_ten_AMANDA_questions._And_answers.
+        20._Collection_of_the_top_ten_Amanda_questions._And_answers.
 
 
               Reason_for_starting_this_list.
@@ -418,15 +462,13 @@ Table of Contents
               ...
 
 
-        19._AMANDA_WISHLIST
-
-        20._AMANDA_Survey_Results
+        21._Amanda_WISHLIST
 
 
   V._Technical_Background
 
 
-        21._How_AMANDA_uses_UDP_and_TCP_ports
+        22._How_Amanda_uses_UDP_and_TCP_ports
 
 
               TCP_port_allocation
@@ -440,7 +482,7 @@ Table of Contents
               Firewalls_and_NAT
 
 
-        22._AMANDA_dumper_API
+        23._Amanda_dumper_API
 
 
               Introduction
@@ -468,7 +510,7 @@ Table of Contents
               Conclusion
 
 
-        23._AMANDA_Internals
+        24._Amanda_Internals
 
 
               Protocols
@@ -482,7 +524,7 @@ Table of Contents
               taper(read)_and_taper(write)
 
 
-        24._AMANDA_Event_API
+        25._Amanda_Event_API
 
 
               Introduction
@@ -496,6 +538,8 @@ Table of Contents
 
                     event_loop
 
+                    event_wait
+
                     event_wakeup
 
 
@@ -526,7 +570,7 @@ Table of Contents
 
 
 
-        25._AMANDA_Security_API
+        26._Amanda_Security_API
 
 
               Introduction
@@ -590,12 +634,12 @@ Table of Contents
 
 
 
-        26._Virtual_Tape_API
+        27._Virtual_Tape_API
 
-        27._Using_Kerberos_with_AMANDA
+        28._Using_Kerberos_with_Amanda
 
 
-              AMANDA_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
+              Amanda_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
 
 
                     Configuration
@@ -605,7 +649,7 @@ Table of Contents
                     conf_file
 
 
-              AMANDA_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
+              Amanda_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
 
 
                     Building
@@ -622,7 +666,7 @@ Table of Contents
   VI._Historical_files
 
 
-        28._Response_to_CPIO_Security_Notice_Issue_11:
+        29._Response_to_CPIO_Security_Notice_Issue_11:
 
 
               Affected_Versions
@@ -632,12 +676,12 @@ Table of Contents
               Acknowledgements
 
 
-        29._Upgrade_Issues
+        30._Upgrade_Issues
 
-        30._What_once_was_new
+        31._What_once_was_new
 
 
-              What's_new_in_AMANDA_2.3
+              What's_new_in_Amanda_2.3
 
 
                     Indexing_backups_for_easier_restore
@@ -657,7 +701,7 @@ Table of Contents
                     amadmin_import/export
 
 
-              What's_new_in_AMANDA_2.2
+              What's_new_in_Amanda_2.2
 
 
                     Client_side_setup_has_changed
@@ -694,7 +738,7 @@ Table of Contents
 
 
 
-        31._Multitape_support_in_AMANDA_2.2
+        32._Multitape_support_in_Amanda_2.2
 
 
               Introduction
@@ -724,19 +768,87 @@ Table of Contents
 
 
 
-        32._Thoughts_about_a_Strategy_API
+        33._Thoughts_about_a_Strategy_API
 
-        33._Y2K_Compliancy
+        34._Y2K_Compliancy
 
-        34._Usage_of_floppy_tape_drives_on_Linux
+        35._Usage_of_floppy_tape_drives_on_Linux
 
 
   VII._Appendixes
 
 
-        35._The_AMANDA_Manual_Pages.
+        36._The_Amanda_Manual_Pages.
+
+
+              amadmin - administrative interface to control Amanda backups
+
+              amaespipe - wrapper program for aespipe
+
+              amanda - Advanced Maryland Automatic Network Disk Archiver
+
+              amanda.conf - Main configuration file for Amanda, the Advanced
+              Maryland Automatic Network Disk Archiver
+
+              amanda-client.conf - Client configuration file for Amanda, the
+              Advanced Maryland Automatic Network Disk Archiver
+
+              amcheck - run Amanda self-checks
+
+              amcheckdb - check Amanda database for tape consistency
+
+              amcleanup - run the Amanda cleanup process after a failure
+
+              amcrypt - reference crypt program for Amanda symmetric data
+              encryption
 
-        36._Web_Ressources
+              amcrypt-ossl - crypt program for Amanda symmetric data encryption
+              using OpenSSL
+
+              amcrypt-ossl-asym - crypt program for Amanda asymmetric data
+              encryption using OpenSSL
+
+              amdd - Amanda version of dd
+
+              amdump - back up all disks in an Amanda configuration
+
+              amfetchdump - extract backup images from multiple Amanda tapes.
+
+              amflush - flush Amanda backup files from holding disk to tape
+
+              amgetconf - look up amanda.conf variables
+
+              amlabel - label an Amanda tape
+
+              ammt - Amanda version of mt
+
+              amoverview - display file systems processed by Amanda over time
+
+              amplot - visualize the behavior of Amanda
+
+              amrecover - Amanda index database browser
+
+              amreport - generate a formatted output of statistics for an
+              Amanda run
+
+              amrestore - extract backup images from an Amanda tape
+
+              amrmtape - remove a tape from the Amanda database
+
+              amstatus - display the state of an Amanda run
+
+              amtape - user interface to Amanda tape changer controls
+
+              amtapetype - generate a tapetype definition.
+
+              amtoc - generate TOC (Table Of Contents) for an Amanda run
+
+              amverify - check an Amanda tape for errors
+
+              amverifyrun - check the tapes written by the last Amanda run
+
+
+        37._Web_Ressources
 
 
   Index
@@ -746,12 +858,42 @@ List of Tables
 
   4.1. Protocol_between_amindexd_and_amrecover
 
-  20.1. Operating_Systems_Running_on_AMANDA_Server_Hosts
-
 List of Examples
 
 
-  16.1. A_C_Program_to_Check_the_AMANDA_Service_Numbers
+  2.1. /etc/crontab
+
+  2.2. /etc/services
+
+  2.3. /etc/inetd.conf
+
+  2.4. /etc/xinetd.d/amandaidx
+
+  2.5. /etc/xinetd.d/amidxtape
+
+  2.6. /etc/amanda/supervise/amandaidx/run
+
+  2.7. /etc/amanda/supervise/amidxtape/run
+
+  2.8. /etc/services
+
+  2.9. /etc/inetd.conf
+
+  2.10. /etc/xinetd.d/amanda
+
+  2.11. /etc/amanda/supervise/amanda/run
+
+  15.1.
+
+  15.2.
+
+  16.1. /usr/local/libexec/amgtar
+
+  16.2. /usr/local/bin/amaespipe
+
+  16.3. bz2aespipe.patch
+
+  18.1. A_C_Program_to_Check_the_Amanda_Service_Numbers
 
 -------------------------------------------------------------------------------
 
index 0256d8a18266b6651357085efe4dba345f157648..fd022634909202929cfb518f9f20a0dda660a9d9 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 4. Indexing with AMANDA
+Chapter 4. Indexing with Amanda
 Prev  Part I. Installation  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 4. Indexing with AMANDA
+Chapter 4. Indexing with Amanda
 
 
 Alan M. McIvor
@@ -71,7 +71,7 @@ generate the entry /user1/data. The index files are stored in compressed format
 
 The client is called amrecover and is loosely based on the functionality of the
 program recover from Backup Copilot. A user starts up amrecover. This requires
-specifying the index server and the AMANDA config name (defaults for both are
+specifying the index server and the Amanda config name (defaults for both are
 compiled in as part of the installation). Then the user has to specify the name
 of the host information is wanted about, the disk name, and (optionally) the
 disk mount point. Finally a date needs to be specified. Given all this, the
@@ -118,7 +118,7 @@ Table 4.1. Protocol between amindexd and amrecover
 |HOST_<host>________|set_host_to_host________________________________________|
 |DISK_<disk>________|set_disk_to_disk________________________________________|
 |LISTDISK_[<device>]|list_the_disks_for_the_current_host_____________________|
-|SCNF_<config>______|set_AMANDA_configuration_to_config______________________|
+|SCNF_<config>______|set_Amanda_configuration_to_config______________________|
 |DATE_<date>________|set_date_to_date________________________________________|
 |DHST_______________|return_dump_history_of_current_disk_____________________|
 |                   |Opaque is directory? query. Is the directory dir present|
@@ -154,10 +154,10 @@ Table 4.1. Protocol between amindexd and amrecover
      This cause sendbackup-dump on the client machine to generate an index file
      which is stored local to the client, for later recovery by amgetidx (which
      is called by amdump).
-  3. AMANDA saves all the index files under a directory specified by
+  3. Amanda saves all the index files under a directory specified by
      "indexdir" in amanda.conf. You need to create this directory by hand. It
      needs to have read/write permissions set for the user you defined to run
-     AMANDA.
+     Amanda.
      If you are using the "text database" option you may set indexdir and
      infofile to be the same directory.
   4. The index browser, amrecover, currently gets installed as part of the
@@ -172,7 +172,7 @@ Table 4.1. Protocol between amindexd and amrecover
 
  Permissions
 
-The userid chosen to run the AMANDA client code must have permission to run
+The userid chosen to run the Amanda client code must have permission to run
 restore since this is used by createindex-dump to generate the index files.
 For a user to be able to restore files from within amrecover, that user must
 have permission to run restore.
@@ -180,7 +180,7 @@ have permission to run restore.
  Changes from amindex-1.0
 
 Get index directory from amanda.conf.
-Integration into AMANDA-2.3.0.4.
+Integration into Amanda-2.3.0.4.
 Rewriting of amgetidx to use amandad instead of using rsh/rcp.
 
  Changes from amindex-0.3
index 5b8630237654675ce53e4194152e7de0ce07998b..46ae52610f774492d201681a0fe32b866316b7a0 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 2. AMANDA Installation Notes
+Chapter 2. Amanda Installation Notes
 Prev  Part I. Installation      Next
 
 -------------------------------------------------------------------------------
 
-Chapter 2. AMANDA Installation Notes
+Chapter 2. Amanda Installation Notes
 
 
 James da Silva
@@ -15,7 +15,7 @@ AMANDA Core Team
 
 Stefan G. Weichinger
 
-XML-conversion
+XML-conversion, Updates
 AMANDA Core Team
 <sgw@amanda.org>
 Table of Contents
@@ -23,9 +23,9 @@ Table of Contents
 
   Before_doing_anything
 
-  Compiling_the_AMANDA_sources
+  Compiling_the_Amanda_sources
 
-  Setting_up_your_AMANDA_Configuration
+  Setting_up_your_Amanda_Configuration
 
 
         Setting_up_the_Tape_Server_Host
@@ -38,333 +38,405 @@ Note
 
 Refer to http://www.amanda.org/docs/install.html for the current version of
 this document.
-This document covers the compilation, installation, and runtime setup of AMANDA
+This document covers the compilation, installation, and runtime setup of Amanda
 2.4.2 and higher.
 
  Before doing anything
 
 
-  a. Read this document all the way through.
-  b. Consult AMANDA_2.4.x_-_System-Specific_Installation_Notes for installation
-     notes specific to particular operating systems. There is often important
-     information there, so don't forget this step.
-  c. Read Upgrade_Issues if you are upgrading from a previous AMANDA version.
-     There are some issues that you will need to be aware of.
-  d. If you are using KERBEROS authentication, read Kerberos for details on
-     installing and running the kerberized version of AMANDA.
-  e. Check the AMANDA Patches Page, http://www.amanda.org/patches
+* Read this document all the way through.
+* Consult Amanda_2.4.x_-_System-Specific_Installation_Notes for installation
+  notes specific to particular operating systems. There is often important
+  information there, so don't forget this step.
+* Read Upgrade_Issues if you are upgrading from a previous Amanda version.
+  There are some issues that you will need to be aware of.
+* If you are using KERBEROS authentication, read Kerberos for details on
+  installing and running the kerberized version of Amanda.
+* Check the Amanda Patches Page, http://www.amanda.org/patches/.
 
 
- Compiling the AMANDA sources
+ Compiling the Amanda sources
 
-If you have multiple architectures, you only need to install the whole AMANDA
+If you have multiple architectures, you only need to install the whole Amanda
 package on the tape server host (the one with tape drive). On the backup client
 hosts (the ones you are going to dump), you only need to compile some of the
-AMANDA programs (see section 1.2.H below).
+Amanda programs (see section Set_up_the_Backup_Client_Hosts below).
 
  Source configuration
 
 
-  a. AMANDA can optionally make use of the following packages to back up
-     different types of clients or clients with different filesystem dumping
-     programs. If you wish to use GNU-tar to back up filesystems, it is
-     recommended to use GNU-tar 1.13.25. Plain GNU-tar 1.12 needs to be patched
-     to handle large files (> 2GB). Plain GNU-tar 1.13 creates bad index-lists
-     which amrecover cannot handle, as does the rarely used GNU-tar 1.13.9x,
-     which changed the index-format again in an incompatible way.
-     If you need to use GNU-tar 1.12, get it at
-     ftp://ftp.gnu.org/pub/gnu/tar/tar-1.12.tar.gz
-     and apply the patch from patches/tar-1.12.patch. The first hunk may be
-     enough, unless it's a SunOS4 host. Read more about the patches in the
-     patch file itself.
-     GNU-tar 1.13.25 can be found at:
-     ftp://alpha.gnu.org/pub/gnu/tar/tar-1.13.25.tar.gz
-     Samba allows Unix systems to talk to PC clients. AMANDA can back up
-     Microsoft Windows clients using Samba:
-     http://www.samba.org
-     Read Backup_PC_hosts_using_Samba for configuration tips and known
-     limitations.
-     Look at http://www.amanda.org/patches.html for up to date information on
-     patches.
-  b. If you wish to make use of some of the scripts that come with AMANDA, you
-     will need to install Perl. You can get Perl from any CPAN site. ftp://
-     ftp.cpan.org/pub/CPAN/src/perl-5.6.1.tar.gz
-  c. One of the programs included in this package is amplot, which reads a data
-     file that AMANDA generates for each dump and translates that information
-     in it into a nice picture that can be used to determine how your
-     installation is doing and if any parameters need to be changed. To use
-     amplot, you need a version of awk that understands command line variable
-     substitutions, such as nawk or gawk, which is available from
-     ftp://ftp.gnu.org/pub/gnu/gawk/gawk-3.1.1.tar.gz
-     Amplot also required that gnuplot be installed on your system. Gnuplot is
-     available at
-     http://www.gnuplot.org/ ftp://ftp.gnuplot.org/pub/gnuplot
-  d. The process of building AMANDA requires that some other packages be
-     installed on your system. The following packages are used:
-     ftp://ftp.gnu.org/pub/gnu/readline/readline-4.2.tar.gz amrecover
-     optionally uses the readline library for its command-line edition
-     mechanisms. This library itself requires either termcap, curses or
-     ncurses. termcap is preferred, and it may be obtained from: ftp://
-     ftp.gnu.org/pub/gnu/termcap/termcap-1.3.tar.gz
-     If you wish to edit and enhance AMANDA, you may need to install the
-     following tools. Autoconf and automake are required if you are going to
-     rebuild the Makefiles and auto configuration scripts. Bison is only needed
-     if you are going to work on the index server and client code.
-     ftp://ftp.gnu.org/pub/gnu/autoconf/autoconf-2.53.tar.gz ftp://ftp.gnu.org/
-     pub/gnu/automake/automake-1.6.3.tar.gz ftp://ftp.gnu.org/pub/gnu/bison/
-     bison-1.27.tar.gz ftp://ftp.gnu.org/pub/gnu/flex/flex-2.5.4a.tar.gz
-  e. Read about the different configuration options available for building and
-     running AMANDA. To see the options, do both:
-
-       a. Run
-
-            ./configure --help
-
-          to see the available options that configure takes.
-       b. Read the example/config.site file which gives longer descriptions to
-          the same options as in step a).
-
-  f. Choose which user and group you will run the dumps under. Common choices
-     for user are `bin' or another user specifically created for AMANDA, such
-     as `amanda'; common choices for group are `operator' or `disk'. If you do
-     not specify --with-user=<username> and --with-group=<groupname>, configure
-     will abort. Also choose the default name for your configuration, such as
-     `csd' or `DailySet1'). This name is used by the AMANDA commands to choose
-     one of multiple possible configurations. You may specify it using the --
-     with-config=<confgname>.
-  g. Decide where AMANDA will live. You need to choose a root directory for
-     AMANDA. Let this root directory be called $prefix. Unless you change the
-     default behavior with the appropriate command line options, AMANDA will
-     install itself as. Listed below each directory is the appropriate
-     configure option to change the location of this part of AMANDA.
-
-       --sbindir=$prefix/sbin                                  AMANDA server side programs
-       --libexecdir=$prefix/libexec                            AMANDA backup client programs
-       --libdir=$prefix/lib                                    AMANDA dynamic libraries
-       --with-configdir=$prefix/etc/amanda                     Runtime configuration files
-       --with-gnutar-listdir=$prefix/var/amanda/gnutar-lists   Directory for
-       GNUtar lists (client)
-       --mandir=$prefix/man                                    Directory for manual pages
-
-     Note that the GNU-tar listdir should be a local filesystem on each client
-     that is going to be backed up with GNU tar. If it really must be NFS-
-     mounted, make sure the filesystem is exported so that the client has root
-     access to it.
-  h. Decide if you are compiling AMANDA on a server only or a client only
-     platform. If you have a particular operating system that will only be a
-     AMANDA client and will never run as the master tape host, then add the --
-     without-server option to configure. In the unlikely case that you have a
-     particular operating system that will serve as the tape host and you do
-     not wish to back up any machines that run this operating system, add the -
-     -without-client option to the configure options. There are many other
-     configuration switches for amanda. You may learn more about them by
-     running `configure --help' and by reading examples/config.site.
-  i. Now configure AMANDA. There are two ways of doing this. If you are running
-     AMANDA on a single OS, then probably the first method works better for
-     you. If you need to support multiple platforms, then the second method
-     will work better.
-
-       a. Run configure as non-root-user with the appropriate command line
-          options. You will probably want to remember the command line options
-          for future builds of AMANDA.
-       b. Edit example/config.site and install it in the directory $prefix/etc
-          or $prefix/share. When `configure' runs the next time it will look
-          for this file and use it to configure AMANDA.
+* Amanda can optionally make use of the following packages to back up different
+  types of clients or clients with different filesystem dumping programs.
+
+  o GNU-tar:
+    If you wish to use GNU-tar to back up filesystems, it is recommended to use
+    GNU-tar 1.13.25. Plain GNU-tar 1.12 needs to be patched to handle large
+    files (> 2GB). Plain GNU-tar 1.13 creates bad index-lists which amrecover
+    cannot handle, as does the rarely used GNU-tar 1.13.9x, which changed the
+    index-format again in an incompatible way.
+    Refer to the Amanda_FAQ for more information about issues with the various
+    releases of GNU-tar.
+    If you need to use GNU-tar 1.12, get it at
+    ftp://ftp.gnu.org/pub/gnu/tar/tar-1.12.tar.gz
+    and apply the patch from patches/tar-1.12.patch. The first hunk may be
+    enough, unless it's a SunOS4 host. Read more about the patches in the patch
+    file itself.
+    GNU-tar 1.13.25 can be found at:
+    ftp://alpha.gnu.org/pub/gnu/tar/tar-1.13.25.tar.gz
+  o Samba:
+    Samba allows Unix systems to talk to PC clients. Amanda can back up
+    Microsoft Windows clients using Samba:
+    http://www.samba.org
+    Read Backup_PC_hosts_using_Samba for configuration tips and known
+    limitations.
+    Look at http://www.amanda.org/patches/ for up to date information on
+    patches.
+  o Perl:
+    If you wish to make use of some of the scripts that come with Amanda, you
+    will need to install Perl. You can get Perl from any CPAN site.
+    ftp://ftp.cpan.org/pub/CPAN/src/perl-5.6.1.tar.gz
+  o Awk:
+    One of the programs included in this package is amplot, which reads a data
+    file that Amanda generates for each dump and translates that information in
+    it into a nice picture that can be used to determine how your installation
+    is doing and if any parameters need to be changed. To use amplot, you need
+    a version of awk that understands command line variable substitutions, such
+    as nawk or gawk, which is available from
+    ftp://ftp.gnu.org/pub/gnu/gawk/gawk-3.1.1.tar.gz
+  o GNUplot:
+    Amplot also required that gnuplot be installed on your system. Gnuplot is
+    available at
+    http://www.gnuplot.org/ ftp://ftp.gnuplot.org/pub/gnuplot
+  o Other packages:
+    The process of building Amanda requires that some other packages be
+    installed on your system. The following packages are used:
+    ftp://ftp.gnu.org/pub/gnu/readline/readline-5.0.tar.gz
+    amrecover optionally uses the readline library for its command-line edition
+    mechanisms. (If you use a package-based distribution, check for the package
+    readline-devel-X.Y.rpm.) This library itself requires either termcap,
+    curses or ncurses. termcap is preferred, and it may be obtained from:
+    ftp://ftp.gnu.org/pub/gnu/termcap/termcap-1.3.1.tar.gz.
+    If you wish to edit and enhance Amanda, you may need to install the
+    following tools. Autoconf and automake are required if you are going to
+    rebuild the Makefiles and auto configuration scripts. Bison is only needed
+    if you are going to work on the index server and client code.
+    ftp://ftp.gnu.org/pub/gnu/autoconf/autoconf-2.53.tar.gz ftp://ftp.gnu.org/
+    pub/gnu/automake/automake-1.6.3.tar.gz ftp://ftp.gnu.org/pub/gnu/bison/
+    bison-1.27.tar.gz ftp://ftp.gnu.org/pub/gnu/flex/flex-2.5.4a.tar.gz
+
+* Read about the different configuration options available for building and
+  running Amanda. To see the options, do both:
+
+  o Run ./configure --help to see the available options that configure takes.
+  o Read the file example/config.site which gives longer descriptions to the
+    same options.
+
+* Choose which user and group you will run the dumps under. Common choices for
+  user are `bin' or another user specifically created for Amanda, such as
+  `amanda'; common choices for group are `operator' or `disk'. If you do not
+  specify --with-user=<username> and --with-group=<groupname>, configure will
+  abort. Also choose the default name for your configuration, such as `csd' or
+  `DailySet1'). This name is used by the Amanda commands to choose one of
+  multiple possible configurations. You may specify it using the --with-
+  config=<confgname>.
+* Decide where Amanda will live. You need to choose a root directory for
+  Amanda. Let this root directory be called $prefix. Unless you change the
+  default behavior with the appropriate command line options, Amanda will
+  install itself as. Listed below you find the appropriate configure-option for
+  each directory to change the location of this part of Amanda.
+
+    --sbindir=$prefix/sbin                                     Amanda server side programs
+    --libexecdir=$prefix/libexec                               Amanda backup client programs
+    --libdir=$prefix/lib                                       Amanda dynamic libraries
+    --with-configdir=$prefix/etc/amanda                        Runtime configuration files
+    --with-gnutar-listdir=$prefix/var/amanda/gnutar-lists      Directory for GNU-tar
+    lists (client)
+    --mandir=$prefix/man                                       Directory for manual pages
+
+  Note that the GNU-tar listdir should be a local filesystem on each client
+  that is going to be backed up with GNU-tar. If it really must be NFS-mounted,
+  make sure the filesystem is exported so that the client has root access to
+  it.
+* Decide if you are compiling Amanda on a server only or a client only
+  platform. If you have a particular operating system that will only be a
+  Amanda client and will never run as the master tape host, then add the --
+  without-server option to configure. In the unlikely case that you have a
+  particular operating system that will serve as the tape host and you do not
+  wish to back up any machines that run this operating system, add the --
+  without-client option to the configure options. There are many other
+  configuration switches for Amanda. You may learn more about them by running
+  configure --help and by reading examples/config.site.
+* Now configure Amanda. There are two ways of doing this. If you are running
+  Amanda on a single OS, then probably the first method works better for you.
+  If you need to support multiple platforms, then the second method will work
+  better.
+
+  o Run configure as non-root-user with the appropriate command line options.
+    You will probably want to remember the command line options for future
+    builds of Amanda.
+  o Edit examples/config.site and install it in the directory $prefix/etc or
+    $prefix/share. When configure runs the next time it will look for this file
+    and use it to configure Amanda.
 
 
 
  Building and installing the binaries
 
 
-  a. Back at the top-level source directory, build the sources:
+* Back at the top-level source directory, build the sources:
 
-       make
-       su root; make install
+    make
+    su root; make install
 
-     Make sure that you don't build the software as root, you may run the first
-     make-command as the AMANDA-user, for example. On the other hand you have
-     to run make install as root to get the binaries installed with the proper
-     permissions. If you want to change the compiler flags, you can do so like
-     this:
+  Make sure that you don't build the software as root, you may run the first
+  make-command as the Amanda-user, for example. On the other hand you have to
+  run make install as root to get the binaries installed with the proper
+  permissions. If you want to change the compiler flags, you can do so like
+  this:
 
-       make CFLAGS="-O3 -Wall"
+    make CFLAGS="-O3 -Wall"
 
-  b. If you have built with USE_VERSION_SUFFIXES, you will want to create
-     symlinks to the version you wish to use, eg:
+* If you have built with USE_VERSION_SUFFIXES, you will want to create symlinks
+  to the version you wish to use, eg: ln -s amdump-x.y.z amdump This is not
+  done automatically by the install process, so that you can have multiple
+  Amanda versions co-existing, and choose yourself which to make the default
+  version. The script contrib/set_prod_link.pl may save you some keystrokes.
+* Run ldconfig as root to update the paths to the recently installed shared
+  libraries.
 
-       ln -s amdump-x.y.z amdump
 
-     This is not done automatically by the install process, so that you can
-     have multiple AMANDA versions co-existing, and choose yourself which to
-     make the default version. The script contrib/set_prod_link.pl may save you
-     some keystrokes.
-  c. Run `ldconfig' as root to update the paths to the recently installed
-     shared libraries.
-
-
- Setting up your AMANDA Configuration
+ Setting up your Amanda Configuration
 
 
  Setting up the Tape Server Host
 
 
-  a. Create the config directory (eg. /usr/local/etc/amanda/confname) and copy
-     the example/ files into that directory. Edit these files to be correct for
-     your site, consulting the amanda(8) man page if necessary. You can also
-     send mail to mailto://amanda-users@amanda.org if you are having trouble
-     deciding how to set things up. You will also need to create the directory
-     for the log and database files for the configuration to use (eg /usr/
-     local/var/amanda/confname), and the work directory on the holding disk.
-     These directories need to agree with the parameters in amanda.conf. Don't
-     forget to make all these directories writable by the dump user!
-     Make sure that you specify the *no-rewind* version of the tape device in
-     your amanda.conf file. This is a frequently encountered problem for new
-     sites.
-     Note that you might want to temporarily set the option "no-record" in all
-     your dumptypes when first installing AMANDA if you'd like to run tests of
-     AMANDA in parallel with your existing dump scheme. AMANDA will then run
-     but will not interfere with your current dumpdates. However, you don't
-     want to run with "no-record" under normal operations.
-  b. Put AMANDA into your crontab. Here's a sample:
-
-       0 16 * * 1-5 /usr/local/sbin/amcheck -m confname
-       45 0 * * 2-6 /usr/local/sbin/amdump confname
-
-     This is for SunOS 4.x, which has a per-user crontab; most other systems
-     also require a userid on each cron line. See your cron(8) for details.
-     With these cron lines, AMANDA will check that the correct tape is in the
-     drive every weekday afternoon at 4pm (if it isn't, all the operators will
-     get mail). At 12:45am that night the dumps will be run.
-  c. Put the AMANDA services into your /etc/services file. Add entries like:
-
-       amanda          10080/udp
-       amandaidx       10082/tcp
-       amidxtape       10083/tcp
-
-     You may choose a different port number if you like, but it must match that
-     in the services file on the client hosts too.
-     If you are running NIS (aka YP), you have to enter the AMANDA service into
-     your NIS services database. Consult your NIS documentation for details.
-     You may use the `patch-system' script, from client-src, in order to modify
-     this file. Run it with a `-h' argument for usage.
-  d. If you are going to use the indexing capabilities of AMANDA, and your
-     server uses inetd, then add these to your inetd.conf on the tape server
-     host:
-
-       amandaidx stream tcp nowait USER AMINDEXD_PATH amindexd
-       amidxtape stream tcp nowait USER AMIDXTAPED_PATH amidxtaped
-
-     where AMINDEXD_PATH and AMIDXTAPED_PATH are the complete paths to where
-     the amindexd and amidxtaped executables (usually libexec_dir/amindexd and
-     libexec_dir/amidxtaped), and USER is the AMANDA user.
-     You may use the `patch-system' script, from client-src, in order to modify
-     this file. Run it with a `-h' argument for usage.
-     If your tape server uses xinetd instead of inetd, then you have to add the
-     following two files to your xinetd-configuration (usually /etc/xinetd.d)
-     and edit the paths:
-
-       #/etc/xinetd.d/amandaidx
-       service amandaidx
-       {
-               socket_type             = stream
-               protocol                = tcp
-               wait                    = no
-               user                    = USER
-               group                   = GROUP
-               groups                  = yes
-               server                  = AMINDEXD_PATH/amindexd
-       }
-
-
-       #/etc/xinetd.d/amidxtaped
-       service amidxtape
-       {
-               socket_type             = stream
-               protocol                = tcp
-               wait                    = no
-               user                    = USER
-               group                   = GROUP
-               groups                  = yes
-               server                  = AMIDXTAPED_PATH/amidxtaped
-       }
-
-  e. If the tape server host is itself going to be backed up (as is usually the
-     case), you must also follow the client-side install instructions below on
-     the server host, INCLUDING setting up the file .amandahosts so that the
-     server host lets itself in. This is a frequently encountered problem for
-     new sites.
+* Create the config directory (eg. /usr/local/etc/amanda/confname) and copy the
+  example/ files into that directory. Edit these files to be correct for your
+  site, consulting the amanda(8) man page if necessary. You can also send mail
+  to mailto://amanda-users@amanda.org if you are having trouble deciding how to
+  set things up. You will also need to create the directory for the log and
+  database files for the configuration to use (eg /usr/local/var/amanda/
+  confname), and the work directory on the holding disk. These directories need
+  to agree with the parameters in amanda.conf. Don't forget to make all these
+  directories writable by the dump user!
+  Make sure that you specify the *no-rewind* version of the tape device in your
+  amanda.conf file. This is a frequently encountered problem for new sites.
+  Note that you might want to temporarily set the option "no-record" in all
+  your dumptypes when first installing Amanda if you'd like to run tests of
+  Amanda in parallel with your existing dump scheme. Amanda will then run but
+  will not interfere with your current dumpdates. However, you don't want to
+  run with "no-record" under normal operations.
+* Put Amanda into your crontab. Here's a sample:
+  Example 2.1. /etc/crontab
+
+    0 16 * * 1-5 /usr/local/sbin/amcheck -m confname
+    45 0 * * 2-6 /usr/local/sbin/amdump confname
+
+  This is for SunOS 4.x, which has a per-user crontab; most other systems also
+  require a userid on each cron line. See your cron(8) for details. With these
+  cron lines, Amanda will check that the correct tape is in the drive every
+  weekday afternoon at 4pm (if it isn't, all the operators will get mail). At
+  12:45am that night the dumps will be run.
+* Put the Amanda services into your /etc/services file. Add entries like:
+  Example 2.2. /etc/services
+
+    amanda             10080/udp
+    amandaidx  10082/tcp
+    amidxtape  10083/tcp
+
+  You may choose a different port number if you like, but it must match that in
+  the services file on the client hosts too.
+  If you are running NIS (aka YP), you have to enter the Amanda service into
+  your NIS services database. Consult your NIS documentation for details.
+  You may use the `patch-system' script, from client-src, in order to modify
+  this file. Run it with a `-h' argument for usage.
+* If you are going to use the indexing capabilities of Amanda, follow one of
+  the following steps:
+
+  o If your server uses inetd, then add these lines to your inetd.conf on the
+    tape server host:
+    Example 2.3. /etc/inetd.conf
+
+       amandaidx stream tcp nowait $USER $AMINDEXD_PATH amindexd
+       amidxtape stream tcp nowait $USER $AMIDXTAPED_PATH amidxtaped
+
+    where $AMINDEXD_PATH and $AMIDXTAPED_PATH are the complete paths to where
+    the amindexd and amidxtaped executables (usually libexec_dir/amindexd and
+    libexec_dir/amidxtaped), and USER is the Amanda user.
+    You may use the `patch-system' script, from client-src, in order to modify
+    this file. Run it with a `-h' argument for usage.
+  o If your tape server uses xinetd instead of inetd, then you have to add the
+    following two files to your xinetd-configuration (usually /etc/xinetd.d)
+    and edit the paths:
+    Example 2.4. /etc/xinetd.d/amandaidx
+
+       service amandaidx
+      {
+       socket_type             = stream
+               protocol                = tcp
+               wait                    = no
+               user                    = $USER
+               group                   = $GROUP
+               groups                  = yes
+               server                  = $AMINDEXD_PATH/amindexd }
+
+    Example 2.5. /etc/xinetd.d/amidxtape
+
+      service amidxtape
+      {
+       socket_type             = stream
+               protocol                = tcp
+               wait                    = no
+               user                    = $USER
+               group                   = $GROUP
+               groups                  = yes
+               server                  = $AMIDXTAPED_PATH/amidxtaped }
+
+  o If your tape server uses Dan Bernstein's daemontools http://cr.yp.to/
+    daemontools.html) instead of (x)inetd, you have to create amandaidx and
+    amidxtape services by hand.
+
+    # Create service directories:
+
+        mkdir -p $prefix/etc/amanda/supervise/amandaidx
+        mkdir -p $prefix/etc/amanda/supervise/amidxtape
+
+    # Create service startup files and make them executable:
+      Example 2.6. /etc/amanda/supervise/amandaidx/run
+
+        #!/bin/sh
+        exec /usr/local/bin/setuidgid amanda \
+        /usr/local/bin/tcpserver -DHRl0 0 10082 \
+        /usr/local/libexec/amindexd >/dev/null 2>/dev/null
+
+      Example 2.7. /etc/amanda/supervise/amidxtape/run
+
+        #!/bin/sh
+        exec /usr/local/bin/setuidgid amanda \
+        /usr/local/bin/tcpserver -DHRl0 0 10083 \
+        /usr/local/libexec/amidxtaped >/dev/null 2>/dev/null
+
+    # Link service directories into your svscan directory:
+
+        cd /service
+        ln -s $prefix/etc/amanda/supervise/amandaidx .
+        ln -s $prefix/etc/amanda/supervise/amidxtape .
+
+
+
+* If the tape server host is itself going to be backed up (as is usually the
+  case), you must also follow the client-side install instructions below on the
+  server host, INCLUDING setting up the file .amandahosts so that the server
+  host lets itself in. This is a frequently encountered problem for new sites.
 
 
  Set up the Backup Client Hosts
 
 
-  a. When using BSD-style security (enabled by default), set up your
-     ~dumpuser/.amandahosts (or ~dumpuser/.rhosts and/or /etc/hosts.equivi, if
-     you have configured --without-amandahosts) so that the dumpuser is allowed
-     in from the server host. Only canonical host names will be accepted in
-     .amandahosts, and usernames must be present in every line, because this is
-     safer.
-  b. Set up your raw disk devices so that the dumpuser can read them, and /etc/
-     dumpdates so that the dumpuser can write to it. Normally this is done by
-     making the disk devices readable by (and dumpdates read/writable by) group
-     `operator', and putting the dumpuser into that group.
-  c. Put the AMANDA service into your /etc/services file. Add entry like:
-
-       amanda          10080/udp
-       amandaidx       10082/tcp
-       amidxtape       10083/tcp
-
-     You may choose a different port number if you like, but it must match that
-     in the services file on the tape server host too.
-     If you are running NIS (aka YP), you have to enter the AMANDA service into
-     your NIS services database. Consult your NIS documentation for details.
-     You may use the `patch-system' script, from client-src, in order to modify
-     this file. Run it with a `-h' argument for usage.
-  d. If your AMANDA client uses inetd, put the AMANDA client service into
-     inetd's config file. This file is usually found in /etc/inetd.conf, but on
-     older systems it is /etc/servers. The format is different on different
-     OSes, so you must consult the inetd man page for your site. Here is an
-     example from our site, again from SunOS 4.x:
-
-       amanda dgram udp wait USER AMANDAD_PATH amandad
-
-     You may use the `patch-system' script, from client-src, in order to modify
-     this file. Run it with a `-h' argument for usage.
-     If your AMANDA client uses xinetd, you have to add the following file to
-     your xinetd-configuration (usually /etc/xinetd.d):
-
-       #/etc/xinetd.d/amanda
-       service amanda
-       {
-       socket_type             = dgram
-       protocol                = udp
-       wait                    = yes
-       user                    = USER
-       group                   = GROUP
-       groups                  = yes
-       server                  = AMANDAD_PATH/amandad
-       }
-
-  e. Kick inetd/xinetd to make it read its config file. On most systems you can
-     just execute kill -HUP inetd (or xinetd). On older systems you may have to
-     kill it completely and restart it. Note that killing/restarting (x)inetd
-     is not safe to do unless you are sure that no (x)inetd services (like
-     rlogin) are currently in use, otherwise (x)inetd will not be able to bind
-     that port and that service will be unavailable.
-  f. If you intend to back up xfs filesystems on hosts running IRIX, you must
-     create the directory /var/xfsdump/inventory, otherwise xfsdump will not
-     work.
+* When using BSD-style security (enabled by default), set up your
+  ~dumpuser/.amandahosts (or ~dumpuser/.rhosts and/or /etc/hosts.equiv, if you
+  have configured --without-amandahosts) so that the dumpuser is allowed in
+  from the server host. Only canonical host names will be accepted in
+  .amandahosts, and usernames must be present in every line, because this is
+  safer.
+* Set up your raw disk devices so that the dumpuser can read them, and /etc/
+  dumpdates so that the dumpuser can write to it. Normally this is done by
+  making the disk devices readable by (and dumpdates read/writable by) group
+  `operator', and putting the dumpuser into that group.
+* Put the Amanda service into your /etc/services file. Add entry like:
+  Example 2.8. /etc/services
+
+    amanda             10080/udp
+    amandaidx  10082/tcp
+    amidxtape  10083/tcp
+
+  You may choose a different port number if you like, but it must match that in
+  the services file on the tape server host too.
+  If you are running NIS (aka YP), you have to enter the Amanda service into
+  your NIS services database. Consult your NIS documentation for details.
+  You may use the `patch-system' script, from client-src, in order to modify
+  this file. Run it with a `-h' argument for usage.
+* Follow one of the following steps to set up the Amanda client service:
+
+  o If your Amanda client uses inetd, put the Amanda client service into
+    inetd's config file. This file is usually found in /etc/inetd.conf, but on
+    older systems it is /etc/servers. The format is different on different
+    OSes, so you must consult the inetd man page for your site. Here is an
+    example from our site, again from SunOS 4.x:
+    Example 2.9. /etc/inetd.conf
+
+      amanda dgram udp wait USER AMANDAD_PATH amandad
+
+    You may use the `patch-system' script, from client-src, in order to modify
+    this file. Run it with a `-h' argument for usage.
+  o If your Amanda client uses xinetd, you have to add the following file to
+    your xinetd-configuration (usually /etc/xinetd.d) and edit it to reflect
+    your settings and paths:
+    Example 2.10. /etc/xinetd.d/amanda
+
+      service amanda
+      {
+      socket_type              = dgram
+      protocol         = udp
+      wait                     = yes
+      user                     = $USER
+      group                    = $GROUP
+      groups                   = yes
+      server                   = $AMANDAD_PATH/amandad
+      }
+
+  o If your Amanda client uses Dan Bernstein's daemontools (http://cr.yp.to/
+    daemontools.html) instead of (x)inetd, you have to create the amanda
+    service by hand. You will need also an UDP super-server (netcat in this
+    example).
+
+    # Create service directory:
+
+        mkdir -p /etc/amanda/supervise/amanda
+
+    # Create service startup file and make it executable:
+      Example 2.11. /etc/amanda/supervise/amanda/run
+
+        #!/bin/sh
+        exec /usr/local/bin/setuidgid amanda \
+          /usr/bin/netcat -l -u -p 10080 -q 0 \
+          -e /usr/local/libexec/amandad >/dev/null 2>/dev/null
+
+
+      Note
+
+      The netcat-binary used in this run-file might also be called /usr/bin/nc
+      on your system, depending on the OS-distribution you use. Refer to http:/
+      /netcat.sourceforge.net for details of netcat.
+    # Link service directory into your svscan directory:
+
+        cd /service
+        ln -s /etc/amanda/supervise/amanda .
+
+
+
+* If you are using (x)inetd, kick inetd/xinetd to make it read its config file.
+  On most systems you can just execute kill -HUP inetd (or xinetd). On older
+  systems you may have to kill it completely and restart it. Note that killing/
+  restarting (x)inetd is not safe to do unless you are sure that no (x)inetd
+  services (like rlogin) are currently in use, otherwise (x)inetd will not be
+  able to bind that port and that service will be unavailable.
+  If you are using the daemontools, svscan should detect and start your new
+  services automatically.
+* If you intend to back up xfs filesystems on hosts running IRIX, you must
+  create the directory /var/xfsdump/inventory, otherwise xfsdump will not work.
 
 THAT'S IT! YOU ARE READY TO RUN, UNLESS WE FORGOT SOMETHING.
 Please send mail to mailto://amanda-users@amanda.org if you have any comments
 or questions. We're not afraid of negative reviews, so let us have it!
-Before writing questions, you may prefer to take a look at the AMANDA_FAQ and
-at the AMANDA home page, at http://www.amanda.org. Browsable archives of AMANDA
+Before writing questions, you may prefer to take a look at the Amanda_FAQ and
+at the Amanda home page, at http://www.amanda.org. Browsable archives of Amanda
 mailing-lists are available at http://marc.theaimsgroup.com/?l=amanda-users and
 http://marc.theaimsgroup.com/?l=amanda-hackers.
 -------------------------------------------------------------------------------
 
 Prev                                       Up                   Next
-Chapter 1. AMANDA 2.4.x - System-Specific Home  Chapter 3. Excluding
+Chapter 1. Amanda 2.5.0 - System-Specific Home  Chapter 3. Excluding
 Installation Notes 
 
index 17fa74d61d3b79b87e7f077f4c02ccea9c57b8df..a95442ad1c032e54e0b6af2c02aad4ab5e60f111 100644 (file)
@@ -1,10 +1,10 @@
 
-         Chapter 23. AMANDA Internals
+         Chapter 24. Amanda Internals
 Prev  Part V. Technical Background  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 23. AMANDA Internals
+Chapter 24. Amanda Internals
 
 
 George Scott
@@ -34,7 +34,7 @@ Note
 
 Refer to http://www.amanda.org/docs/internals.html for the current version of
 this document.
-This is an attempt to document AMANDA's internals. Please feel free to make
+This is an attempt to document Amanda's internals. Please feel free to make
 comments and suggest changes. Text for new sections gratefully accepted!
 
  Protocols
@@ -44,7 +44,7 @@ Note
 
 The following was an ASCII-illustration in the original docs, I managed to
 transfer it at last. Maybe someone will convert this to the first image in the
-AMANDA-docs ;-) . sgw.
+Amanda-docs ;-) . sgw.
 
 
         Client I Server         +-planner-+
@@ -177,5 +177,5 @@ Quit Q --->
 -------------------------------------------------------------------------------
 
 Prev                            Up                           Next
-Chapter 22. AMANDA dumper API  Home  Chapter 24. AMANDA Event API
+Chapter 23. Amanda dumper API  Home  Chapter 25. Amanda Event API
 
index 9098bbb56640c9dba25934a9b22c27fc60871e6c..4596658f94232455a682d0c88b35adfe8e15c27c 100644 (file)
@@ -5,22 +5,24 @@ Prev            Next
 -------------------------------------------------------------------------------
 
 
-Installation
+Part I. Installation
 
 
 
 Initial Installation
 
-This section of the AMANDA-docs contains general info on how to install AMANDA
+This section of the Amanda-docs contains general info on how to install Amanda
 and how to configure its basic parts. Please read this!
 Table of Contents
 
 
-  1._AMANDA_2.4.x_-_System-Specific_Installation_Notes
+  1._Amanda_2.5.0_-_System-Specific_Installation_Notes
 
 
         Solaris_2.6
 
+        Solaris
+
         Trusted_Solaris
 
         SunOS_4.x
@@ -56,14 +58,14 @@ Table of Contents
         Mac_OS_X
 
 
-  2._AMANDA_Installation_Notes
+  2._Amanda_Installation_Notes
 
 
         Before_doing_anything
 
-        Compiling_the_AMANDA_sources
+        Compiling_the_Amanda_sources
 
-        Setting_up_your_AMANDA_Configuration
+        Setting_up_your_Amanda_Configuration
 
 
               Setting_up_the_Tape_Server_Host
@@ -100,7 +102,7 @@ Table of Contents
 
 
 
-  4._Indexing_with_AMANDA
+  4._Indexing_with_Amanda
 
 
         Database_Format
@@ -144,7 +146,7 @@ Table of Contents
 
 -------------------------------------------------------------------------------
 
-Prev           Up                                                     Next
-Attributions  Home  Chapter 1. AMANDA 2.4.x - System-Specific Installation
+Prev                                                                  Next
+Attributions  Home  Chapter 1. Amanda 2.5.0 - System-Specific Installation
                                                                      Notes
 
index 35f588577347fb1563b5724e8de6524101463678..ad2272b89dd3c55ac5731c64e92c2ee7a0338291 100644 (file)
@@ -14,13 +14,6 @@ A
   autoflush, the_multiple-dumps-question
 
 
-B
-
-
-
-  bumping, AMANDA_FAQ
-
-
 C
 
 
@@ -90,6 +83,6 @@ V
 
 -------------------------------------------------------------------------------
 
-Prev                         Up   
-Chapter 36. Web Ressources  Home  
+Prev                              
+Chapter 37. Web Ressources  Home  
 
index 3b6b64b496897fff6f11f0e4d49996b2011fea6d..81fdadd0b57de760ee9e23e226b885f615f1aa42 100644 (file)
@@ -1,13 +1,13 @@
 
- Chapter 27. Using Kerberos with AMANDA
+ Chapter 28. Using Kerberos with Amanda
 Prev  Part V. Technical Background  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 27. Using Kerberos with AMANDA
+Chapter 28. Using Kerberos with Amanda
 
 
-AMANDA Core Team
+Amanda Core Team
 
 Original text
 AMANDA Core Team
@@ -20,7 +20,7 @@ AMANDA Core Team
 Table of Contents
 
 
-  AMANDA_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
+  Amanda_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
 
 
         Configuration
@@ -30,7 +30,7 @@ Table of Contents
         conf_file
 
 
-  AMANDA_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
+  Amanda_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
 
 
         Building
@@ -48,7 +48,7 @@ Note
 Refer to http://www.amanda.org/docs/kerberos.html for the current version of
 this document.
 
- AMANDA 2.5.0 - KERBEROS v4 SUPPORT NOTES
+ Amanda 2.5.0 - KERBEROS v4 SUPPORT NOTES
 
 
  Configuration
@@ -88,7 +88,7 @@ libkrb.a.
 
  Installation
 
-The kerberized AMANDA service uses a different port on the client hosts. The /
+The kerberized Amanda service uses a different port on the client hosts. The /
 etc/services line is:
 
   kamanda      10081/udp
@@ -100,7 +100,7 @@ And the /etc/inetd.conf line is:
   auth=krb4
        
 
-Note that you're running this as root, rather than as your dump user. AMANDA
+Note that you're running this as root, rather than as your dump user. Amanda
 will set it's uid down to the dump user at times it doesn't need to read the
 srvtab file, and give up root permissions entirely before it goes off and runs
 dump. Alternately you can change your srvtab files to be readable by user
@@ -121,7 +121,7 @@ The following dumptype options apply to krb4:
        
 
 
- AMANDA 2.5.0 - KERBEROS v5 SUPPORT NOTES
+ Amanda 2.5.0 - KERBEROS v5 SUPPORT NOTES
 
 
  Building
@@ -141,12 +141,12 @@ The krb5 driver script defaults to:
   /*
    * The lifetime of our tickets in minutes.
    */
-  #define AMANDA_TKT_LIFETIME     (12*60)
+  #define Amanda_TKT_LIFETIME     (12*60)
 
   /*
    * The name of the service in /etc/services.
    */
-  #define AMANDA_KRB5_SERVICE_NAME        "k5amanda"
+  #define Amanda_KRB5_SERVICE_NAME        "k5amanda"
        
 
 You can currently only override these by editing the source.
@@ -156,7 +156,7 @@ want to and that's described in common-src/krb5-security.c
 
  Installation
 
-The kerberized AMANDA service uses a different port on the client hosts. The /
+The kerberized Amanda service uses a different port on the client hosts. The /
 etc/services line is:
 
   k5amanda      10082/tcp
@@ -168,7 +168,7 @@ And the /etc/inetd.conf line is:
   auth=krb5
        
 
-Note that you're running this as root, rather than as your dump user. AMANDA
+Note that you're running this as root, rather than as your dump user. Amanda
 will set it's uid down to the dump user at times it doesn't need to read the
 keytab file, and give up root permissions entirely before it goes off and runs
 dump. Alternately you can change your keytab files to be readable by user
@@ -214,8 +214,8 @@ This is described in section 4.
 There are several ways to go about authorizing a server to connect to a client.
 The normal way is via a .k5amandausers file or a .k5login file in the client
 user's home directory. The determination of which file to use is based on the
-way you ran configure on AMANDA. By default, AMANDA will use .k5amandahosts,
-but if you configured with --without-amandahosts, AMANDA will use .k5login.
+way you ran configure on Amanda. By default, Amanda will use .k5amandahosts,
+but if you configured with --without-amandahosts, Amanda will use .k5login.
 (similar to the default for .rhosts/.amandahosts-style security). The .k5login
 file syntax is a superset of the default krb5 .k5login. The routines to check
 it are implemented in amanda rather than using krb5_kuserok because the
@@ -249,5 +249,5 @@ have cross-realm authentication setup).
 -------------------------------------------------------------------------------
 
 Prev                           Up                        Next
-Chapter 26. Virtual Tape API  Home  Part VI. Historical files
+Chapter 27. Virtual Tape API  Home  Part VI. Historical files
 
index 5693880c16364ac096ec08cb4d554ff9cb69c2c3..7342f166df81923b5b3814df90e8d13b6c91b150 100644 (file)
@@ -31,14 +31,14 @@ of this document.
 
  The New Feature
 
-AMANDA now has the ability to print postscript paper tape labels. The labels
+Amanda now has the ability to print postscript paper tape labels. The labels
 have what machines, partitions, and the level of the dump the tape has on it.
 This is achieved by adding the lbl-templ field to the tapetype definition.
 Since the labels are specific to the type of tape you have, that seemed to most
 logical place to add it.
 You can also specify an alternate "printer" definition to print the label to
 other than the system default printer.
-If you don't add this line to your tapetype definition, AMANDA works as it
+If you don't add this line to your tapetype definition, Amanda works as it
 always has.
 
  Labels provided
@@ -56,12 +56,12 @@ Others are encouraged to do so.
 
 At the University of Colorado at Boulder, we used to use some dump scripts that
 printed out paper tape labels that went with the tape. When we started using
-AMANDA for our dumps, my boss insisted we still generate them, in case we
-weren't able to access the AMANDA database. The thought was that as long as we
+Amanda for our dumps, my boss insisted we still generate them, in case we
+weren't able to access the Amanda database. The thought was that as long as we
 had an amrestore binary on a machine, we could just look at the label, grab the
 tapes, and do the restore.
 As a result of this we have had to hack this feature into every version of
-AMANDA from 2.1.1 through 2.4.0-prerelease.
+Amanda from 2.1.1 through 2.4.0-prerelease.
 Our hope in adding this feature is that others find it as useful as we have.
 
  How it works
index 5b9519e6ba937a9e4912ce826c00113e72ae2bcf..2df00fc2d40cc24d76c6ef73970b4ffa861708f2 100644 (file)
@@ -1,10 +1,10 @@
 
-    Chapter 36. Web Ressources
+    Chapter 37. Web Ressources
 Prev  Part VII. Appendixes  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 36. Web Ressources
+Chapter 37. Web Ressources
 
 
 Stefan G. Weichinger
@@ -17,12 +17,12 @@ Note
 
 Refer to http://www.amanda.org/docs/links.html for the current version of this
 document.
-See some original AMANDA-papers by James da Silva and Olafur Gundmundsson here:
+See some original Amanda-papers by James da Silva and Olafur Gundmundsson here:
 
-* The presentation of AMANDA:
+* The presentation of Amanda:
   Postscript: http://www.amanda.org/docs/lisa-vii.ps
   PDF: http://www.amanda.org/docs/lisa-vii.pdf
-* A document about the performance of AMANDA:
+* A document about the performance of Amanda:
   Postscript: http://www.amanda.org/docs/usenix92.ps
   PDF: http://www.amanda.org/docs/usenix92.pdf
 
index fda852c1bbc8203bf2e9ac8ab23f67d37181ce18..27b70072265ed138424e1ef227b52e747949e2c1 100644 (file)
@@ -1,69 +1,84 @@
 
-Chapter 35. The AMANDA Manual Pages.
+Chapter 36. The Amanda Manual Pages.
 Prev  Part VII. Appendixes      Next
 
 -------------------------------------------------------------------------------
 
-Chapter 35. The AMANDA Manual Pages.
+Chapter 36. The Amanda Manual Pages.
 
 Table of Contents
 
 
-  amadmin - administrative interface to control AMANDA backups
+  amadmin - administrative interface to control Amanda backups
+
+  amaespipe - wrapper program for aespipe
 
   amanda - Advanced Maryland Automatic Network Disk Archiver
 
-  amanda.conf - Main configuration file for AMANDA, the Advanced Maryland
+  amanda.conf - Main configuration file for Amanda, the Advanced Maryland
   Automatic Network Disk Archiver
 
-  amcheck - run AMANDA self-checks
+  amanda-client.conf - Client configuration file for Amanda, the Advanced
+  Maryland Automatic Network Disk Archiver
+
+  amcheck - run Amanda self-checks
+
+  amcheckdb - check Amanda database for tape consistency
+
+  amcleanup - run the Amanda cleanup process after a failure
+
+  amcrypt - reference crypt program for Amanda symmetric data encryption
+
+  amcrypt-ossl - crypt program for Amanda symmetric data encryption using
+  OpenSSL
 
-  amcheckdb - check AMANDA database for tape consistency
+  amcrypt-ossl-asym - crypt program for Amanda asymmetric data encryption using
+  OpenSSL
 
-  amcleanup - run the AMANDA cleanup process after a failure
+  amdd - Amanda version of dd
 
-  amdd - AMANDA version of dd
+  amdump - back up all disks in an Amanda configuration
 
-  amdump - back up all disks in an AMANDA configuration
+  amfetchdump - extract backup images from multiple Amanda tapes.
 
-  amflush - flush AMANDA backup files from holding disk to tape
+  amflush - flush Amanda backup files from holding disk to tape
 
   amgetconf - look up amanda.conf variables
 
-  amlabel - label an AMANDA tape
+  amlabel - label an Amanda tape
 
-  ammt - AMANDA version of mt
+  ammt - Amanda version of mt
 
-  amoverview - display file systems processed by AMANDA over time
+  amoverview - display file systems processed by Amanda over time
 
-  amplot - visualize the behavior of AMANDA
+  amplot - visualize the behavior of Amanda
 
-  amrecover - AMANDA index database browser
+  amrecover - Amanda index database browser
 
-  amreport - generate a formatted output of statistics for an AMANDA run
+  amreport - generate a formatted output of statistics for an Amanda run
 
-  amrestore - extract backup images from an AMANDA tape
+  amrestore - extract backup images from an Amanda tape
 
-  amrmtape - remove a tape from the AMANDA database
+  amrmtape - remove a tape from the Amanda database
 
-  amstatus - display the state of an AMANDA run
+  amstatus - display the state of an Amanda run
 
-  amtape - user interface to AMANDA tape changer controls
+  amtape - user interface to Amanda tape changer controls
 
   amtapetype - generate a tapetype definition.
 
-  amtoc - generate TOC (Table Of Contents) for an AMANDA run
+  amtoc - generate TOC (Table Of Contents) for an Amanda run
 
   amverify - check an Amanda tape for errors
 
-  amverifyrun - check the tapes written by the last AMANDA run
+  amverifyrun - check the tapes written by the last Amanda run
 
 
 Note
 
 Refer to http://www.amanda.org/docs/manpages.html for the current version of
 this document.
-This chapter contains the manual pages from the official AMANDA distribution.
+This chapter contains the manual pages from the official Amanda distribution.
 -------------------------------------------------------------------------------
 
 Prev                   Up      Next
index 920920ed6086dfc8338dcb600682dbe6867c10f3..b9bbe49d5a00ca4bb6e536bed3fd06b5690aa1d0 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 31. Multitape support in AMANDA 2.2
+Chapter 32. Multitape support in Amanda 2.2
 Prev  Part VI. Historical files        Next
 
 -------------------------------------------------------------------------------
 
-Chapter 31. Multitape support in AMANDA 2.2
+Chapter 32. Multitape support in Amanda 2.2
 
 
 James da Silva
@@ -56,8 +56,8 @@ this document.
 
  Introduction
 
-The goal of this enhancement is to make AMANDA independent of the number of
-tapes used per run or even per dump cycle. Specifically, I would like AMANDA to
+The goal of this enhancement is to make Amanda independent of the number of
+tapes used per run or even per dump cycle. Specifically, I would like Amanda to
 handle the following:
 
 * output of amdump run goes to more than one tape
@@ -79,10 +79,10 @@ And later:
  Time
 
 Previously, planner marked time by the number of amdump runs, which it equated
-with number of tapes, and number of days. In AMANDA 2.2, AMANDA keeps track of
+with number of tapes, and number of days. In Amanda 2.2, Amanda keeps track of
 the real passage of time, and doesn't generally care about the number of runs
 or tapes between any two events.
-While AMANDA 2.2 doesn't care about spacing between runs, dump cycles are still
+While Amanda 2.2 doesn't care about spacing between runs, dump cycles are still
 in terms of days, to make things easy to understand for the user. So, time
 differences are rounded to the nearest 24 hours:
 days_diff(A,B) = (<B> - <A> + 86400/2) / 86400
@@ -100,7 +100,7 @@ There is a complication for "skip-full" filesystems. Under 2.2, these will be
 skipped on any runs that occur on the day the full is due, but we have to do
 the right thing if multiple runs are done that day, and if no runs are done
 that day (in which case we should be doing an incremental). Also, the time of
-last full dump is a fiction maintained by the planner -- AMANDA has no way to
+last full dump is a fiction maintained by the planner -- Amanda has no way to
 tell whether the full backup was actually done or when it was done:
 
        if(skip-full) {
@@ -144,11 +144,11 @@ handle stale information.
 
 taper must now handle writing to multiple tapes in one night, but choosing the
 tapes from the tape rack is done one at a time as needed, re-applying the same
-algorithm each time (see AMANDA_Tape_Changer_Support).
+algorithm each time (see Amanda_Tape_Changer_Support).
 
  End of tape handling
 
-As in earlier versions of AMANDA, taper itself does not try to restrict writing
+As in earlier versions of Amanda, taper itself does not try to restrict writing
 to the tape size given in the config file. It relied on planner having
 correctly estimated backup sizes and limiting itself to what would fit on one
 tape.
@@ -178,5 +178,5 @@ whether or not the end of tape was reached.
 -------------------------------------------------------------------------------
 
 Prev                            Up                                        Next
-Chapter 30. What once was new  Home  Chapter 32. Thoughts about a Strategy API
+Chapter 31. What once was new  Home  Chapter 33. Thoughts about a Strategy API
 
index 3536e539dcb4dcd31cdb4bf4565895e4601133e8..92cd6ba1e51321172475a1b907c45803b1bf2ee1 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 21. How AMANDA uses UDP and TCP ports
+Chapter 22. How Amanda uses UDP and TCP ports
 Prev  Part V. Technical Background       Next
 
 -------------------------------------------------------------------------------
 
-Chapter 21. How AMANDA uses UDP and TCP ports
+Chapter 22. How Amanda uses UDP and TCP ports
 
 
 John R. Jackson
@@ -36,7 +36,7 @@ Note
 
 Refer to http://www.amanda.org/docs/portusage.html for the current version of
 this document.
-AMANDA uses both UDP and TCP ports during its operation. The amandad service is
+Amanda uses both UDP and TCP ports during its operation. The amandad service is
 listening (via inetd/xinetd) at a well known (fixed) port on each client for
 UDP connections. The amindexd and amidxtaped services are listening (also via
 inetd/xinetd) at well known ports on the tape server for TCP connections.
@@ -51,7 +51,7 @@ A similar sequence of events happens when amrecover on a client wants to
 contact amindexd or amidxtaped on the tape server. The port that amrecover
 binds to its TCP socket must be privileged, which is one of the reasons it must
 be run as root.
-AMANDA also uses TCP connections for transmitting the backup image, messages
+Amanda also uses TCP connections for transmitting the backup image, messages
 and (optionally) the index list from a client back to the dumper process on the
 tape server. A process called sendbackup is started by amandad on the client.
 It creates two (or three, if indexing is enabled) TCP sockets and sends their
@@ -66,7 +66,7 @@ does not check the peer (connecting) port number.
 
  TCP port allocation
 
-When AMANDA creates a TCP server socket to listen for incoming connections
+When Amanda creates a TCP server socket to listen for incoming connections
 ( sendbackup), it goes through the following bind steps:
 
 * try for the user TCP port range (--with-tcpportrange), if defined. If that
@@ -78,8 +78,9 @@ When AMANDA creates a TCP server socket to listen for incoming connections
 
 * get any available port.
 
-This sequence is implemented in stream_server().
-When AMANDA ( dumper) creates an unprivileged TCP client socket to connect to a
+In all cases, it will not use a port that has been assigned to other well-known
+services. This sequence is implemented in stream_server().
+When Amanda ( dumper) creates an unprivileged TCP client socket to connect to a
 server, it goes through the following bind steps:
 
 * try for the user TCP port range (--with-tcpportrange), if defined. If that
@@ -88,8 +89,9 @@ server, it goes through the following bind steps:
 
 * get any available port.
 
-This sequence is implemented in stream_client().
-When AMANDA ( amrecover) creates a privileged TCP client socket to connect to a
+In all cases, it will not use a port that has been assigned to other well-known
+services. This sequence is implemented in stream_client().
+When Amanda ( amrecover) creates a privileged TCP client socket to connect to a
 server, it goes through the following bind step:
 
 * try for a privileged port (512 .. 1023). If that fails, the whole request is
@@ -141,7 +143,7 @@ potential use by making the portrange larger.
 
  UDP port allocation
 
-When AMANDA creates a UDP socket, the same order of assignment as above is used
+When Amanda creates a UDP socket, the same order of assignment as above is used
 by dgram_bind():
 
 * try for the user UDP port range (--with-udpportrange), if defined. If that
@@ -153,11 +155,12 @@ by dgram_bind():
 
 * get any available port.
 
-The dgram_bind() routine is called from three places, amcheck, planner and
-dumper. In each case, a connection to amandad on a client is being set up.
-amandad, in turn, calls security_ok(), which insists the other end of the
-connection be a privileged port, so a user UDP port range (--with-udpportrange)
-must specify privileged port numbers.
+In all cases, it will not use a port that has been assigned to other well-known
+services. The dgram_bind() routine is called from three places, amcheck,
+planner and dumper. In each case, a connection to amandad on a client is being
+set up. amandad, in turn, calls security_ok(), which insists the other end of
+the connection be a privileged port, so a user UDP port range (--with-
+udpportrange) must specify privileged port numbers.
 A user UDP port range must allow for one port for each client that might be
 contacted at a time. planner and amcheck use a single socket to contact all
 their clients, but there may be multiple dumpers (based on "inparallel" in
@@ -175,16 +178,16 @@ I'm not familiar with firewalls or NAT -- one of the benefits of working in a
 University environment :-). So the following is likely to be completely wrong,
 but I have tried to get the advice of folks who do really understand this
 stuff.
-Firewalls and AMANDA should be pretty easy to set up. Just pick user UDP and
-TCP port ranges, build AMANDA with them (--with-udpportrange and --with-
+Firewalls and Amanda should be pretty easy to set up. Just pick user UDP and
+TCP port ranges, build Amanda with them (--with-udpportrange and --with-
 tcpportrange) and let them through the firewall. You also need to let the well
-known AMANDA ports through, just as you would ftp or telnet.
-NAT has other issues. If the AMANDA client is "outside" NAT, there should not
+known Amanda ports through, just as you would ftp or telnet.
+NAT has other issues. If the Amanda client is "outside" NAT, there should not
 be a problem for backups. Sendbackup will set up the ports and tell dumper what
 they are. Then dumper will connect to them from "inside" and NAT should leave
 that alone, although it doesn't really matter since sendbackup does not care
 who connects to it (other than it not be ftp port 20).
-If the AMANDA tape server is outside, NAT will have to be told how to translate
+If the Amanda tape server is outside, NAT will have to be told how to translate
 the incoming connections from dumper to the client. To do that, the UDP and TCP
 port ranges will have to be known and only one client can be inside.
 The reverse is true for amrecover. If amrecover is run from inside NAT, there
@@ -202,5 +205,5 @@ up on the documentation that comes with them.
 -------------------------------------------------------------------------------
 
 Prev                           Up                            Next
-Part V. Technical Background  Home  Chapter 22. AMANDA dumper API
+Part V. Technical Background  Home  Chapter 23. Amanda dumper API
 
index 4d254f3b4a97de2a4d2f2dd4f3543fbe5a143de4..47fe6de5fb598d2ace917546489f0e3528249593 100644 (file)
@@ -9,30 +9,24 @@ Abstract
 
 Note
 
-This is the first release of the Docbook/XML-version of the official AMANDA
-documentation. Please refer to http://www.amanda.org/docs/AMANDA-docs.html for
-the latest versions of these documents. They are available as html, ps and pdf.
-This is an effort to give the AMANDA-documentation a general overhaul. There
-are many parts that need to be reviewed and corrected, updated and added. The
-conversion of the old ASCII-formatted documentation to Docbook/XML should help
-to enhance the possibilities and to ease the generation of various output-
-formats.
-Recent changes:
-
-* addition of the AMANDA-chapter by John R. Jackson (with kind permission of W.
-  Curtis Preston).
-
-Planned:
-
-* addition of some historical AMANDA-papers.
-* addition of some illustrations and charts.
-* addition of more chapters ...
+This is the Docbook/XML-version of the official Amanda documentation. Please
+refer to http://www.amanda.org/docs/AMANDA-docs.html for the latest versions of
+these documents. They are available as html, ps and pdf.
+This is the official documentation for Amanda 2.5.0. The release 2.5.0 brings
+various new features:
+
+* Communication security/authentication
+* Data security
+* Enhanced possibilities for Compression
+* Dump images spanning multiple media volumes
+* Auto tape labelling
+* Improved code quality
 
 Feel free to contact me with corrections, additions or updates. Thank you.
-Stefan G. Weichinger, for the AMANDA Core Team, April 2005.
+Stefan G. Weichinger, for the AMANDA Core Team, March 2006.
 <sgw@amanda.org>
 -------------------------------------------------------------------------------
 
-Prev                                Up   Next
+Prev                                     Next
 The Official AMANDA Documentation  Home      
 
index 652ab4a21ef2282305118abf572d6fcc32254bc0..df0c9cb3b51d5617dae74d6b8bab1ed34472ada6 100644 (file)
@@ -2,12 +2,12 @@
 Prev     Next
 
 -------------------------------------------------------------------------------
-Conversion to Docbook/XML by Stefan G. Weichinger, member of the AMANDA Core
+Conversion to Docbook/XML by Stefan G. Weichinger, member of the Amanda Core
 Team.
 XML-Buildtree by Jelmer R. Vernooij, member of the Samba-Team. Thanks, Jelmer
 ... !
 -------------------------------------------------------------------------------
 
-Prev       Up                    Next
+Prev                             Next
 Abstract  Home  Copyright Information
 
index 6790466343399de74854fcdd9993b65a132e2b35..803e0f904bd4b426c06ddd43d6f86261e7c3c6cb 100644 (file)
@@ -22,6 +22,6 @@ CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION
 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 -------------------------------------------------------------------------------
 
-Prev   Up           Next
+Prev                Next
       Home  Attributions
 
index 4d8e9af87707ba0bbbb6cde555eb0000036ea567..512eef6dd977b34c5ff8e43b51424892bd01869a 100644 (file)
@@ -6,21 +6,21 @@ Prev     Next
 
 Attributions
 
-AMANDA_2.4.x_-_System-Specific_Installation_Notes
+Amanda_2.5.0_-_System-Specific_Installation_Notes
 
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
-AMANDA_Installation_Notes
+Amanda_Installation_Notes
 
 * James da Silva <jds@amanda.org> (Original text)
-* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
+* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion, Updates)
 
 Excluding
 
 * Andrew Hall (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
-Indexing_with_AMANDA
+Indexing_with_Amanda
 
 * Alan M. McIvor (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
@@ -39,7 +39,7 @@ Restore
 * Ralf Fassel (Corrections and additions)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
-AMANDA_Tape_Changer_Support
+Amanda_Tape_Changer_Support
 
 * James da Silva <jds@amanda.org> (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
@@ -58,12 +58,12 @@ Printing_of_Labels
 
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
-AMANDA_on_Cygwin_HOWTO
+Amanda_on_Cygwin_HOWTO
 
 * Doug Kingston (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
 
-How_to_use_the_AMANDA_file-driver
+How_to_use_the_Amanda_file-driver
 
 * Stefan G. Weichinger <sgw@amanda.org> (Original text;XML-conversion;Updates)
 
@@ -74,54 +74,59 @@ AFS_HOWTO
 How_to_use_a_wrapper
 
 * Bert de Ridder (Original text)
+* Paul Bijnens (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion; Updates)
 
-Using_AMANDA
+How_to_do_Amanda-server-side_gpg-encrypted_backups.
+
+* Stefan G. Weichinger <sgw@amanda.org> (Original text)
+
+How_to_use_different_auth_with_Amanda
+
+* Jean-Louis Martineau <martinea@iro.umontreal.ca> (Original text;XML-
+  conversion;Updates)
+
+Using_Amanda
 
 * John R. Jackson <jrj@purdue.edu> (Original text)
 * Gavin Henry <ghenry@suretecsystems.com> (XML-conversion)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion, Updates)
 
-AMANDA_FAQ
+Amanda_FAQ
 
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
-Collection_of_the_top_ten_AMANDA_questions._And_answers.
+Collection_of_the_top_ten_Amanda_questions._And_answers.
 
 * Stefan G. Weichinger <sgw@amanda.org> (Original text; Conversion to Docbook/
   XML)
 
-AMANDA_WISHLIST
+Amanda_WISHLIST
 
 * Jean-Louis Martineau <martinea@iro.umontreal.ca> (Additions and Updates)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion; Additions and Updates)
 
-AMANDA_Survey_Results
-
-* Jon LaBadie <jon@jgcomp.com> (Original text)
-* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
-
-How_AMANDA_uses_UDP_and_TCP_ports
+How_Amanda_uses_UDP_and_TCP_ports
 
 * John R. Jackson <jrj@purdue.edu> (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
-AMANDA_dumper_API
+Amanda_dumper_API
 
 * Alexandre Oliva <oliva@dcc.unicamp.br> (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
-AMANDA_Internals
+Amanda_Internals
 
 * George Scott (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
 
-AMANDA_Event_API
+Amanda_Event_API
 
 * Mike Grupenhoff <kashmir@munge.com> (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
-AMANDA_Security_API
+Amanda_Security_API
 
 * Mike Grupenhoff <kashmir@munge.com> (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
@@ -130,7 +135,7 @@ Virtual_Tape_API
 
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
 
-Using_Kerberos_with_AMANDA
+Using_Kerberos_with_Amanda
 
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
 
@@ -146,7 +151,7 @@ What_once_was_new
 
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion, Updates)
 
-Multitape_support_in_AMANDA_2.2
+Multitape_support_in_Amanda_2.2
 
 * James da Silva <jds@amanda.org> (Original text)
 * Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
@@ -171,6 +176,6 @@ Web_Ressources
 
 -------------------------------------------------------------------------------
 
-Prev                    Up                   Next
+Prev                                         Next
 Copyright Information  Home  Part I. Installation
 
index 7893fd0ee8acae41c7505c332516ecac22e3d9bd..3fc018736dfe4c038ea47351104efcfb0c3dee2d 100644 (file)
@@ -46,12 +46,12 @@ double-tape failure is required to lose data).
 Similarly, a 5-drive RAIT set will give you 4 times the capacity, 4 times the
 throughput (with sufficient bus bandwidth), and the square of the failure rate.
 This means you can back up partitions as large as four times your tape size
-with AMANDA, with higher reliability and speed.
+with Amanda, with higher reliability and speed.
 
  Using a RAIT
 
 If you have several tape devices on your system [currently either 3 or 5 drive
-sets are supported] you tell AMANDA to use them as a RAIT by listing them as a
+sets are supported] you tell Amanda to use them as a RAIT by listing them as a
 single tape device using /bin/csh curly-brace-and-comma notation, as in:
 
        tapedev = "rait:/dev/rmt/tps0d{4,5,6}n"
@@ -87,15 +87,15 @@ and change your tapetype entry to:
        tapetype EXB-8500x3
                
 
-to tell AMANDA about the multiple drive set.
+to tell Amanda about the multiple drive set.
 
  Disaster Recovery
 
-To assist in disaster recovery (as well as changer scripts) the AMANDA package
+To assist in disaster recovery (as well as changer scripts) the Amanda package
 now also includes amdd, which is a simple dd(1) replacement which supports
 (only) the "if=xxx", "of=xxx", "bs=nnn[kMb]" "skip=nnn" and "count=nnn"
 options, but which can read and write RAIT tapesets.
-Using amdd and your usual AMANDA unpack instructions will suffice for disaster
+Using amdd and your usual Amanda unpack instructions will suffice for disaster
 recovery from RAIT tape-sets.
 -------------------------------------------------------------------------------
 
index 65290dd27ad32e56f22044aa6b8d5754c63e3d3d..182ae9f21901e51dfa07ed7c20557295ee1b7239 100644 (file)
@@ -35,8 +35,8 @@ Note
 
 Refer to http://www.amanda.org/docs/restore.html for the current version of
 this document.
-This document describes how to restore files backed up with AMANDA either with
-or without AMANDA tools.
+This document describes how to restore files backed up with Amanda either with
+or without Amanda tools.
 All these cases assume you're trying to restore a complete disk, that is,
 you've replaced the lost disk with a new one, or created a new filesystem on
 it. Tweaking with the arguments to restore (not amrestore), you will be able to
@@ -108,41 +108,41 @@ Barney) runs sunos.
      First of all, boot off the CD, and reinstall the system critical
      partition, restoring it to vendor supplied state. Then, go through all of
      Scenario 1.
-  3. Server machine fails, non-system critical, non-AMANDA disk.
+  3. Server machine fails, non-system critical, non-Amanda disk.
      Proceed just as described in Scenario 1. However, you won't have to go
      through the rsh process, because you can just use amrestore to replace the
      lost data directly.
-  4. Server machine fails, system critical, non-AMANDA disk.
+  4. Server machine fails, system critical, non-Amanda disk.
      Example: / on Aaron
      First of all, boot off the CD, and reinstall the system critical
      partition, restoring it to vendor supplied state.
      Then, follow steps in Scenario 3.
-  5. Server machine fails, non-system critical, AMANDA disk, with db.
+  5. Server machine fails, non-system critical, Amanda disk, with db.
      Example: /opt on Aaron
-     If the disk that contains the AMANDA database is toast, then you need to
+     If the disk that contains the Amanda database is toast, then you need to
      rebuild the database. The easiest way to do it is to take the text file
      that you had mailed to you via the 'amadmin export' command, and import
      via the 'amadmin import' command. Then you should be able to follow the
      steps outlined in Scenario 4.
-     Note that AMANDA does not mail the exported database automatically; you
+     Note that Amanda does not mail the exported database automatically; you
      may add this to the crontab entry that runs amanda.
      Maybe it's a good idea to print out the text files as well and store the
      last 2 dumpcycles worth of paper (the disc text files might have got
      toasted as well). From the paper you still are able to reconstruct where
      your discs are.
-  6. Server machine fails, non-system critical, AMANDA disk, with binaries.
+  6. Server machine fails, non-system critical, Amanda disk, with binaries.
      Example: /usr/local on Aaron
      This is where things get hairy. If the disk with the amanda binaries on it
      is toast, you have three options.
 
-       i. reinstall the AMANDA binaries from another tape, on which you have
+       i. reinstall the Amanda binaries from another tape, on which you have
           conveniently backed up the binaries within the last couple of weeks
-          (not using AMANDA).
-      ii. recompile AMANDA, making sure not to overwrite your db files.
-     iii. use dd to read AMANDA formatted tapes. This is the option I am going
+          (not using Amanda).
+      ii. recompile Amanda, making sure not to overwrite your db files.
+     iii. use dd to read Amanda formatted tapes. This is the option I am going
           to explore most fully, because this seems the most likely to occur.
 
-            a. Find out the device name used by AMANDA, by looking in
+            a. Find out the device name used by Amanda, by looking in
                amanda.conf. Turns out to be /dev/rmt/0cn for this system.
                If amanda.conf isn't at hand: this must be a non-rewinding tape
                device specifier (which I believe the trailing `n' stands for).
@@ -184,12 +184,12 @@ Barney) runs sunos.
 
                Example output:
 
-                 AMANDA: FILE 19971220 uri /root-sun4 lev 1 comp .gz program
+                 Amanda: FILE 19971220 uri /root-sun4 lev 1 comp .gz program
                  DUMP
-                 AMANDA: FILE 19971220 uri /misc lev 1 comp .gz program DUMP
-                 AMANDA: FILE 19971220 uri / lev 1 comp .gz program DUMP
+                 Amanda: FILE 19971220 uri /misc lev 1 comp .gz program DUMP
+                 Amanda: FILE 19971220 uri / lev 1 comp .gz program DUMP
 
-            g. Restore the AMANDA binaries (what else do you need??), and then
+            g. Restore the Amanda binaries (what else do you need??), and then
                bail out of ufsrestore. You can use amrestore, as in Scenario 3.
 
 
index 16957c4fc4e70e169bc08220a83b96649f3df0a8..36046e6844dd7f8b2d474c64f6958fd60d2a4758 100644 (file)
@@ -43,7 +43,7 @@ document.
 
  Installation
 
-AMANDA is able to back up Microsoft Windows shared disks by using Samba, a
+Amanda is able to back up Microsoft Windows shared disks by using Samba, a
 package that implements a SMB client and server for Unix:
 http://www.samba.org
 
@@ -52,17 +52,17 @@ Note
 This is old stuff and will be (re)moved soon:
 Releases from 1.9.18p5 up to 1.9.18p10 logged information in the tar files
 produced, making them unusable! If you really must use a release prior to Samba
-2.0.6, a patch that fixes the problem is available in the AMANDA patches page:
+2.0.6, a patch that fixes the problem is available in the Amanda patches page:
 http://www.amanda.org/patches/
-AMANDA no longer supports Samba releases prior to 1.9.18. If you're using Samba
+Amanda no longer supports Samba releases prior to 1.9.18. If you're using Samba
 from 1.9.18 through 1.9.18p3, make sure you don't set a low logging/debugging
 level in smb.conf. This flag may prevent estimate sizes from printing correctly
-and AMANDA will report an estimate failure.
+and Amanda will report an estimate failure.
 This problem may also occur if you have large (>2GB) shares with Samba prior to
-2.0.4. In this case, apply samba2-largefs.patch from the AMANDA patches page
+2.0.4. In this case, apply samba2-largefs.patch from the Amanda patches page
 (http://www.amanda.org/patches/).
-After building and installing Samba, AMANDA must be configured with support for
-smbclient. AMANDA will automatically find smbclient if it is in your PATH when
+After building and installing Samba, Amanda must be configured with support for
+smbclient. Amanda will automatically find smbclient if it is in your PATH when
 you run configure, or you may add the following argument:
 
   --with-smbclient=/full/path/to/smbclient
@@ -70,13 +70,13 @@ you run configure, or you may add the following argument:
 
  Setup
 
-Once AMANDA and Samba are installed, the only difference between a Unix client/
+Once Amanda and Samba are installed, the only difference between a Unix client/
 disk and PC client/share is in how the backup disks are specified in the file
 disklist. For each PC share, the entry lists the 'samba server' host (where the
 patched Samba software is installed) and the disk field is the share name. The
 remaining fields are like any other DLE.
 A user must be created on the PC with full access rights (read/write) to the
-share. AMANDA, via the Samba server, will connect to the PC via this user. If
+share. Amanda, via the Samba server, will connect to the PC via this user. If
 the user does not have full access, incremental backups will not work and the
 whole share will be backed up every time (the archive bits are never reset).
 The file /etc/amandapass must be created by hand. It contains share name to
@@ -96,13 +96,13 @@ fields, separated by whitespace:
   password.
 * Workgroup (optional).
 
-This file must be owned by the AMANDA-user, and disallow world access
+This file must be owned by the Amanda-user, and disallow world access
 privileges. Blank lines are ignored. A "#" on a line at the start of a field
 (including start of line) causes the rest of the line to be ignored.
 
  Example
 
-The AMANDA client software and (patched) Samba is installed on host "pcserver".
+The Amanda client software and (patched) Samba is installed on host "pcserver".
 A share to be backed up called "backupc" is on PC "thepc". The share will be
 accessed via PC user "bozo" and password "f00bar" and does not require a
 workgroup.
@@ -135,7 +135,7 @@ An example dumptype in amanda.conf would be:
 
 Essentially, the entry in disklist is a 'pseudo-disk' which contains all the
 relevant information needed by smbclient to backup the disk, but in a way that
-is compatible to AMANDA.
+is compatible to Amanda.
 amcheck does a quick check to see if smbclient exists and tries to connect to
 the PC clients. It also checks for the existence and permissions of /etc/
 amandapass.
@@ -144,9 +144,9 @@ amandapass.
 
 Samba will not back up open files (such as PAGEFILE.SYS and registry files) nor
 Access Control List data. Furthermore, at restore time, smbclient is unable to
-overwrite read-only files. Hence, AMANDA+Samba is not a perfect solution for
+overwrite read-only files. Hence, Amanda+Samba is not a perfect solution for
 backing up (restoring, actually) system disks.
-Samba does not use the Windows Backup API, so configuring the AMANDA backup
+Samba does not use the Windows Backup API, so configuring the Amanda backup
 user as a member of group backup on the Windows host is useless. You will
 probably have to configure it as an Administrator, and make sure it can read
 and change permission of all files in the share.
@@ -169,7 +169,7 @@ Also the new option "exclude append" is not yet supported with smbclient.
 Note
 
 Since Samba-3.0.2a smbclient supports multiple exclusion-patterns. It is one of
-the "Ongoing Projects" to make use of this in AMANDA. Refer to http://
+the "Ongoing Projects" to make use of this in Amanda. Refer to http://
 www.amanda.org/ongoing.php for details.
 The size estimate calculation does not use the same method as the dump, so it
 may be inaccurate. It also does not support any type of exclusion ("exclude" is
@@ -184,5 +184,5 @@ filesystems.
 -------------------------------------------------------------------------------
 
 Prev                              Up                 Next
-Chapter 4. Indexing with AMANDA  Home  Chapter 6. Restore
+Chapter 4. Indexing with Amanda  Home  Chapter 6. Restore
 
index cdd5c63d6f6961ca968f5031d9e670e7fc472a81..043d7883190eaaae1ec52b5cefacc1e3548fe464 100644 (file)
@@ -1,10 +1,10 @@
 
-      Chapter 25. AMANDA Security API
+      Chapter 26. Amanda Security API
 Prev  Part V. Technical Background  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 25. AMANDA Security API
+Chapter 26. Amanda Security API
 
 
 Mike Grupenhoff
@@ -90,26 +90,26 @@ of this document.
  Introduction
 
 This is a document of the API for defining and utilizing multiple security and
-transport mechanisms for the AMANDA network protocol.
+transport mechanisms for the Amanda network protocol.
 The goal of this API is to allow several different forms of communication and
-authentication to exist between the AMANDA server and its clients.
+authentication to exist between the Amanda server and its clients.
 
  The Problem
 
 There exist many potential ways that a user might wish to grant access to the
-AMANDA daemon. The two currently supported are BSD (reserved port) and Kerberos
+Amanda daemon. The two currently supported are BSD (reserved port) and Kerberos
 IV security. The current implementation of these two methods is not very
 general, and adding additional methods requires a large amount of code to be
 modified.
 Additionally, the current methods require the protocol and dump transport to be
-transmitted across the network using a pre-defined method. The AMANDA protocol
+transmitted across the network using a pre-defined method. The Amanda protocol
 currently must be sent using udp datagrams to a well-known port, and the dumps
 are transported using tcp connections between ports negotiated via the
 protocol.
 
  The API
 
-The security API was designed to be a layer in between the core logic of AMANDA
+The security API was designed to be a layer in between the core logic of Amanda
 and the transport and authentication of the protocol and dumps.
 The component server and client programs now deal with abstract concepts
 instead of concrete udp and tcp handles.
@@ -136,7 +136,7 @@ Given a security driver, and a hostname, calls back with a security_handle_t
 (section 4.2) that can be used to communicate with that host. The status arg to
 the callback is reflects the success of the request. Error messages can be had
 via security_geterror().
-This is expected to be the AMANDA server's interface for setting up connections
+This is expected to be the Amanda server's interface for setting up connections
 to clients.
 conf_fn is used to determine configuration information. If NULL, no
 configuration information is available.
@@ -149,8 +149,8 @@ Given a security driver, an input file descriptor, and an output file
 descriptor, and a callback, when new connections are detected on the given file
 descriptors, the function is called with a newly created security handle and
 the initial packet received.
-This is expected to be the AMANDA daemon's interface for setting up incoming
-connections from the AMANDA server. The file descriptors are typically 0 and 1
+This is expected to be the Amanda daemon's interface for setting up incoming
+connections from the Amanda server. The file descriptors are typically 0 and 1
 (stdin/stdout).
 This function uses the event interface, and only works properly when event_loop
 () is called later in the program.
@@ -443,5 +443,5 @@ Implementation of security_stream_read_cancel.
 -------------------------------------------------------------------------------
 
 Prev                           Up                           Next
-Chapter 24. AMANDA Event API  Home  Chapter 26. Virtual Tape API
+Chapter 25. Amanda Event API  Home  Chapter 27. Virtual Tape API
 
index fff409496f432eb6aa30d16075bd316bf5835fa2..af06155f066ca45c5c3c5ddfbf231752d534e728 100644 (file)
@@ -1,13 +1,13 @@
 
-Chapter 28. Response to CPIO Security Notice Issue 11:
+Chapter 29. Response to CPIO Security Notice Issue 11:
 Prev  Part VI. Historical files                   Next
 
 -------------------------------------------------------------------------------
 
-Chapter 28. Response to CPIO Security Notice Issue 11:
+Chapter 29. Response to CPIO Security Notice Issue 11:
 
 
-AMANDA Core Team
+Amanda Core Team
 
 Original text
 AMANDA Core Team
@@ -31,8 +31,8 @@ Note
 
 Refer to http://www.amanda.org/docs/security.html for the current version of
 this document.
-The AMANDA development team confirms the existence of the amrecover security
-hole in recent versions of AMANDA. We have made a new release, AMANDA 2.4.0b5,
+The Amanda development team confirms the existence of the amrecover security
+hole in recent versions of Amanda. We have made a new release, Amanda 2.4.0b5,
 that fixes the amrecover problem and other potential security holes, and is the
 product of a security audit conducted in conjunction with the OpenBSD effort.
 The new version is available at:
@@ -42,16 +42,16 @@ information given in the CPIO Security Notice:
 
  Affected Versions
 
-The AMANDA 2.3.0.x interim releases that introduced amrecover, and the 2.4.0
-beta releases by the AMANDA team are vulnerable.
-AMANDA 2.3.0 and earlier UMD releases are not affected by this particular bug,
+The Amanda 2.3.0.x interim releases that introduced amrecover, and the 2.4.0
+beta releases by the Amanda team are vulnerable.
+Amanda 2.3.0 and earlier UMD releases are not affected by this particular bug,
 as amrecover was not part of those releases. However, earlier releases do have
-potential security problems and other bugs, so the AMANDA Team recommends
+potential security problems and other bugs, so the Amanda Team recommends
 upgrading to the new release as soon as practicable.
 
  Workaround
 
-At an active site running AMANDA 2.3.0.x or 2.4.0 beta, amrecover/ amindexd can
+At an active site running Amanda 2.3.0.x or 2.4.0 beta, amrecover/ amindexd can
 be disabled by:
 
 * removing amandaidx and amidxtape from /etc/inetd.conf
@@ -60,7 +60,7 @@ be disabled by:
 * restarting /etc/inetd.conf (kill -HUP should do)
 
 This will avoid this particular vulnerability while continuing to run backups.
-However, other vulnerabilities might exist, so the AMANDA Team recommends
+However, other vulnerabilities might exist, so the Amanda Team recommends
 upgrading to the new release as soon as practicable.
 
  Acknowledgements
@@ -68,12 +68,12 @@ upgrading to the new release as soon as practicable.
 This release (2.4.0) has addressed a number of security concerns with the
 assistance of Theo de Raadt, Ejovi Nuwere and David Sacerdote of the OpenBSD
 project. Thanks guys! Any problems that remain are our own fault, of course.
-The AMANDA Team would also like to thank the many other people who have
-contributed suggestions, patches, and new subsystems for AMANDA. We're grateful
+The Amanda Team would also like to thank the many other people who have
+contributed suggestions, patches, and new subsystems for Amanda. We're grateful
 for any contribution that helps us achieve and sustain critical mass for
-improving AMANDA.
+improving Amanda.
 -------------------------------------------------------------------------------
 
 Prev                        Up                         Next
-Part VI. Historical files  Home  Chapter 29. Upgrade Issues
+Part VI. Historical files  Home  Chapter 30. Upgrade Issues
 
index e2dffb9c943faf6360d96b735c2ea88328f53030..fcea728856dd7f1ece4dc5a2832437d6ef6aef18 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 32. Thoughts about a Strategy API
+Chapter 33. Thoughts about a Strategy API
 Prev  Part VI. Historical files      Next
 
 -------------------------------------------------------------------------------
 
-Chapter 32. Thoughts about a Strategy API
+Chapter 33. Thoughts about a Strategy API
 
 
 Alexandre Oliva
@@ -61,5 +61,5 @@ of this document.
 -------------------------------------------------------------------------------
 
 Prev                                          Up                         Next
-Chapter 31. Multitape support in AMANDA 2.2  Home  Chapter 33. Y2K Compliancy
+Chapter 32. Multitape support in Amanda 2.2  Home  Chapter 34. Y2K Compliancy
 
index bd3f678b50549e8b010a07bc7675ea906be9da7b..9ab55ca8dea4319eb315f0921d0fddda00675a50 100644 (file)
@@ -1,13 +1,13 @@
 
-Chapter 1. AMANDA 2.4.x - System-Specific Installation Notes
+Chapter 1. Amanda 2.5.0 - System-Specific Installation Notes
 Prev  Part I. Installation                              Next
 
 -------------------------------------------------------------------------------
 
-Chapter 1. AMANDA 2.4.x - System-Specific Installation Notes
+Chapter 1. Amanda 2.5.0 - System-Specific Installation Notes
 
 
-AMANDA Core Team
+Amanda Core Team
 
 Original text
 AMANDA Core Team
@@ -22,6 +22,8 @@ Table of Contents
 
   Solaris_2.6
 
+  Solaris
+
   Trusted_Solaris
 
   SunOS_4.x
@@ -64,7 +66,7 @@ this document.
 Please read the notes that correspond to the architectures you are installing
 for. If you find additional gotchas, or anything incorrect in these notes,
 please send your updates to mailto://amanda-hackers@amanda.org after checking
-that they are not known/fixed problems in the AMANDA patches page: http://
+that they are not known/fixed problems in the Amanda patches page: http://
 www.amanda.org/patches/.
 
  Solaris 2.6
@@ -76,6 +78,12 @@ must rebuild gcc if you get this kind of trouble. Note, however, that gcc
 2.7.2.3 does not support Solaris 2.6, you should upgrade to 2.8.0 or higher, or
 egcs.
 
+ Solaris
+
+You may get errors running make: Assure that you use the BSD-version of make,
+usually /usr/ccs/bin/make. Add /usr/ccs/bin to the path before running
+configure.
+
  Trusted Solaris
 
 According to Julian Stevens <julian.stevens@baedsl.co.uk>, the format of inetd
@@ -83,15 +91,14 @@ on Trusted Solaris 1.2 is a bit different. Just before the user name, you
 should insert the word `untrusted':
 
   amanda dgram udp wait untrusted amuser /usr/local/libexec/amandad amandad
-       
 
 The patch-system script is *NOT* aware of this detail; you must fix it
 yourself.
 
  SunOS 4.x
 
-A bug in GNUtar 1.12 causes it to miscalculate (in fact, to misreport) the size
-of filesystems. A patch for GNUtar is available in the patches directory.
+A bug in GNU-tar 1.12 causes it to miscalculate (in fact, to misreport) the
+size of filesystems. A patch for GNU-tar is available in the patches directory.
 
  Ultrix
 
@@ -104,8 +111,8 @@ enabled by default. If you find rundump is not necessary for you, just run
 
 The Ultrix restore program will fail if it is not connected to a tty. Since the
 restore program is invoked in the clients in order to create index files, and
-it the client is not connected to a tty, index creation will fail. Using GNUTAR
-instead of DUMP is an option. Thanks to Edwin Wiles
+it the client is not connected to a tty, index creation will fail. Using GNU-
+tar instead of DUMP is an option. Thanks to Edwin Wiles
 <ewiles@mclean.sterling.com> for the investigation. Another alternative
 proposed by Martyn Johnson <Martyn.Johnson@cl.cam.ac.uk> is to use a modified
 restore program: use a binary program editor and replace `/dev/tty' with `/dev/
@@ -116,9 +123,8 @@ preserve a copy of the original restore program, it will be rewritten by
 running this script!):
 
   perl -pi -e 'BEGIN { $/ = "/dev/tty" } s-$/-/dev/nul-' restore
-       
 
-The Ultrix C compiler seems to be too broken to compile AMANDA. You are likely
+The Ultrix C compiler seems to be too broken to compile Amanda. You are likely
 to need gcc or egcs.
 
  HP/UX
@@ -127,7 +133,6 @@ You may run into an internal /bin/sh limit when running the configure script.
 The error message is:
 
   ./configure: sh internal 2K buffer overflow
-       
 
 Using /bin/posix/sh usually works around the problem. Another solution is to
 install GNU bash and use it instead of /bin/sh.
@@ -140,12 +145,12 @@ stock mt. The work-around is to install GNU cpio, that contains an
 implementation of mt, and edit amverify so that MT points to GNU mt and MTOPT
 is `-f', or reconfigure and rebuild amanda from scratch, making sure it finds
 GNU mt before the stock mt in the PATH.
-If you have vxfs filesystems to back up, AMANDA will pick vxdump automatically.
-GNU tar 1.12 will incorrectly report the size of backups. There's a patch in
+If you have vxfs filesystems to back up, Amanda will pick vxdump automatically.
+GNU-tar 1.12 will incorrectly report the size of backups. There's a patch in
 the patches directory that fixes this problem.
 The use of `amhpfixdevs' is deprecated, since you can list mount-points or full
 device names in the disklist. The script may be removed in future releases of
-AMANDA.
+Amanda.
 Sometimes you may get the error message `Link severed' from an HP/UX client.
 This is just a cute name the developers of HP/UX found for `Network error'.
 Reported by Michael Brehl <mbr@condor.de>
@@ -159,14 +164,14 @@ Note, however, that DUMP for Linux has been quite unreliable, sometimes being
 unable to perform backups, producing weird error messages such as `master/slave
 protocol botched', and sometimes creating unrestorable dump images, especially
 of active filesystems. The first problem can sometimes be fixed by cleaning up
-outdated entries in /etc/dumpdates, but your best bet is probably GNU tar.
+outdated entries in /etc/dumpdates, but your best bet is probably GNU-tar.
 Make sure the user that runs configure has permission to run the dump program,
 otherwise configure may misdetect an ability of dump to accept a -E (for
 estimates) switch.
-GNUtar 1.11.8, distributed with some Linux versions, will cause index failures
-(Index returned -1). Upgrading to GNUtar 1.12 fixes this problem. This is not a
-Linux-specific problem, but it is quite common in this platform.
-AMANDA now supports the ftape driver version 3.04d. It adjusts the blocksize
+GNU-tar 1.11.8, distributed with some Linux versions, will cause index failures
+(Index returned -1). Upgrading to GNU-tar 1.12 fixes this problem. This is not
+Linux-specific problem, but it is quite common in this platform.
+Amanda now supports the ftape driver version 3.04d. It adjusts the blocksize
 automatically to 32k and supports QIC volume tables. More details con be found
 in the file ZFTAPE in this directory.
 Some releases of dump for Linux, such as the one distributed with Debian 2.0,
@@ -179,26 +184,26 @@ case, you should create a link to it in /etc. Suggested by David Wolfskill
 According to Michael Galloway <mgx@spruce.lsd.ornl.gov>, the stock DUX4 dump is
 broken. There is a patch available at ftp://ftp.service.digital.com/public/
 dunix/v4.0b/duv40bas00005-19970926.README
-When both dump and vdump are available, AMANDA will use vdump for backing up
+When both dump and vdump are available, Amanda will use vdump for backing up
 advfs filesystems only, and dump will be used for the rest. If you'd rather
 back up all filesystems with vdump, #undef DUMP in config/config.h after
 running configure.
 Unfortunately, the output of `dump -E' incorrectly matches a line of output
-from SAMBA, which gets AMANDA's estimate process confused. client-src/
+from SAMBA, which gets Amanda's estimate process confused. client-src/
 sendsize.c will refuse to compile if both HAVE_DUMP_ESTIMATE and SAMBA_CLIENT
-are defined in config/config.h. AMANDA will work correctly if you undefine
+are defined in config/config.h. Amanda will work correctly if you undefine
 HAVE_DUMP_ESTIMATE in config/config.h; if you prefer to have incorrect
 estimates for SAMBA backups, follow the instructions in client-src/sendsize.c
 on removing the compile-time error.
 According to Oren Laadan <orenl@cs.huji.ac.il>, DEC compiler version "DEC C
 V5.2-033 on Digital UNIX V4.0 (Rev. 564)" (obtained with "cc -V") does not
-build AMANDA properly, in particular, taper.c. Using gcc is OK.
+build Amanda properly, in particular, taper.c. Using gcc is OK.
 
  Sinix 5.43 (Reliant Unix)
 
 The use of `amsinixfixdevs' is deprecated, since you can list mount-points or
 full device names in the disklist. The script may be removed in future releases
-of AMANDA.
+of Amanda.
 Sinix port originally by Michael Schmitz <mschmitz@iname.com>.
 
  IRIX (all)
@@ -206,14 +211,13 @@ Sinix port originally by Michael Schmitz <mschmitz@iname.com>.
 When setting the tape device name in either amanda.conf or one of the changer
 configuration files, make sure you specify the "variable" device name, which
 has a 'v' on the end. If not, IRIX will write 4KByte blocks instead of the
-32KByte blocks AMANDA tells it to. This apparantly works OK unless you take the
+32KByte blocks Amanda tells it to. This apparantly works OK unless you take the
 tape to a non-IRIX system, where amrestore will complain about a short (4096)
 read.
 If you do end up in this situation, the dd command to use to pipe into your
 system restore program is:
 
   dd if=/dev/whatever bs=4k skip=8 | ...
-       
 
 Jean-Francois Malouin <Jean-Francois.Malouin@bic.mni.mcgill.ca> reports that,
 if you are going to use an IRIX host as the tape server, you *must* patch your
@@ -230,13 +234,13 @@ always performed twice. According to Mike Acar <mike@kentinfoworks.com>, patch
 Seems like SGI make program is a bit broken, in a way that causes it to rebuild
 some files if doesn't have to if you happen to run make again. Using GNU make
 fixes this problem.
-If you have xfs filesystems to back up, AMANDA will pick xfsdump automatically.
+If you have xfs filesystems to back up, Amanda will pick xfsdump automatically.
 
  IRIX 6.5.x
 
 Luc Lalonde <Luc.Lalonde@polymtl.ca> contributed the following notes:
 If you use a jukebox, you must set the ownership of the robot-changer device to
-the AMANDA operator:group in /etc/ioperms. Here's my configuration:
+the Amanda operator:group in /etc/ioperms. Here's my configuration:
 
   /etc/ioperms: /dev/scsi/sc8d6l0 0600 amanda backup
 
@@ -244,14 +248,14 @@ Otherwise the ownership:group is changed to "root:sys" after each reboot. When
 you do upgrades, check the file /var/sysgen/master.d/scsi to see if it has
 changed. Otherwise your jukebox could be rendered unuseable. In particular,
 check if it has been replaced by a new version and renamed to "./scsi.O/.".
-If you use the AMANDA package provided by freeware.sgi.com, you are not
-affected by the first question since at compile time the AMANDA operator is
+If you use the Amanda package provided by freeware.sgi.com, you are not
+affected by the first question since at compile time the Amanda operator is
 "root:sys".
 
  SCO
 
-Jens Krause <jens@transcom.de> has reported some problems with GNUtar 1.12 on
-SCO Release 5. Although the `sparse' files patch was applied, GNU tar would
+Jens Krause <jens@transcom.de> has reported some problems with GNU-tar 1.12 on
+SCO Release 5. Although the `sparse' files patch was applied, GNU-tar would
 consistently crash. GNUtar had to be built linked with malloc-libraries, and
 the `--sparse' switches had to be removed from client-src/sendbackup-gnutar.c
 and client-src/sendsize.c.
@@ -265,13 +269,13 @@ instead.
  FreeBSD 4.9
 
 Sep. 28th, 2004: Jason Miller <jwm@interlinc.net> reported problems with
-setting up the AMANDA-client on FreeBSD 4.9. He wrote:
-Due to the need for read permissions for AMANDA-client the default user and
+setting up the Amanda-client on FreeBSD 4.9. He wrote:
+Due to the need for read permissions for Amanda-client the default user and
 group for this on FreeBSD 4.9 is "operator:operator" which I found a write up
 on that as well. Just a note the port wanted to install it with these user
 permissions by default and I initially changed them to match my Redhat 9.0
 install. So just doing a
-make distclean uninstall install AMANDA_SERVER=servername
+make distclean uninstall install Amanda_SERVER=servername
 fixed that for me. Then I just followed the below instructions and everything
 was good to go.
 Refer to this link for more details: http://www.freebsd.org/cgi/query-
@@ -290,18 +294,17 @@ but this won't last until the next reboot.
 To make it permanent, just add this line:
 
   net.inet.udp.maxdgram=65535
-       
 
 in the file /etc/sysctl.conf.
 
  AIX
 
 sendsize is reported to coredump on AIX 4.3.3, this is a linking problem, try
-configuring AMANDA with the option "--disable-shared".
+configuring Amanda with the option "--disable-shared".
 
  Microsoft Windows
 
-Although AMANDA won't run standalone on MS-Windows hosts, it is possible to use
+Although Amanda won't run standalone on MS-Windows hosts, it is possible to use
 it to back up their disks, by using SAMBA. Please read Backup_PC_hosts_using
 Samba for more information.
 SAMBA may be unable to back up some files due to file locking restrictions.
@@ -314,12 +317,12 @@ separately. Thanks to Ernie Oporto <ernie_oporto@mentorg.com> for the tip.
 
  Mac OS X
 
-For notes on how to setup AMANDA under Apple's OS X, please refer to http://
+For notes on how to setup Amanda under Apple's OS X, please refer to http://
 web.brandeis.edu/pages/view/Bio/AmandaMacOSXCompileNotes, written by Steven
 Karel<karel@brandeis.edu>. Thanks to Jose L.Hales-Garcia <jose@stat.ucla.edu>
 for the tip.
 -------------------------------------------------------------------------------
 
 Prev                   Up                                   Next
-Part I. Installation  Home  Chapter 2. AMANDA Installation Notes
+Part I. Installation  Home  Chapter 2. Amanda Installation Notes
 
index b4fb9b179102c1f510fbffbdc5311241ecaff63f..266a14766f308169bb2d307682c39348cfd40082 100644 (file)
@@ -1,10 +1,10 @@
 
-     Chapter 8. AMANDA Tape Changer Support
+     Chapter 8. Amanda Tape Changer Support
 Prev  Part II. About Tapes and Changers  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 8. AMANDA Tape Changer Support
+Chapter 8. Amanda Tape Changer Support
 
 
 James da Silva
@@ -74,16 +74,16 @@ of this document.
 
  Introduction
 
-This document outlines the tape changer support design of AMANDA 2.2 and
+This document outlines the tape changer support design of Amanda 2.2 and
 beyond. It defines a small interface for changer software to follow so that
-AMANDA can remain device-independent but still support the widest range of tape
+Amanda can remain device-independent but still support the widest range of tape
 software and hardware possible.
 The interface is a bit simplistic and has only had complications added when
 there is a body of field experience.
 
  Specifying a tape changer in amanda.conf
 
-All device-specifics are hidden by a glue program that the rest of AMANDA calls
+All device-specifics are hidden by a glue program that the rest of Amanda calls
 to interact with the tape changer.
 The name of this changer program is given by the "tpchanger" variable in the
 file amanda.conf. Example entry:
@@ -95,9 +95,9 @@ The tapedev parameter is ignored if a tpchanger program is specified, unless
 the changer program itself reads tapedev from amanda.conf. The chg-multi
 changer doesn't, as it reads all its configuration arguments from its own
 configuration file, specified as changerfile.
-If the tpchanger program does not begin with a '/', AMANDA expects it to reside
+If the tpchanger program does not begin with a '/', Amanda expects it to reside
 in libexecdir, and possibly have the version suffix appended depending on how
-AMANDA was configured.
+Amanda was configured.
 Two other amanda.conf parameters are available for changer use, however their
 definition is left entirely up to the changer script itself. They are
 changerfile and changerdev. Typically changerfile will point to the
@@ -147,7 +147,7 @@ Flag indicating whether the changer can go backwards
 (0 if it can't, 1 if it can). (required)
 Flag indicating whether the changer is searchable
 (optional). Shows whether the changer supports the -search and -label commands
-and is able to load a tape given only the AMANDA label string (0 or omitted if
+and is able to load a tape given only the Amanda label string (0 or omitted if
 it can't, 1 if it can). (optional)
 Examples:
 
@@ -196,7 +196,7 @@ The tape changer program MAY support the following commands:
 
 * <tpchanger> -search <labelstr>
 
-Loads an AMANDA tape by name (labelstr).
+Loads an Amanda tape by name (labelstr).
 Output and error handling are the same as the -slot command.
 taper, amcheck and amtape will use this command if the changer reports it is
 searchable.
@@ -205,7 +205,7 @@ Example:
                % chg-zd-mtx -search DailySet005
                5 /dev/nrst8                    # exitcode returned is 0
 
--<tpchanger> -label <labelstr> Associates the AMANDA label <labelstr> with the
+-<tpchanger> -label <labelstr> Associates the Amanda label <labelstr> with the
 barcode of the currently loaded (in the tape drive) tape.
 Outputs to stdout the current slot and tape device. amlabel will use this
 command if your changer is searchable to build up the barcode database.
@@ -216,15 +216,15 @@ Example:
 
 For all the commands:
 An exit code of 0 implies that the operation was completely successful, and the
-output may be parsed by the AMANDA code as described above.
+output may be parsed by the Amanda code as described above.
 For non-zero exit codes, the first field is still the slot name, but the actual
 error messages are not fixed. They are just displayed and/or logged as-is by
-the calling AMANDA program.
+the calling Amanda program.
 An exit code of 1 implies the operation failed in a benign way, for example an
 empty slot or an attempt to go backwards in a gravity stacker. The calling
-AMANDA program will print the error message if appropriate and continue,
+Amanda program will print the error message if appropriate and continue,
 perhaps requesting a different slot be loaded.
-Any other exit code is considered fatal and will cause AMANDA to stop
+Any other exit code is considered fatal and will cause Amanda to stop
 attempting to talk to the tape changer.
 
  Slot names and the "current" slot
@@ -233,14 +233,14 @@ Some tape changers, such as carousels and gravity stackers, have a hardware
 notion of current position. Others have no current position when no tape is
 loaded: all tapes are in their slots and the changer arm is docked away from
 the slots.
-Nevertheless, AMANDA requires tape-changer scripts to maintain the notion of a
+Nevertheless, Amanda requires tape-changer scripts to maintain the notion of a
 "current" position. This is for performance reasons: as tapes tend to be loaded
-into the rack in order, and AMANDA uses them in order, the next tape to use can
+into the rack in order, and Amanda uses them in order, the next tape to use can
 be found much quicker if the position of the current one is remembered. As an
 example, the chg-multi script maintains the current position in a chg-
 multi.state file (or any other file specified in a `statefile' line in the
 changer configuration file).
-AMANDA does not care how slots are available or how they are named. They could
+Amanda does not care how slots are available or how they are named. They could
 be numbered 0 to N-1, numbered 1 to N, or even designated by letter, A .. Z.
 The only requirement is that the names do not contain whitespace and that the
 names "current", "next", "prev", "first", "last" and "advance" retain their
@@ -259,7 +259,7 @@ issuing successive "slot next" positioning commands.
 
  Operator interface
 
-The amtape program is the main operator interface to AMANDA's tape changer
+The amtape program is the main operator interface to Amanda's tape changer
 support. The commands supported include:
 amtape <conf> slot <slot-specifier> Load the tape from the specified slot into
 the drive
@@ -295,7 +295,7 @@ find the right tape, then run amrestore giving the resulting tape device name.
 
  How amdump interacts with the tape changer
 
-AMANDA does not require a particular tape label for a run. Any label that
+Amanda does not require a particular tape label for a run. Any label that
 matches the labelstr regex and is determined to be "inactive" according to the
 tapelist database, may be written to. However, there is a preferred 'next'
 tape, the one that is next in the cycle implied by the current tapelist.
@@ -310,7 +310,7 @@ it is not found, the first tape encountered that matches the labelstr and is
 not active is picked.
 Gravity stackers (anything that can not go backwards):
 To avoid going all the way to the bottom of the stacker only to find that the
-preferred tape isn't present and nothing can be done, AMANDA picks the first
+preferred tape isn't present and nothing can be done, Amanda picks the first
 tape (starting at the current position) that matches the labelstr and is not
 active, regardless of whether it is the preferred tape.
 
@@ -323,7 +323,7 @@ This tape changer script supports several common configurations:
 
 * Using multiple tape drives in a single host to emulate a tape changer. This
   can also be used with a single physical drive to write several tapes in an
-  AMANDA run.
+  Amanda run.
 
 
 * Using a gravity stacker or a real changer configured to sequentially load the
@@ -390,11 +390,11 @@ changerfile points to a real configuration file, not only a counting file. In
 this configuration file you may specify that the tapedrive needs an eject
 command and an optional waittime, necessary after inserting the tape into the
 drive. You are also able to configure a range of slots which should be used by
-your configuration. The idea behind this is, that you don't want AMANDA to
-cycle all the tapes if AMANDA searches exactly one tape. If you have a library
+your configuration. The idea behind this is, that you don't want Amanda to
+cycle all the tapes if Amanda searches exactly one tape. If you have a library
 which supports more than one drive you can also specify which drive to use. For
 each configuration (there should be at least one) you have to specify a file,
-where AMANDA remembers which tape is actually in the drive. For future use
+where Amanda remembers which tape is actually in the drive. For future use
 there is also some stuff for cleaning the drives.
 In amanda.conf:
 
@@ -469,7 +469,7 @@ If this option is given on every eject/move the log pages of the tape device
 will be dumped in this file. There are 2 log pages were you can see how many
 read/write errors (corrected) are processed by the tape
 labelfile <filename>
-This file is used for the mapping from barcode labels to AMANDA volume labels.
+This file is used for the mapping from barcode labels to Amanda volume labels.
 It is used if the changer has a barcode reader. To initialize run amtape show,
 this will add the mapping for the tapes in the magazine.
 eject > 1
@@ -585,11 +585,11 @@ the SCSI bus. It expects `tapedev' to specify the tape device to be used.
 chg-juke
 
 A shell script that uses the Fermilab "juke" software (see http://www.fnal.gov/
-fermitools/, the "juke" link) to control tape chagners. It supports mounting
+fermitools, the "juke" link) to control tape chagners. It supports mounting
 multiple tapes for RAIT tapedrive sets, both multiple jukeboxes, or one jukebox
 with multiple tape drives, or combinations. 'juke' must be configured to know
-tape drives by the same name AMANDA calls them. It uses 'changerfile' to track
-AMANDA's current tape state, 'tapedev' must be the tape drive (or RAIT set)
+tape drives by the same name Amanda calls them. It uses 'changerfile' to track
+Amanda's current tape state, 'tapedev' must be the tape drive (or RAIT set)
 name, and 'changerdev' is the juke software's name for the changer, or a csh-
 glob that expands to several jukebox names (i.e. "changer{a,b,c}").
 
@@ -636,7 +636,7 @@ The directory tree should be:
 
 Where "slot_root_dir" is the tapedev "file:xxx" parameter and "n" the tapecycle
 parameter.
-Please refer to How_to_use_the_AMANDA_file-driver for details of usage.
+Please refer to How_to_use_the_Amanda_file-driver for details of usage.
 
 chg-iomega
 
@@ -661,7 +661,7 @@ via crontab. Make sure you comply with any of the following. - Add statements
 to your amanda.conf. - Add entry to /etc/fstab to specify mount point of
 removable disk and make this disk mountable by any user. - Format all disks,
 add a "data" sub directory and label all disks by using amlabel. - Be aware
-that as of version 2.4.4p1, AMANDA can't handle backups that are larger than
+that as of version 2.4.4p1, Amanda can't handle backups that are larger than
 the size of the removable disk media. So make sure /etc/amanda/<backup_set>/
 disklist specifies chunks smaller than the disk size.
 
index 8e8dd6bc33cb07af41b0de886add987eb0e04c9f..a7addeb285c05a53b9e5786338fb02f2b04af486 100644 (file)
@@ -5,13 +5,13 @@ Prev                         Next
 -------------------------------------------------------------------------------
 
 
-About Tapes and Changers
+Part II. About Tapes and Changers
 
 
 
 Tape-Drives and Tape-Changers
 
-AMANDA is able to use a wide range of Tape-Drives and Tape-Changers. This
+Amanda is able to use a wide range of Tape-Drives and Tape-Changers. This
 section contains information on the concept of the tapetypes as well as
 information on how to make use of your tape-changer by using the appropriate
 changer-scripts.
@@ -20,7 +20,7 @@ Table of Contents
 
   7._Tapetypes
 
-  8._AMANDA_Tape_Changer_Support
+  8._Amanda_Tape_Changer_Support
 
 
         Introduction
@@ -76,7 +76,7 @@ Table of Contents
 
         Notes_about_changer.conf
 
-        AMANDA's_actual_usage_of_chg-scsi
+        Amanda's_actual_usage_of_chg-scsi
 
         Configuration_notes
 
@@ -107,6 +107,6 @@ Table of Contents
 
 -------------------------------------------------------------------------------
 
-Prev                 Up                   Next
+Prev                                      Next
 Chapter 6. Restore  Home  Chapter 7. Tapetypes
 
index 8f2e4ae15099a6ef3c944b91eb0dcb9668026d3e..f1e98c0c961a14682c90cb61c5abc48228c2e7d0 100644 (file)
@@ -11,12 +11,15 @@ Note
 
 Refer to http://www.amanda.org/docs/tapetypes.html for the current version of
 this document.
-Several tapetype definitions are available in example/amanda.conf They inform
-AMANDA how much it is supposed to be able to store in a tape (length), how much
-space is wasted at the end of a dump image with the EOF mark (filemark) and how
-fast the tape unit is (speed).
-The most inportant parameter is length, since AMANDA may decide to delay a
-backup if length is too small, but, if it is too large, AMANDA may end up
+You may find tapetype-definitions in the example amanda.conf, in the
+mailinglist-archives of the amanda-users-mailinglist at http://
+marc.theaimsgroup.com/?l=amanda-users or in the Amanda-FAQ-O-Matic at http://
+www.amanda.org/fom-serve/cache/1.html. They inform Amanda how much it is
+supposed to be able to store in a tape (length), how much space is wasted at
+the end of a dump image with the EOF mark (filemark) and how fast the tape unit
+is (speed).
+The most inportant parameter is length, since Amanda may decide to delay a
+backup if length is too small, but, if it is too large, Amanda may end up
 leaving dumps in the holding disk or having to abort some dump.
 Filemark is important if you have many disks, particularly with small
 incremental backups. The space wasted by so many filemarks may add up and
@@ -25,7 +28,7 @@ The speed is currently unused.
 If none of the sample tapetype entries match your needs, you may search the
 mailing list archives or look up the on-line list of tapetype entries. Just
 follow the links from http://www.amanda.org.
-AMANDA provides the amtapetype utility to calculate the size of a tape, to
+Amanda provides the amtapetype utility to calculate the size of a tape, to
 generate a "tapetype" entry for your amanda.conf.
 Specifying the appropriate tape device, but beware that it may take many hours
 to run (it fills the tape twice ...). Make sure you do not use hardware
@@ -44,5 +47,5 @@ tape.
 -------------------------------------------------------------------------------
 
 Prev                                Up                                     Next
-Part II. About Tapes and Changers  Home  Chapter 8. AMANDA Tape Changer Support
+Part II. About Tapes and Changers  Home  Chapter 8. Amanda Tape Changer Support
 
index 402a92525fea5480f29bce7585ef79911d9e69d2..c9aeea1fd81865ccf9edac42a03aaf4d5c1ac8e0 100644 (file)
@@ -5,19 +5,19 @@ Prev                    Next
 -------------------------------------------------------------------------------
 
 
-Technical Background
+Part V. Technical Background
 
 
 
-How AMANDA really works ...
+How Amanda really works ...
 
 This section contains some papers which describe the technical concepts behind
-AMANDA. You find descriptions of the various APIs as well as a basic draft of
-the internals of AMANDA.
+Amanda. You find descriptions of the various APIs as well as a basic draft of
+the internals of Amanda.
 Table of Contents
 
 
-  21._How_AMANDA_uses_UDP_and_TCP_ports
+  22._How_Amanda_uses_UDP_and_TCP_ports
 
 
         TCP_port_allocation
@@ -31,7 +31,7 @@ Table of Contents
         Firewalls_and_NAT
 
 
-  22._AMANDA_dumper_API
+  23._Amanda_dumper_API
 
 
         Introduction
@@ -59,7 +59,7 @@ Table of Contents
         Conclusion
 
 
-  23._AMANDA_Internals
+  24._Amanda_Internals
 
 
         Protocols
@@ -73,7 +73,7 @@ Table of Contents
         taper(read)_and_taper(write)
 
 
-  24._AMANDA_Event_API
+  25._Amanda_Event_API
 
 
         Introduction
@@ -87,6 +87,8 @@ Table of Contents
 
               event_loop
 
+              event_wait
+
               event_wakeup
 
 
@@ -117,7 +119,7 @@ Table of Contents
 
 
 
-  25._AMANDA_Security_API
+  26._Amanda_Security_API
 
 
         Introduction
@@ -181,12 +183,12 @@ Table of Contents
 
 
 
-  26._Virtual_Tape_API
+  27._Virtual_Tape_API
 
-  27._Using_Kerberos_with_AMANDA
+  28._Using_Kerberos_with_Amanda
 
 
-        AMANDA_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
+        Amanda_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
 
 
               Configuration
@@ -196,7 +198,7 @@ Table of Contents
               conf_file
 
 
-        AMANDA_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
+        Amanda_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
 
 
               Building
@@ -211,7 +213,7 @@ Table of Contents
 
 -------------------------------------------------------------------------------
 
-Prev                                Up                                  Next
-Chapter 20. AMANDA Survey Results  Home  Chapter 21. How AMANDA uses UDP and
-                                                                   TCP ports
+Prev                                                                  Next
+Chapter 21. Amanda WISHLIST  Home  Chapter 22. How Amanda uses UDP and TCP
+                                                                     ports
 
index 7b8b9314cb440ffc63f27ab18f7b2e43a9d1d106..7cf1e0a17b3315520adb31f697f40097f1c17e22 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 18. Collection of the top ten AMANDA questions. And answers.
+Chapter 20. Collection of the top ten Amanda questions. And answers.
 Prev  Part IV. Various Information                              Next
 
 -------------------------------------------------------------------------------
 
-Chapter 18. Collection of the top ten AMANDA questions. And answers.
+Chapter 20. Collection of the top ten Amanda questions. And answers.
 
 
 Stefan G. Weichinger
@@ -50,9 +50,9 @@ document.
  Reason for starting this list.
 
 Jon LaBadie once wrote to me:
-" I think a good "what is AMANDA", "how is it different", "can I use it in my
+" I think a good "what is Amanda", "how is it different", "can I use it in my
 setup", "why is it so different" kinda document is needed to stop the constant
-"how do I put 10 dumps on one tape", or "how do I make AMANDA do full backups
+"how do I put 10 dumps on one tape", or "how do I make Amanda do full backups
 on saturday and incrementals ..." queries off the list :)) "
 Stefan G. Weichinger
 
@@ -67,7 +67,7 @@ confused by the use of the abbreviation DLE.
 It has become very common for regular mailinglist-participants to use the
 abbreviation DLE, which means in its long form
 DiskList Entry
-A DLE refers to one entry in the disklist of an AMANDA-configuration. General
+A DLE refers to one entry in the disklist of an Amanda-configuration. General
 usage was to describe them as partitions, or file systems. But in fact they do
 not have to be either. They can be directory trees, or multiple trees, or trees
 with some branches cut off. So the more generic term DLE was coined.
@@ -85,7 +85,7 @@ and ask "Why?"
 SHORT ANSWER:
 DO NOT USE "localhost" as host entry in your disklist entries (aka DLEs). Use
 the FQDN (Fully Qualified Domain Name) instead.
-In AMANDA-releases newer than 2004-03-22 there is a WARNING issued when you use
+In Amanda-releases newer than 2004-03-22 there is a WARNING issued when you use
 something like "localhost" or localhost.localdomain.net in your disklist.
 Example (applies to Linux, syntax may be different on other systems):
 
@@ -111,12 +111,12 @@ then give some typical goofs:
 The first thing to understand is how to read this message. When it says "access
 as amanda ..." it is telling you the client side ( amandad) is running as user
 "amanda". The "... from amanda@some.amanda.server" part tells you the server
-trying to connect is "some.amanda.server" and the AMANDA command (e.g. amcheck
+trying to connect is "some.amanda.server" and the Amanda command (e.g. amcheck
 or amdump) is running as user "amanda".
 The user names are typically the same on both client and server, but some
 situations use different names and it is important to understand which is
 which. For instance, amrecover connects as root ("... from
-root@some.amanda.server") regardless of what the usual AMANDA user is.
+root@some.amanda.server") regardless of what the usual Amanda user is.
 Potential problems:
 
 * "some.server" is not spelled exactly that way in ~amanda/.amandahosts. A
@@ -127,13 +127,13 @@ Potential problems:
   some amanda
 
 does not match "some.amanda.server" even though both names may be equivalent.
-When AMANDA looks up the host name in .amandahosts, it uses the exact name it
+When Amanda looks up the host name in .amandahosts, it uses the exact name it
 lists in the message. It does not try to look up abbreviations.
 The only exception to this is that the lookup is case insensitive.
 
 * The user name listed in ~amanda/.amandahosts is not the one trying to connect
   from the server. In particular, watch out for the "root" case listed above
-  for amrecover. The AMANDA server typically needs lines like this in its
+  for amrecover. The Amanda server typically needs lines like this in its
   .amandahosts file:
 
 
@@ -158,7 +158,7 @@ same machine), the server will look for the matching DLE's using the real host
 name, not "localhost". The sethost command inside amrecover can "fix" this, but
 why not just set it up right in the first place?
 Another reason to not use "localhost" is because it helps with future changes.
-As the AMANDA configuration grows, it's not at all unusual to take a server and
+As the Amanda configuration grows, it's not at all unusual to take a server and
 make it a client of a new, larger, server. But now "localhost" does not point
 to the same machine it used to. If the FQDN of the machine had been used all
 along, this upgrade would have been much easier.
@@ -169,23 +169,23 @@ when they didn't :-).
 
  the friday-tape-question
 
-"How do I make AMANDA do full backups on Saturday and incrementals ... ?"
+"How do I make Amanda do full backups on Saturday and incrementals ... ?"
 "My backup screwed up on tuesday and now it keeps asking for the tuesday tape
 even though it is wednesday!"
 ANSWER:
 The short answer is: You can't.
 The longer answer is: You can. But you should not.
-The reason: AMANDA is designed to schedule your backups. Let "her" do it.
-When you want to make the best use of AMANDA, you have to let go the classic
+The reason: Amanda is designed to schedule your backups. Let "her" do it.
+When you want to make the best use of Amanda, you have to let go the classic
 schedule where one used to have one tape dedicated to each day of the week, and
 one for the friday.
 The main difference in concept is this:
 In the classic backup scheme you said:
 "I want to have incremental backups from Mo-Th and a full backup on Fr."
-Using AMANDA you say:
+Using Amanda you say:
 "I want to have at least one full backup in 5 days."
 So you don't have to specify exactly WHEN the full backup should happen. You
-just tell AMANDA some goals it should reach and let it work out the details.
+just tell Amanda some goals it should reach and let it work out the details.
 There are several advantages in this:
 Imagine that you have your classic backup-schedule running fine. Everything is
 calculated and designed well, so your tape gets filled well each night.
@@ -194,16 +194,16 @@ duplicates one big data-directory by mistake.
 So the size of the directory raises within one day, maybe for multiple GBs.
 Would your classic backup-scheme catch that? Or would it run out of tape,
 simply because it was not calculated to have that filesystem with that size?
-AMANDA would try to catch it (and most of the time succeed ...).
-As there is the estimate-phase before actually dumping something, AMANDA can
+Amanda would try to catch it (and most of the time succeed ...).
+As there is the estimate-phase before actually dumping something, Amanda can
 look at the DLEs and determine the actual size at the time. It also determines
 the size of an incremental backup so it can test for the Plan B to just run a
 level-1 if it does not work out to do a level-0 for that DLE.
-If the size of the DLE is much bigger than it has been the run before, AMANDA
+If the size of the DLE is much bigger than it has been the run before, Amanda
 still tries to meet your goals. It just reschedules stuff, combining full and
 incremental backups to meet the goals as good as possible.
-So you can think of it as some algorithm which lets AMANDA adapt to your data.
-If you set the goals in a reasonable way, AMANDA will just do the rest.
+So you can think of it as some algorithm which lets Amanda adapt to your data.
+If you set the goals in a reasonable way, Amanda will just do the rest.
 
  the multiple-dumps-question
 
@@ -212,18 +212,18 @@ ANSWER (provided by Jon LaBadie):
 Use another backup scheduler.
 This question is most often asked by individual computer users as a cost
 consideration.
-AMANDA was developed at the University of Maryland Computing Center for use in
+Amanda was developed at the University of Maryland Computing Center for use in
 moderately sized computer centers. That it can be used by users of small
 computers is a testament to its designers and maintainers.
 While it may seem cost effective to put as many dumps as possible on a single
 tape, in a computing center that would be considered a very risky decision. The
 loss of, or damage to, a single tape would be the loss of many days worth of
 dumps. That is too much to chance.
-Thus, AMANDA was designed to never overwrite a non-AMANDA tape, nor an AMANDA
-tape from a different configuration, nor an AMANDA tape from the current
+Thus, Amanda was designed to never overwrite a non-Amanda tape, nor an Amanda
+tape from a different configuration, nor an Amanda tape from the current
 configuration that is still "active", i.e. has backups on the tape more recent
 than the dumpcycle length.
-If you still feel you want AMANDA to put multiple dumps on a single tape, there
+If you still feel you want Amanda to put multiple dumps on a single tape, there
 is a crude way to accomplish your goal.
 But first ask yourself, "If my data is worth so little that I can not afford a
 few more tapes, why am I backing it up?"
@@ -241,7 +241,7 @@ tape. I.e. if you want a weeks' worth of backups on a single tape, leave the
 tape out for a week. Then stick it in and run amflush.
 (Better make sure you have sufficient disk space on your holding disk.)
 Note, a slight variant of this is to have the parameter autoflush in
-amanda.conf set to "yes". (Users of older AMANDA-releases should check out if
+amanda.conf set to "yes". (Users of older Amanda-releases should check out if
 their version already supports that parameter.)
 Then after several dumps have collected in the holding disk, put the tape in
 before that day's amdump is scheduled. amdump will both flush the holding disk
@@ -251,10 +251,10 @@ to tape and add the regularly scheduled dump.
 
 "How do i get off this damn mailing list?"
 ANSWER:
-Frequent users of the AMANDA-users-mailing-list get mails like containing
+Frequent users of the Amanda-users-mailing-list get mails like containing
 "unsubscribe"
 as people are trying desperately to get off the list.
-Everyone that subscribes to AMANDA-users gets a mail in which the following is
+Everyone that subscribes to Amanda-users gets a mail in which the following is
 contained:
 >Welcome to the amanda-users mailing list!
 >Please save this message for future reference. Thank you.
@@ -267,23 +267,23 @@ to <amanda-users@amanda.org> !
 
  the distro-question
 
-"Where can i get binary distributions of AMANDA?"
+"Where can i get binary distributions of Amanda?"
 ANSWER:
 It is well known that various distributions of Linux contain precompiled
-packages of AMANDA-servers and -clients.
-Due to the design of the AMANDA source code, in which MANY features can be
+packages of Amanda-servers and -clients.
+Due to the design of the Amanda source code, in which MANY features can be
 configured at compile-time, it is heavily and heartily recommended to take the
 effort and roll your own special flavour.
-Thinking about these things before actually doing backups with AMANDA will help
+Thinking about these things before actually doing backups with Amanda will help
 you in many ways. And you get the benefits of compiling your own paths/devices/
-configurations right into your AMANDA-binaries. You also get the benefit of a
-much more improved understanding of the way AMANDA does backups.
+configurations right into your Amanda-binaries. You also get the benefit of a
+much more improved understanding of the way Amanda does backups.
 
  the index-question
 
 "Why does amrecover say there are no index files?"
 ANSWER:
-It is very likely that AMANDA is right about that. Check your dumptypes and
+It is very likely that Amanda is right about that. Check your dumptypes and
 make sure they include the line:
 
   index yes
@@ -297,14 +297,14 @@ that line was edited?
  the tapetype-questions
 
 " amtapetype has been running for 9 days, is this normal?"
-"Will AMANDA work with my frozboz tape drive/library?"
+"Will Amanda work with my frozboz tape drive/library?"
 "Which device is my changer?"
 " amtapetype is broken, it says my 200GB tape only holds 65GB."
 "My file marks are HUGE, 1.3MB (on a 200GB tape, i.e. about 0.05% of the total
 capacity, or expressed another way, maybe 2 mm of a 125000 mm tape ...)"
 ANSWER:
-It is crucial to tell AMANDA the truth about the tape-device(s) you want to
-use. Given the wrong values, AMANDA can't calculate proper dumpsizes, free
+It is crucial to tell Amanda the truth about the tape-device(s) you want to
+use. Given the wrong values, Amanda can't calculate proper dumpsizes, free
 tape-space or make valuable use of compression.
 Before you consider running amtapetype, think twice. Twice.
 As tapedrives tend to be produced by not-so-small companies and as those not-
@@ -312,12 +312,12 @@ so-small companies tend to produce more than one unit to maximize profits, it
 is very likely that someone else has the same device you have or at least one
 that uses the same technology.
 Many people have already run amtapetype to determine the proper values to fill
-in their amanda.conf-files. Browse the example amanda.conf in your AMANDA-
-tarball for various tapetypes. Browse the AMANDA-FAQ on http://www.amanda.org.
+in their amanda.conf-files. Browse the example amanda.conf in your Amanda-
+tarball for various tapetypes. Browse the Amanda-FAQ on http://www.amanda.org.
 Chances are high that you find just your device described.
 As in every other topic discussed in internet mailing lists, please try finding
-an answer there before asking on the AMANDA-users list.
-If your device is so exotic that even the AMANDA-users can't help you, you
+an answer there before asking on the Amanda-users list.
+If your device is so exotic that even the Amanda-users can't help you, you
 still have your copy of amtapetype.
 Before you start running it, note this:
 
@@ -346,12 +346,12 @@ And for the filemark-size: Just read the question again.
 
 "How do I back up a partition that won't fit on a tape?"
 aka
-"Can AMANDA span one file over multiple tapes?"
+"Can Amanda span one file over multiple tapes?"
 ANSWER:
 There are two basic rules when it comes to these things:
 
-* AMANDA supports using more than one tape in a single run of amdump
-* AMANDA does not support splitting a dump image across tapes
+* Amanda supports using more than one tape in a single run of amdump
+* Amanda does not support splitting a dump image across tapes
 
 The first rule lets you make use of two or more tapes for a single amdump when
 using a tapechanger-robot or a tape-library. You could even use multiple tapes
@@ -388,26 +388,26 @@ Try to redefine your disklist as in the following example:
   exclude append "./bigdir"
   }
 
-(example taken from a mail by Paul Bijnens on the AMANDA-users-list)
+(example taken from a mail by Paul Bijnens on the Amanda-users-list)
 The trick is to form several chunks of data of which each fits on tape. In the
 example above the chunks are formed by regular expressions matching files named
 like file00, file123 and file9999. You have to look at your DLEs to find the
 patterns describing your chunks.
-As this technique forms data-chunks that fit on your tape it also helps AMANDA
+As this technique forms data-chunks that fit on your tape it also helps Amanda
 to schedule your backups more flexible. Having more and smaller DLEs, the
 planner has more variations to possibly schedule your backups, so this will
 help getting nice output from amadmin <conf> balance, too.
 
 Note
 
-DLE-spanning might be supported by AMANDA in a future release.
+DLE-spanning might be supported by Amanda in a future release.
 
  the GUI-question
 
-"Is anyone working on a GUI for AMANDA?"
+"Is anyone working on a GUI for Amanda?"
 ANSWER:
-Actually there are people working on GUIs for AMANDA. Aside from that the
-question really is: "Does anyone need a GUI for AMANDA?"
+Actually there are people working on GUIs for Amanda. Aside from that the
+question really is: "Does anyone need a GUI for Amanda?"
 Given the fact that backups tend to be run at night while people tend to sleep,
 who would need a fancy GUI showing 3D-backup-diagrams via X11? The only part of
 backups where GUIs maybe could add some comfort is recovery for unexperienced
@@ -427,5 +427,5 @@ users-mailinglist at mailto://amanda-users@amanda.org.
 -------------------------------------------------------------------------------
 
 Prev                     Up                          Next
-Chapter 17. AMANDA FAQ  Home  Chapter 19. AMANDA WISHLIST
+Chapter 19. Amanda FAQ  Home  Chapter 21. Amanda WISHLIST
 
index 3b64d8c602cb1dbc06284fb10c0afc36f5874a16..faa9c4582b207938e88833c6b4546d075702ee38 100644 (file)
@@ -1,10 +1,10 @@
 
-        Chapter 29. Upgrade Issues
+        Chapter 30. Upgrade Issues
 Prev  Part VI. Historical files  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 29. Upgrade Issues
+Chapter 30. Upgrade Issues
 
 
 Stefan G. Weichinger
@@ -17,17 +17,17 @@ Note
 
 Refer to http://www.amanda.org/docs/upgrade.html for the current version of
 this document.
-AMANDA 2.4.0 has introduced a major incompatibility in the AMANDA protocol.
+Amanda 2.4.0 has introduced a major incompatibility in the Amanda protocol.
 This means that pre-2.4.0 clients won't interoperate with a 2.4.0 server, nor
 will 2.4.0 clients interoperate with pre-2.4.0 servers. You have to upgrade
 them all at the same time.
-To ease the upgrade process AMANDA has, from release 2.4.0 on, a configure flag
-(--with-testing) that will cause AMANDA to use alternate service names (AMANDA-
+To ease the upgrade process Amanda has, from release 2.4.0 on, a configure flag
+(--with-testing) that will cause Amanda to use alternate service names (Amanda-
 test) instead of the standard ones. This allows you to keep using your old
-version of AMANDA while you test the new one.
-Depending upon the version of AMANDA you are upgrading from, AMANDA may use a
-different database library to store the backup information, and the new AMANDA
-may not be able to read the old AMANDA database files. In this case, you will
+version of Amanda while you test the new one.
+Depending upon the version of Amanda you are upgrading from, Amanda may use a
+different database library to store the backup information, and the new Amanda
+may not be able to read the old Amanda database files. In this case, you will
 want to do something like the following:
 Before the upgrade (using the old version of amadmin):
 
@@ -63,6 +63,6 @@ http://www.amanda.org/2.4-conv/msg00428.html
 -------------------------------------------------------------------------------
 
 Prev                                   Up                            Next
-Chapter 28. Response to CPIO Security Home  Chapter 30. What once was new
+Chapter 29. Response to CPIO Security Home  Chapter 31. What once was new
 Notice Issue 11: 
 
index 0c7a775b3dad796158abcf360d2fe26074f0f8c3..81750940cb1e1efed56485ec58544f092fecb583 100644 (file)
@@ -1,10 +1,10 @@
 
-            Chapter 16. Using AMANDA
+            Chapter 18. Using Amanda
 Prev  Part IV. Various Information  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 16. Using AMANDA
+Chapter 18. Using Amanda
 
 
 John R. Jackson
@@ -29,24 +29,24 @@ Table of Contents
 
   An_Introduction
 
-  AMANDA_Features
+  Amanda_Features
 
-  Future_Capabilities_of_AMANDA
+  Future_Capabilities_of_Amanda
 
-  AMANDA_Resources
+  Amanda_Resources
 
-  Installing_AMANDA
+  Installing_Amanda
 
 
         Install_Related_Packages
 
         Perform_Preliminary_Setup
 
-        Configure_the_AMANDA_Build
+        Configure_the_Amanda_Build
 
-        Build_and_Install_AMANDA
+        Build_and_Install_Amanda
 
-        Configuring_AMANDA
+        Configuring_Amanda
 
         Decide_on_a_Tape_Server
 
@@ -74,7 +74,7 @@ Table of Contents
 
         Run_amdump
 
-        Read_AMANDA's_Reports
+        Read_Amanda's_Reports
 
         Monitor_Tape_and_Holding_Disk_Status
 
@@ -83,7 +83,7 @@ Table of Contents
         Miscellanous_Operational_Notes
 
 
-  Advanced_AMANDA_Configuration
+  Advanced_Amanda_Configuration
 
 
         Adjust_the_Backup_Cycle
@@ -95,14 +95,14 @@ Table of Contents
         Excluding_Files
 
 
-  Restoring_with_AMANDA
+  Restoring_with_Amanda
 
 
         Configuring_and_Using_amrecover
 
         Using_amrestore
 
-        Restoring_Without_AMANDA
+        Restoring_Without_Amanda
 
 
 
@@ -120,26 +120,26 @@ This chapter was written by John R. Jackson with input from Alexandre Oliva. It
 is part of the O'Reilly book "Unix Backup & Recovery" by W. Curtis Preston and
 has been provided online at http://www.backupcentral.com/amanda.html since the
 first edition of this book.
-During the Docbook-conversion of the AMANDA-docs we asked for permission to
-include this chapter in the Official AMANDA documentation and W. Curtis Preston
+During the Docbook-conversion of the Amanda-docs we asked for permission to
+include this chapter in the Official Amanda documentation and W. Curtis Preston
 allowed to us to include the now converted version. There will be some updates
 to this chapter in the next few months to reflect various changes and
 enhancements.
 You can find online versions of this chapter at http://www.amanda.org/docs/
 using.html and at http://www.backupcentral.com/amanda.html.
-AMANDA, the Advanced Maryland Automated Network Disk Archiver, is a public
+Amanda, the Advanced Maryland Automated Network Disk Archiver, is a public
 domain utility developed at the University of Maryland. It is as advanced as a
-free backup utility gets, and has quite a large user community. AMANDA allows
+free backup utility gets, and has quite a large user community. Amanda allows
 you to set up a single master backup server to back up multiple hosts to a
-single backup drive. (It also works with a number of stackers.) AMANDA uses
+single backup drive. (It also works with a number of stackers.) Amanda uses
 native dump and/or GNU-tar, and can back up a large number of workstations
 running multiple versions of Unix. Recent versions can also use SAMBA to back
-up Microsoft Windows (95/98/NT/2000)-based hosts. More information about AMANDA
+up Microsoft Windows (95/98/NT/2000)-based hosts. More information about Amanda
 can be found at http://www.amanda.org
-AMANDA was written primarily by James da Silva at the Department of Computer
+Amanda was written primarily by James da Silva at the Department of Computer
 Science of the University of Maryland around 1992. The goal was to be able to
 back up large numbers of client workstations to a single backup server machine.
-AMANDA was driven by the introduction of large capacity tape drives, such as
+Amanda was driven by the introduction of large capacity tape drives, such as
 ExaByte 8mm and DAT 4mm. With these drives, and the increased number of
 personal workstations, it no longer made sense to back up individual machines
 to separate media. Coordinating access and providing tape hardware was
@@ -150,54 +150,54 @@ streaming mode, causing a severe performance penalty.
 
 Note
 
-Since AMANDA is optimized to take advantage of tape drives, we will use the
+Since Amanda is optimized to take advantage of tape drives, we will use the
 word tape throughout this section. However, that doesn't mean that you couldn\19t
 use it with an optical or CD-R drive.
-The AMANDA approach is to use a "holding disk" on the tape server machine, do
+The Amanda approach is to use a "holding disk" on the tape server machine, do
 several dumps in parallel into files in the holding disk, and have an
 independent process take data out of the holding disk. Because most dumps are
 small partials, even a modest amount of holding disk space can provide an
 almost optimal flow of dump images onto tape.
-AMANDA also has a unique approach to scheduling dumps. A "dump cycle" is
-defined for each area to control the maximum time between full dumps. AMANDA
+Amanda also has a unique approach to scheduling dumps. A "dump cycle" is
+defined for each area to control the maximum time between full dumps. Amanda
 takes that information, statistics about past dump performance, and estimates
 on the size of dumps for this run to decide which backup level to do. This gets
 away from the traditional static "it's Friday so do a full dump of /usr on
-client A" approach and frees AMANDA to balance the dumps so the total run time
+client A" approach and frees Amanda to balance the dumps so the total run time
 is roughly constant from day to day.
-AMANDA is freely-available software maintained by the AMANDA Users Group. Based
-on membership of AMANDA-related mailing lists, there are probably well over
-1500 sites using it. This chapter is based on AMANDA version 2.4.2. Updated
-versions of this section will be available with the AMANDA source code.
+Amanda is freely-available software maintained by the Amanda Users Group. Based
+on membership of Amanda-related mailing lists, there are probably well over
+1500 sites using it. This chapter is based on Amanda version 2.4.2. Updated
+versions of this section will be available with the Amanda source code.
 
-AMANDA Features
+Amanda Features
 
-AMANDA is designed to handle large numbers of clients and data, yet is
+Amanda is designed to handle large numbers of clients and data, yet is
 reasonably simple to install and maintain. It scales well, so small
 configurations, even a single host, are possible. The code is portable to a
 large number of Unix platforms. It calls standard backup software, such as
 vendor provided dump or GNU-tar, to perform actual client dumping. There is
 also support for backing up Windows-based hosts via SAMBA. There is no
 Macintosh support yet.
-AMANDA provides its own network protocols on top of TCP and UDP. It does not,
+Amanda provides its own network protocols on top of TCP and UDP. It does not,
 for instance, use rsh or rdump/rmt. Each client backup program is instructed to
-write to standard output, which AMANDA collects and transmits to the tape
-server host. This allows AMANDA to insert compression and encryption and also
+write to standard output, which Amanda collects and transmits to the tape
+server host. This allows Amanda to insert compression and encryption and also
 gather a catalogue of the image for recovery. Multiple clients are typically
 backed up in parallel to files in one or more holding disk areas. A separate
 tape writing process strives to keep the tape device streaming at maximum
-throughput. AMANDA can run direct to tape without holding disks, but with
+throughput. Amanda can run direct to tape without holding disks, but with
 reduced performance.
-AMANDA supports using more than one tape in a single run, but does not yet
+Amanda supports using more than one tape in a single run, but does not yet
 split a dump image across tapes. This also means it does not support dump
-images larger than a single tape. AMANDA currently starts a new tape for each
+images larger than a single tape. Amanda currently starts a new tape for each
 run and does not provide a mechanism to append a new run to the same tape as a
 previous run, which might be an issue for small configurations.
-AMANDA supports a wide range of tape storage devices. It uses basic operations
+Amanda supports a wide range of tape storage devices. It uses basic operations
 through the normal operating system I/O subsystem and a simple definition of
 characteristics. New devices are usually trivial to add. Several tape changers,
 stackers, and robots are supported to provide truly hands-off operation. The
-changer interface is external to AMANDA and well-documented, so unsupported
+changer interface is external to Amanda and well-documented, so unsupported
 changers can be added without a lot of effort.
 Either the client or tape server may do software compression, or hardware
 compression may be used. On the client side, software compression reduces
@@ -205,27 +205,27 @@ network traffic. On the server side, it reduces client CPU load. Software
 compression may be selected on an image-by-image basis. If Kerberos is
 available, clients may use it for authentication and dump images may be
 encrypted. Without Kerberos, .amandahosts authentication (similar to .rhosts)
-is used, or AMANDA may be configured to use .rhosts (although rsh/rlogin/rexec
-are not themselves used). AMANDA works well with security tools like TCP
+is used, or Amanda may be configured to use .rhosts (although rsh/rlogin/rexec
+are not themselves used). Amanda works well with security tools like TCP
 Wrappers (ftp://info.cert.org/pub/network_tools) and firewalls.
 Since standard software is used for generating dump images and software
 compression, only normal Unix tools such as mt, dd, and gunzip/uncompress are
-needed to recover a dump image from tape if AMANDA is not available. When
-AMANDA software is available, it locates which tapes are needed and finds
+needed to recover a dump image from tape if Amanda is not available. When
+Amanda software is available, it locates which tapes are needed and finds
 images on the tapes.
-AMANDA is meant to run unattended, such as from a nightly cron job. Client
-hosts that are down or hung are noted and bypassed. Tape errors cause AMANDA to
+Amanda is meant to run unattended, such as from a nightly cron job. Client
+hosts that are down or hung are noted and bypassed. Tape errors cause Amanda to
 fall back to ?degraded? mode where backups are still performed but only to the
 holding disks. They may be flushed to tape by hand after the problem is
 resolved.
-AMANDA has configuration options for controlling almost all aspects of the
+Amanda has configuration options for controlling almost all aspects of the
 backup operation and provides several scheduling methods. A typical
 configuration does periodic full dumps with partial dumps in between. There is
 also support for:
 
 * Periodic archival backup, such as taking full dumps to a vault away from the
   primary site.
-* Incremental-only backups where full dumps are done outside of AMANDA, such as
+* Incremental-only backups where full dumps are done outside of Amanda, such as
   very active areas that must be taken offline, or no full dumps at all for
   areas that can easily be recovered from vendor media.
 * Always doing full dumps, such as database areas that change completely
@@ -236,40 +236,40 @@ It's easy to support multiple configurations on the same tape server machine,
 such as a periodic archival configuration along side a normal daily
 configuration. Multiple configurations can run simultaneously on the same tape
 server if there are multiple tape drives.
-Scheduling of full dumps is typically left up to AMANDA. They are scattered
+Scheduling of full dumps is typically left up to Amanda. They are scattered
 throughout the dump cycle to balance the amount of data backed up each run.
 It's important to keep logs of where backup images are for each area (which
-AMANDA does for you), since they are not on a specific, predictable, tape
+Amanda does for you), since they are not on a specific, predictable, tape
 (e.g., the Friday tape will not always have a full dump of /usr for client A).
-The partial backup level is also left to AMANDA. History information about
+The partial backup level is also left to Amanda. History information about
 previous levels is kept and the backup level automatically increases when
 sufficient dump size savings will be realized.
-AMANDA uses a simple tape management system and protects itself from
+Amanda uses a simple tape management system and protects itself from
 overwriting tapes that still have valid dump images and from tapes not
 allocated to the configuration. Images may be overwritten when a client is down
 for an extended period or if not enough tapes are allocated, but only after
-AMANDA has issued several warnings. AMANDA can also be told to not reuse
+Amanda has issued several warnings. Amanda can also be told to not reuse
 specific tapes.
 A validation program may be used before each run to note potential problems
 during normal working hours when they are easier to correct. An activity report
-is sent via e-mail after each run. AMANDA can also send a report to a printer
+is sent via e-mail after each run. Amanda can also send a report to a printer
 and even generate sticky tape labels.
 There is no graphical interface. For administration, there is usually only a
 single simple text file to edit, so this is not much of an issue. For security
-reasons, AMANDA does not support user controlled file recovery. There is an
+reasons, Amanda does not support user controlled file recovery. There is an
 ftp-like restore utility for administrators to make searching online dump
 catalogues easier when recovering individual files.
 
-Future Capabilities of AMANDA
+Future Capabilities of Amanda
 
 In addition to the usual enhancements and fixes constantly being added by the
-AMANDA Core Development Team, three main changes are in various stages of
+Amanda Core Development Team, three main changes are in various stages of
 development.
 
 * A new internal security framework will make it easier for developers to add
   other security methods, such as SSH (ftp://ftp.cs.hut.fi/pub/ssh/) and SSL
   (Secure Socket Layer).
-* Another major project is a redesign of how AMANDA runs the client dump
+* Another major project is a redesign of how Amanda runs the client dump
   program. This is currently hardcoded for a vendor dump program, GNU-tar or
   SAMBA tar. The new mechanism will allow arbitrary programs such as cpio,
   star, and possibly other backup systems. It will also add optional pre-dump
@@ -285,34 +285,34 @@ development.
 * In addition, the output format will be enhanced to include a file-1 and a
   file-n. The idea is to put site-defined emergency recovery tools in file-1
   (the first file on the output) that can be retrieved easily with standard
-  non-AMANDA programs like tar, then use those tools to retrieve the rest of
+  non-Amanda programs like tar, then use those tools to retrieve the rest of
   the data. The file-n area is the last file on the output and can contain
-  items such as the AMANDA database, which would be complete and up to date by
+  items such as the Amanda database, which would be complete and up to date by
   the time file-n is written.
 
 
-AMANDA Resources
+Amanda Resources
 
-AMANDA may be obtained via the web page http://www.amanda.org or with anonymous
+Amanda may be obtained via the web page http://www.amanda.org or with anonymous
 ftp at ftp://ftp.amanda.org/pub/amanda.A typical release is a gzip compressed
 tar file with a name like amanda-2.4.1.tar.gz, which means it is major version
 2.4 and minor version 1. There are occasional patch releases that have a name
 like amanda-2.4.1p1.tar.gz (release 2.4.1 plus patch set 1). Beta test pre-
 releases have a names like amanda-2.5.0b3.tar.gz (third beta test pre-release
 of 2.5.0).
-Some operating system distributions provide pre-compiled versions of AMANDA,
-but because AMANDA hardcodes some values into the programs, they may not match
+Some operating system distributions provide pre-compiled versions of Amanda,
+but because Amanda hardcodes some values into the programs, they may not match
 the configuration. Work is being done to move these values to run-time
-configuration files, but for now AMANDA should be built from source.
-The AMANDA web page contains useful information about patches not yet part of a
+configuration files, but for now Amanda should be built from source.
+The Amanda web page contains useful information about patches not yet part of a
 release, how to subscribe to related mailing lists, and pointers to mailing
 list archives. Subscribe to at least amanda-announce to get new release
 announcements or amanda-users to get announcements plus see problems and
-resolutions from other AMANDA users. The amanda-users mailing list is a
+resolutions from other Amanda users. The amanda-users mailing list is a
 particularly good resource for help with initial setup as well as problems.
 When posting to it, be sure to include the following information:
 
-* AMANDA version
+* Amanda version
 * OS version on the server and client(s)
 * Exact symptoms seen, such as error messages, relevant sections of e-mail
   reports, debugging and log files
@@ -322,15 +322,15 @@ When posting to it, be sure to include the following information:
 Finally, the docs directory in the release contains several files with helpful
 information, such as a FAQ.
 
-Installing AMANDA
+Installing Amanda
 
-After downloading and unpacking the AMANDA release, read the README, docs/
+After downloading and unpacking the Amanda release, read the README, docs/
 INSTALL, and docs/SYSTEM.NOTES files. They contain important and up-to-date
-information about how to set up AMANDA.
+information about how to set up Amanda.
 
 Install Related Packages
 
-Several other packages may be required to complete an AMANDA install. Before
+Several other packages may be required to complete an Amanda install. Before
 continuing, you should locate and install packages your environment will need.
 In particular, consider the following:
 
@@ -338,85 +338,85 @@ In particular, consider the following:
   GNU-tar 1.12 or later \14 www.gnu.org
       The GNU version of the standard tar program with enhancements to do
       partial backups and omit selected files. It is one of the client backup
-      programs AMANDA knows how to use.
+      programs Amanda knows how to use.
 
   Samba 1.9.18p10 or later \14 www.samba.org
       SAMBA is an implementation of the System Message Block (SMB) protocol
       used by Windows-based systems for file access. It contains a tool,
-      smbclient, that AMANDA can use to back them up.
+      smbclient, that Amanda can use to back them up.
 
   Perl 5.004 or later \14 www.perl.org
       Perl is a scripting programming language oriented toward systems
-      programming and text manipulation. It is used for a few optional AMANDA
+      programming and text manipulation. It is used for a few optional Amanda
       reporting tools and by some tape changers.
 
   GNU readline 2.2.1 or later \14 www.gnu.org
       The GNU readline library may be incorporated into interactive programs to
-      provide command-line history and editing. It is built into the AMANDA
+      provide command-line history and editing. It is built into the Amanda
       amrecover restoration tool, if available.
 
   GNU awk 3.0.3 or later \14 www.gnu.org
       The GNU version of the awk programming language contains a common version
       across platforms and some additional features. It is used for the
-      optional AMANDA amplot statistics tool.
+      optional Amanda amplot statistics tool.
 
   Gnuplot 3.5 or later \14 ftp://ftp.dartmouth.edu/pub/gnuplot/
       This gnuplot library (which has nothing to do with the GNU tools, see the
       accompanying README) is a graph plotting package. It is used for the
-      optional AMANDA amplot statistics tool.
+      optional Amanda amplot statistics tool.
 
-Be sure to look in the AMANDA patches directory and the patches section on the
+Be sure to look in the Amanda patches directory and the patches section on the
 web page for updates to these packages. SAMBA versions before 2.0.3, in
 particular, must have patches applied to make them work properly with Amanda.
 Without the patches, backups appear to work but the resulting images are
 corrupt.
-When AMANDA is configured, locations of additional software used on the
-clients, such as GNU-tar and SAMBA, get built into the AMANDA programs, so
-additional software must be installed in the same place on the AMANDA build
+When Amanda is configured, locations of additional software used on the
+clients, such as GNU-tar and SAMBA, get built into the Amanda programs, so
+additional software must be installed in the same place on the Amanda build
 machine and all the clients.
 
 Perform Preliminary Setup
 
-A typical AMANDA configuration runs as a user other than root, such as backup
+A typical Amanda configuration runs as a user other than root, such as backup
 or amanda, given just enough permissions to do backups. Often, direct login as
 the user is disallowed. To use the vendor dump program instead of GNU-tar, the
-AMANDA user must be in a group with read access to the raw disk devices.
+Amanda user must be in a group with read access to the raw disk devices.
 Membership in this group should be tightly controlled since it opens up every
 file on the client for viewing.
-There are two ways to link AMANDA and the raw device group membership. Either
-put the AMANDA user in the group that currently owns the raw devices, as the
-primary group or as a secondary, or pick a new group for AMANDA and change the
-group ownership of the devices. AMANDA (actually, the vendor dump program)
+There are two ways to link Amanda and the raw device group membership. Either
+put the Amanda user in the group that currently owns the raw devices, as the
+primary group or as a secondary, or pick a new group for Amanda and change the
+group ownership of the devices. Amanda (actually, the vendor dump program)
 needs only read access, so turn off group write permission. Turn off all
 "world" access.
-To use GNU-tar, AMANDA runs it under a setuid-root program that grants the
-needed permissions. The GNU version of tar must be used with AMANDA. Vendor
+To use GNU-tar, Amanda runs it under a setuid-root program that grants the
+needed permissions. The GNU version of tar must be used with Amanda. Vendor
 supplied versions (unless they originated from GNU and are at least version
-1.12) do not work because AMANDA depends on additional features.
+1.12) do not work because Amanda depends on additional features.
 
-Configure the AMANDA Build
+Configure the Amanda Build
 
-Use the AMANDA user and group for the --with-user and --with-group options to
+Use the Amanda user and group for the --with-user and --with-group options to
 ./configure. For instance, to use amanda for the user and backup as the group:
 ./configure --with-user=amanda --with-group=backup ...
 No other options are required for ./configure, but all the possibilities may be
 seen with ./configure --help. Don't get carried away changing options. The
-defaults are usually suitable and some require experience with AMANDA to fully
+defaults are usually suitable and some require experience with Amanda to fully
 understand. Leave --with-debugging enabled so debug log files are created on
 the clients. They take very little space but are often necessary for tracking
 down problems.
 The normal build creates both tape server and client software. The tape server
-host is often backed up by AMANDA and needs the client parts. However, the
+host is often backed up by Amanda and needs the client parts. However, the
 clients usually do not need the tape server parts. A little disk space and
 build time may be saved by adding --without-server to the ./configure arguments
 when building for them.
 The default security mechanism uses a file formatted just like .rhosts but
-called .amandahosts. This keeps AMANDA operations separate from normal rsh/rcp
+called .amandahosts. This keeps Amanda operations separate from normal rsh/rcp
 work that might use the same user. It is not recommended, but .rhosts and
 hosts.equiv may be used by adding --without-amandahosts to the ./configure
 arguments.
 The TCP ports used for data transfer may be restricted with --with-portrange to
-use AMANDA between hosts separated by a firewall. A typical entry would be: ./
+use Amanda between hosts separated by a firewall. A typical entry would be: ./
 configure --with-portrange=50000,50100 ... This does not affect the initial UDP
 requests made from the tape server to the clients. The amanda UDP port
 (typically 10080) must be allowed through the firewall.
@@ -424,11 +424,11 @@ If more than just a few ./configure options are used, they may be put in /usr/
 local/share/config.site or /usr/local/etc/config.site to keep them the same
 from build to build. An example is in example/config.site.
 
-Build and Install AMANDA
+Build and Install Amanda
 
-After ./configure is done, run make to build AMANDA, then make install to
-install it. The make install step must be done as root because some AMANDA
-programs require system privileges. Unless the base location is changed, AMANDA
+After ./configure is done, run make to build Amanda, then make install to
+install it. The make install step must be done as root because some Amanda
+programs require system privileges. Unless the base location is changed, Amanda
 installs into these areas:
 
 
@@ -439,13 +439,13 @@ installs into these areas:
       Libraries.
 
   /usr/local/libexec
-      Private programs only AMANDA uses.
+      Private programs only Amanda uses.
 
   /usr/local/man
       Documentation.
 
-Now is a good time to read the main AMANDA man page. It provides an overview of
-AMANDA, a description of each program, and detailed configuration information.
+Now is a good time to read the main Amanda man page. It provides an overview of
+Amanda, a description of each program, and detailed configuration information.
 The following programs must be setuid-root (which make install as root does).
 The first group (amcheck,dumper, and planner) run on the tape server machine
 and need a privileged network port for secure communication with the clients.
@@ -454,7 +454,7 @@ the dump program used and operating system type.
 
 
   sbin/amcheck
-      AMANDA sanity checker program
+      Amanda sanity checker program
 
   libexec/dumper
       Client communication program
@@ -473,13 +473,13 @@ the dump program used and operating system type.
       Setuid wrapper to run GNU-tar as root
 
 All these programs are installed with world access disabled and group access
-set to the AMANDA group from --with-group. Be sure all members of that group
+set to the Amanda group from --with-group. Be sure all members of that group
 are trustworthy since rundump and runtar in particular give access to every
-file on the system. If AMANDA software is made available via NFS, be sure the
+file on the system. If Amanda software is made available via NFS, be sure the
 mount options allow setuid programs. Also, if GNU-tar is used, root needs write
 access to /usr/local/var/amanda/gnutar-lists (or the --with-gnutar-list value
 to ./configure) to store information about each partial level.
-If the build has trouble or AMANDA needs to be rebuilt, especially with
+If the build has trouble or Amanda needs to be rebuilt, especially with
 different ./configure options, the following sequence makes sure everything is
 cleaned up from the previous build: make distclean ./configure ... make make
 install (as root) Problems with the ./configure step can sometimes be diagnosed
@@ -492,17 +492,17 @@ to system header files and must be re-installed or have its fixincludes step
 rerun (see the gcc release installation notes) if the operating system is
 upgraded. Running gcc --verbose shows where gcc gets its information, and
 contains an indication of the operating system version expected.
-AMANDA needs changes to the network services and inetd configuration files. The
+Amanda needs changes to the network services and inetd configuration files. The
 client-src/patch-system script should be able to set up systems in most cases.
 It does not currently handle systems that deliver service entries via YP/NIS.
 If the script does not work, add the following entries to the services file
 (e.g., /etc/services) or YP/NIS map: Amanda 10080/udp Amandaidx 10082/tcp
 Amidxtape 10083/tcp
 Each client needs an entry in the inetd configuration file (e.g., /etc/
-inetd.conf) like this, substituting the AMANDA user for Amanda and the full
-path to the AMANDA libexec directory for PATH: amanda dgram udp wait Amanda /
+inetd.conf) like this, substituting the Amanda user for Amanda and the full
+path to the Amanda libexec directory for PATH: amanda dgram udp wait Amanda /
 PATH/libexec/amandad amandad
-The amanda service is used by all AMANDA controlling programs to perform
+The amanda service is used by all Amanda controlling programs to perform
 functions on the clients.
 The tape server host needs entries like these if the amrecover tool is to be
 used: amandaidx stream tcp nowait Amanda /PATH/libexec/amindexd amindexd
@@ -512,20 +512,20 @@ provides remote access to a tape device. After every inetd configuration file
 change, send a HUP signal to the inetd process and check the system logs for
 errors.
 
-Configuring AMANDA
+Configuring Amanda
 
-Once installed, AMANDA must be configured to your environment.
+Once installed, Amanda must be configured to your environment.
 
 Decide on a Tape Server
 
-The first thing to decide is what machine will be the AMANDA tape server.
-AMANDA can be CPU-intensive if configured to do server compression, and almost
+The first thing to decide is what machine will be the Amanda tape server.
+Amanda can be CPU-intensive if configured to do server compression, and almost
 certainly network and I/O-intensive. It does not typically use much real
 memory. It needs direct access to a tape device that supports media with enough
 capacity to handle the expected load.
 To get a rough idea of the backup sizes, take total disk usage (not capacity),
 Usage, and divide it by how often full dumps will be done, Runs. Pick an
-estimated run-to-run change rate, Change. Each AMANDA run, on average, does a
+estimated run-to-run change rate, Change. Each Amanda run, on average, does a
 full dump of Usage/Runs. Another Usage/Runs*Change is done of areas that got a
 full dump the previous run, Usage/Runs*Change* is done of areas that got a full
 dump two runs ago, and so on.
@@ -552,20 +552,20 @@ Decide Which Tape Devices to Use
 
 Unix operating systems typically incorporate device characteristics into the
 file name used to access a tape device. The two to be concerned with are
-"rewind" and "compression." AMANDA must be configured with the non-rewinding
+"rewind" and "compression." Amanda must be configured with the non-rewinding
 tape device, so called because when the device is opened and closed it stays at
 the same position and does not automatically rewind. This is typically a name
 with an n in it, such as /dev/rmt/0n or /dev/nst0. On AIX, it is a name with a
 .1 or .5 suffix.
-Put the AMANDA user in the group that currently owns the tape device, either as
-the primary group or as a secondary, or pick a new group for AMANDA and change
-the group ownership of the device. AMANDA needs both read and write access.
+Put the Amanda user in the group that currently owns the tape device, either as
+the primary group or as a secondary, or pick a new group for Amanda and change
+the group ownership of the device. Amanda needs both read and write access.
 Turn off all "world" access.
 
 Decide Whether to Use Compression
 
 Dump images may optionally be compressed on the client, the tape server, or the
-tape device hardware. Software compression allows AMANDA to track usage and
+tape device hardware. Software compression allows Amanda to track usage and
 make better estimates of image sizes, but hardware compression is more
 efficient of CPU resources. Turn off hardware compression when using software
 compression on the client or server. See the operating system documentation for
@@ -574,43 +574,43 @@ device file name just like the non-rewinding flag. AIX uses the chdev command.
 
 Decide Where the Holding Space Will Be
 
-If at all possible, allocate some holding disk space for AMANDA on the tape
+If at all possible, allocate some holding disk space for Amanda on the tape
 server. Holding disk space can significantly reduce backup time by allowing
 several dumps to be done at once while the tape is being written. Also, for
-streaming tape devices, AMANDA keeps the device going at speed, and that may
-increase capacity. AMANDA may be configured to limit disk use to a specific
+streaming tape devices, Amanda keeps the device going at speed, and that may
+increase capacity. Amanda may be configured to limit disk use to a specific
 value so it can share with other applications, but a better approach is to
-allocate one or more inexpensive disks entirely to AMANDA.
+allocate one or more inexpensive disks entirely to Amanda.
 Ideally, there should be enough holding disk space for the two largest backup
 images simultaneously, so one image can be coming into the holding disk while
 the other is being written to tape. If that is not practical, any amount that
-holds at least a few of the smaller images helps. The AMANDA report for each
+holds at least a few of the smaller images helps. The Amanda report for each
 run shows the size of the dump image after software compression (if enabled).
 That, in addition to the amplot and amstatus tools, may be used to tune the
 space allocated.
 
 Compute Your Dump Cycle
 
- Decide how often AMANDA should do full dumps. This is the "dump cycle." Short
+ Decide how often Amanda should do full dumps. This is the "dump cycle." Short
 periods make restores easier because there are fewer partials, but use more
-tape and time. Longer periods let AMANDA spread the load better but may require
+tape and time. Longer periods let Amanda spread the load better but may require
 more steps during a restore.
 Large amounts of data to back up or small capacity tape devices also affect the
-dump cycle. Choose a period long enough that AMANDA can do a full dump of every
+dump cycle. Choose a period long enough that Amanda can do a full dump of every
 area during the dump cycle and still have room in each run for the partials.
 Typical dump cycles are one or two weeks. Remember that the dump cycle is an
-upper limit on how often full dumps are done, not a strict value. AMANDA runs
+upper limit on how often full dumps are done, not a strict value. Amanda runs
 them more often and at various times during the cycle as it balances the backup
 load. It violates the limit only if a dump fails repeatedly, and issues
 warnings in the e-mail report if that is about to happen.
-By default, AMANDA assumes it is run every day. If that is not the case, set
+By default, Amanda assumes it is run every day. If that is not the case, set
 "runs per cycle" (described below) to a different value. For instance, a dump
 cycle of seven days and runs per cycle of five would be used if runs are done
 only on weekdays.
-Normally, AMANDA uses one tape per run. With a tape changer (even the chg-
+Normally, Amanda uses one tape per run. With a tape changer (even the chg-
 manual one), the number of tapes per run may be set higher for extra capacity.
-This is an upper limit on the number of tapes. AMANDA uses only as much tape as
-it needs. AMANDA does not yet do overflow from one tape to another. If it hits
+This is an upper limit on the number of tapes. Amanda uses only as much tape as
+it needs. Amanda does not yet do overflow from one tape to another. If it hits
 end of tape (or any other error) while writing an image, that tape is
 unmounted, the next one is loaded, and the image starts over from the
 beginning. This sequence continues if the image cannot fit on a tape.
@@ -625,7 +625,7 @@ needs 22 tapes (10+1 runs * two tapes/run).
 More tapes than the minimum should be allocated to handle error situations.
 Allocating at least two times the minimum allows the previous full dump to be
 used if the most recent full dump cannot be read. Allocating more tapes than
-needed also goes back further in time to recover lost files. AMANDA does not
+needed also goes back further in time to recover lost files. Amanda does not
 have a limit on the number of tapes in the tape cycle.
 
 Copy and Edit the Default Configuration File
@@ -633,17 +633,17 @@ Copy and Edit the Default Configuration File
 Pick a name for the configuration (the name Daily will be used for the rest of
 this section). Create a directory on the tape server machine to hold the
 configuration files, typically /usr/local/etc/amanda/Daily. Access to this
-directory (or perhaps its parent) should be restricted to the AMANDA group or
-even just the AMANDA user.
+directory (or perhaps its parent) should be restricted to the Amanda group or
+even just the Amanda user.
 Each tape assigned to a configuration needs a unique label. For this example,
 we'll use the configuration name, a dash, and a three-digit suffix, Daily-000
 through Daily-999. Do not use blanks, tabs, slashes (/), shell wildcards, or
 non-printable characters.
-AMANDA limits network usage so backups do not take all the capacity. This limit
-is imposed when AMANDA is deciding whether to perform a dump by estimating the
+Amanda limits network usage so backups do not take all the capacity. This limit
+is imposed when Amanda is deciding whether to perform a dump by estimating the
 throughput and adding that to dumps that are already running. If the value
-exceeds the bandwidth allocated to AMANDA, the dump is deferred until enough
-others complete. Once a dump starts, AMANDA lets underlying network components
+exceeds the bandwidth allocated to Amanda, the dump is deferred until enough
+others complete. Once a dump starts, Amanda lets underlying network components
 do any throttling.
 Copy the template example/amanda.conf file to the configuration directory and
 edit it. Full documentation is in the amanda man page. There are many
@@ -652,10 +652,10 @@ following (some of which are described later):
 
 
   org
-      This string will be in the Subject line of AMANDA e-mail reports.
+      This string will be in the Subject line of Amanda e-mail reports.
 
   mailto
-      Target address for AMANDA e-mail reports.
+      Target address for Amanda e-mail reports.
 
   dumpuser
       Same as --with-user from ./configure.
@@ -680,41 +680,40 @@ following (some of which are described later):
       Type of tape media.
 
   netusage
-      Network bandwidth allocated to AMANDA.
+      Network bandwidth allocated to Amanda.
 
   labelstr
       A regular expression (grep pattern) used to make sure each tape is
-      allocated to this AMANDA configuration. Our example might use Daily-[0-9]
+      allocated to this Amanda configuration. Our example might use Daily-[0-9]
       [0-9][0-9].
 
 The following parameters probably do not need to be changed, but look at their
-values to know where AMANDA expects to find things:
+values to know where Amanda expects to find things:
 
 
   infofile
-      Location of AMANDA history database. Older versions of AMANDA used this
+      Location of Amanda history database. Older versions of Amanda used this
       as the base name of a database file. Newer versions use this as a
       directory name.
 
   logdir
-      Directory where AMANDA logs are stored.
+      Directory where Amanda logs are stored.
 
   indexdir
-      Location of optional AMANDA catalogue database.
+      Location of optional Amanda catalogue database.
 
 
 Configure the Holding Disk
 
 Define each holding disk in an amanda.conf holdingdisk section. If partitions
-are dedicated to AMANDA, set the use value to a small negative number, such as
--10 MB. This tells AMANDA to use all but that amount of space. If space is
-shared with other applications, set the value to the amount AMANDA may use,
-create the directory and set the permissions so only the AMANDA user can access
+are dedicated to Amanda, set the use value to a small negative number, such as
+-10 MB. This tells Amanda to use all but that amount of space. If space is
+shared with other applications, set the value to the amount Amanda may use,
+create the directory and set the permissions so only the Amanda user can access
 it.
-Set a chunksize value for each holding disk. Negative numbers cause AMANDA to
-write dumps larger than the absolute value directly to tape, bypassing the
-holding disk. Positive numbers split dumps in the holding disk into chunks no
-larger than the chunksize value. Even though the images are split in the
+Set a chunksize value for each holding disk. Positive numbers split dumps in
+the holding disk into chunks no larger than the chunksize value. Negative
+numbers are no longer supported. Even though the images are split in the
 holding disk, they are written to tape as a single image. At the moment, all
 chunks for a given image go to the same holding disk.
 Older operating systems that do not support individual files larger than 2GB
@@ -724,11 +723,11 @@ larger than 2 GB should have a very large value, such as 2000 GBytes.
 
 Configure Tape Devices and Label Tapes
 
-AMANDA needs to know some characteristics of the tape media. This is set in a
+Amanda needs to know some characteristics of the tape media. This is set in a
 tapetype section. The example amanda.conf, web page, and amanda-users mailing
 list archives have entries for most common media. Currently, all tapes should
 have the same characteristics. For instance, do not use both 60-meter and 90-
-meter DAT tapes since AMANDA must be told the smaller value, and larger tapes
+meter DAT tapes since Amanda must be told the smaller value, and larger tapes
 may be underutilized.
 If the media type is not listed and there are no references to it in the
 mailing list archives, go to the tape-src directory, make tapetype, mount a
@@ -743,21 +742,21 @@ may benefit from your effort.
 When using hardware compression, change the length value based on the estimated
 compression rate. This typically means multiplying by something between 1.5 and
 2.0.
-The length and filemark values are used by AMANDA only to plan the backup
-schedule. Once dumps start, AMANDA ignores the values and writes until it gets
+The length and filemark values are used by Amanda only to plan the backup
+schedule. Once dumps start, Amanda ignores the values and writes until it gets
 an error. It does not stop writing just because it reaches the tapetype length.
-AMANDA does not currently use the tapetype speed parameter.
+Amanda does not currently use the tapetype speed parameter.
 Once the tapetype definition is in amanda.conf, set the tapetype parameter to
 reference it.
 Without special hardware to mount tapes, such as a robot or stacker, either set
-the tapedev parameter to the no-rewind device name or set up the AMANDA chg-
+the tapedev parameter to the no-rewind device name or set up the Amanda chg-
 manual changer. The manual changer script prompts for tape mounts as needed.
-The prompts normally go to the terminal of the person running AMANDA, but the
+The prompts normally go to the terminal of the person running Amanda, but the
 changer may be configured to send requests via e-mail or to some other system
 logging mechanism.
 To configure the manual changer, set tapedev to the no-rewind tape device and
 set tpchanger to chg-manual. To send tape mount prompts someplace other than
-the terminal, which is necessary if AMANDA is run from a cron job, see the
+the terminal, which is necessary if Amanda is run from a cron job, see the
 request shell function comments in changer-src/chg-manual.sh.in.
 Another common tape changer is chg-multi. This script can drive stackers that
 advance to the next tape when the drive is unloaded or it can use multiple tape
@@ -809,10 +808,10 @@ comments in the script and insert calls to commands appropriate for the device.
 Make any source changes to the changer-src/chg-multi.sh.in file. That file is
 processed by ./configure to generate chg-multi.sh, which turns into chg-multi
 with make. If chg-multi.sh or chg-multi is altered, the changes will be lost
-the next time AMANDA is rebuilt.
+the next time Amanda is rebuilt.
 A third popular changer is chg-scsi. It can drive devices that have their own
 SCSI interface. An operating system kernel module may need to be installed to
-control such devices, like sst for Solaris, which is released with AMANDA, or
+control such devices, like sst for Solaris, which is released with Amanda, or
 chio, available for various systems. As with chg-multi, set the amanda.conf
 changerfile parameter to the changer configuration file path. There is a sample
 in example/chg-scsi.conf. The initial section has parameters common to the
@@ -858,8 +857,8 @@ entire changer:
 Test any changer setup with the amtape command. Make sure it can load a
 specific tape with the slot NNN suboption, eject the current tape with eject
 and advance to the next slot with slot next.
-Tapes must be pre-labeled with amlabel so AMANDA can verify the tape is one it
-should use. Run amlabel as the AMANDA user, not root. For instance:
+Tapes must be pre-labeled with amlabel so Amanda can verify the tape is one it
+should use. Run amlabel as the Amanda user, not root. For instance:
 
        
            # su amanda -c "amlabel Daily Daily-123 slot 123"
@@ -896,11 +895,11 @@ that value.
 The indexing facility generates a compressed catalogue of each dump image.
 These are useful for finding lost files and are the basis of the amrecover
 program. Long dump cycles or areas with many or very active files can cause the
-catalogues to use a lot of disk space. AMANDA automatically removes catalogues
+catalogues to use a lot of disk space. Amanda automatically removes catalogues
 for images that are no longer on tape.
 Create a file named disklist in the same directory as amanda.conf and either
 copy the file from example/disklist or start a new one. Make sure it is
-readable by the AMANDA user. Each line in disklist defines an area to be backed
+readable by the Amanda user. Each line in disklist defines an area to be backed
 up. The first field is the client host name (fully qualified names are
 recommended), the second is the area to be backed up on the client and the
 third is the dumptype. The area may be entered as a disk name, (sd0a), a device
@@ -910,22 +909,28 @@ To set up a Windows client, set the host name to the name of the Unix machine
 running SAMBA and the area to the Windows share name, such as //some-pc/C$.
 Note that Unix-style forward slashes are used instead of Windows-style backward
 slashes.
-Enable AMANDA access to the client from the tape server host (even if the
+Enable Amanda access to the client from the tape server host (even if the
 client is the tape server host itself) by editing .amandahosts (or .rhosts,
-depending on what was set with ./configure) in the AMANDA user home directory
-on the client. Enter the fully qualified tape server host name and AMANDA user,
-separated by a blank or tab. Make sure the file is owned by the AMANDA user and
+depending on what was set with ./configure) in the Amanda user home directory
+on the client. Enter the fully qualified tape server host name and Amanda user,
+separated by a blank or tab. Make sure the file is owned by the Amanda user and
 does not allow access to anyone other than the owner (e.g. mode 0600 or 0400).
 For Windows clients, put the share password in /etc/amandapass on the SAMBA
 host. The first field is the Windows share name, the second is the clear text
-password and the optional third field is the domain. Because this file contains
-clear text passwords, it should be carefully protected, owned by the AMANDA
-user and only allow user access. By default, AMANDA uses SAMBA user backup.
-This can be changed with --with-samba-user to ./configure.
+password and the optional third field is the domain.
+
+Note
+
+This info isn't correct anymore. Please refer to Backup_PC_hosts_using_Samba
+for details on this file.
+Because this file contains clear text passwords, it should be carefully
+protected, owned by the Amanda user and only allow user access. By default,
+Amanda uses SAMBA user backup. This can be changed with --with-samba-user to ./
+configure.
 
 Test and Debug Setup
 
-Test the setup with amcheck. As with all AMANDA commands, run it as the AMANDA
+Test the setup with amcheck. As with all Amanda commands, run it as the Amanda
 user, not root:
 
        
@@ -934,16 +939,16 @@ user, not root:
        
 
 Many errors reported by amcheck are described in docs/FAQ or the amcheck man
-page. The most common error reported to the AMANDA mailing lists is selfcheck
+page. The most common error reported to the Amanda mailing lists is selfcheck
 request timed out, meaning amcheck was not able to talk to amandad on the
 client. In addition to the ideas in docs/FAQ, here are some other things to
 try:
 
-* Are the AMANDA services listed properly in /etc/services or a YP/NIS map? The
-  C program in Figure 4-1 uses the same system call as AMANDA to look up
+* Are the Amanda services listed properly in /etc/services or a YP/NIS map? The
+  C program in Figure 4-1 uses the same system call as Amanda to look up
   entries:
 
-Example 16.1. A C Program to Check the AMANDA Service Numbers
+Example 18.1. A C Program to Check the Amanda Service Numbers
 
        
            #include <stdio.h>
@@ -1001,18 +1006,18 @@ Run it on both the tape server and client and make sure the port numbers match:
   amandad?
 * Was inetd sent a HUP signal after the configuration file was changed?
 * Are there system log messages from inetd about amanda or amandad? For
-  instance, inetd complains if it cannot look up the AMANDA services.
+  instance, inetd complains if it cannot look up the Amanda services.
 * Is /tmp/amanda/amandad/debug being updated?
 * Is the access time on the amandad executable (ls -lu) being updated? If not,
   inetd is probably not able to run it, possibly because of an error in the
   inetd configuration file or a permission problem.
-* Run the amandad program by hand as the AMANDA user on the client. It should
+* Run the amandad program by hand as the Amanda user on the client. It should
   sit for about 30 seconds, then terminate. Enter the full path exactly as it
   was given to inetd, perhaps by using copy/paste.
 
 Do not proceed until amcheck is happy with the configuration.
 For initial testing, set the record option to no in the global dumptype, but
-remember to set it back to yes when AMANDA goes into normal production. This
+remember to set it back to yes when Amanda goes into normal production. This
 parameter controls whether the dump program on the client updates its own
 database, such as /etc/dumpdates for vendor dump.
 To forget about an individual test run, use amrmtape to remove references to
@@ -1020,32 +1025,32 @@ the tapes used, then use amlabel to relabel them. To completely start over,
 remove the files or directories named in the infofile and indexdir parameters,
 the tapelist file named in the tapelist parameter, all amdump.* files in the
 configuration directory and all log.* files in the directory named by the
-logdir parameter. These files contain history information AMANDA needs between
+logdir parameter. These files contain history information Amanda needs between
 runs and also what is needed to find particular dump images for restores and
-should be protected when AMANDA goes into production.
+should be protected when Amanda goes into production.
 
 Operating Amanda
 
-Once configured, you will need to setup the automated use of AMANDA.
+Once configured, you will need to setup the automated use of Amanda.
 
 Run amdump
 
-The amdump script controls a normal AMANDA backup run. However, it's common to
+The amdump script controls a normal Amanda backup run. However, it's common to
 do site-specific things as well with a wrapper shell script around amdump.
 amdump is meant to run unattended from cron. See the operating system
-documentation for how to set up a cron task. Be sure it runs as the AMANDA
+documentation for how to set up a cron task. Be sure it runs as the Amanda
 user, not root or the installer.
 The amdump script does the following:
 
 * If a file named hold is in the configuration directory, amdump pauses until
   it goes away. This may be created and removed by hand to temporarily delay
-  AMANDA runs without having to change the cron task.
+  Amanda runs without having to change the cron task.
 * If it looks like another copy of amdump is running, or a previous run
   aborted, amdump logs an error and terminates. If an earlier run aborted,
   amcleanup must be run. An amcleanup step should be added to the tape server
   system boot sequence to handle crashes. No backups can be performed after an
   abort or crash until amcleanup is run.
-* The AMANDA planner program decides what areas to back up and at what level.
+* The Amanda planner program decides what areas to back up and at what level.
   It does this by connecting to each client and getting estimated sizes of a
   full dump, the same partial level that was done on the previous run and
   possibly the next partial level. All clients are done in parallel, but it can
@@ -1072,19 +1077,19 @@ The amdump script does the following:
 * The amtrmidx program is run to remove old catalogues if indexing has been
   used.
 
-There are several ways to determine which tapes AMANDA will need for a run. One
-is to look at the AMANDA e-mail report from the previous run. The tapes used
+There are several ways to determine which tapes Amanda will need for a run. One
+is to look at the Amanda e-mail report from the previous run. The tapes used
 during that run and those expected for the next run are listed. Another is to
 run amcheck during normal working hours. In addition to showing which tapes are
 needed, it makes sure things are set up properly so problems can be fixed
-before the real AMANDA run. A third is to use the tape suboption of amadmin.
-Without a tape changer, AMANDA expects the first tape to be mounted in the
+before the real Amanda run. A third is to use the tape suboption of amadmin.
+Without a tape changer, Amanda expects the first tape to be mounted in the
 drive when it starts. Automated tape changers should be able to locate the
 tapes. The chg-manual changer prompts for the tapes.
 
-Read AMANDA's Reports
+Read Amanda's Reports
 
-An AMANDA report has several sections:
+An Amanda report has several sections:
 
        
 
@@ -1115,7 +1120,7 @@ Problems found during the run are summarized in this section. In this example:
 * gurgi.cc.purdue.edu was down, so all its backups failed.
 * The /var/mail problem on pete.cc.purdue.edu and F$ problem on nt-
   test.cc.purdue.edu are detailed later.
-* The /master area on mace.cc.purdue.edu is new to AMANDA so a full dump is
+* The /master area on mace.cc.purdue.edu is new to Amanda so a full dump is
   required, but it would not fit in the available tape space for this run.
 
 
@@ -1194,11 +1199,11 @@ not fit on the first tape so was aborted and rerun on the next tape, as
 described further in the next section.
 The dump of F$ on nt-test.cc.purdue.edu failed due to a problem with the SAMBA
 configuration file. It's marked STRANGE because the line with a question mark
-does not match any of the regular expressions built into AMANDA. When dumping
+does not match any of the regular expressions built into Amanda. When dumping
 Windows clients via SAMBA, it's normal to get errors about busy files, such as
 PAGEFILE.SYS and the registry. Other arrangements should be made to get these
 safely backed up, such as a periodic task on the PC that creates a copy that
-will not be busy at the time AMANDA runs.
+will not be busy at the time Amanda runs.
 
        
            NOTES:
@@ -1292,19 +1297,19 @@ suboption of the amadmin command, amtoc can generate a tape table of contents
 after a run, or amreport can generate a printed listing. By default, client
 names are truncated on the right, area names on the left, to keep the report
 width under 80 character. This typically leaves the unique portions of both.
-Two log files are created during an AMANDA run. One is named amdump.NN, where
+Two log files are created during an Amanda run. One is named amdump.NN, where
 NN is a sequence number (1 is most recent, 2 is next most recent, etc), and is
 in the same directory as amanda.conf. The file contains detailed step by step
 information about the run and is used for statistics by amplot and amstatus,
 and for debugging. The other file is named log.YYYYMMDD.N where YYYYMMDD is the
-date of the AMANDA run and N is a sequence number in case more than one run is
+date of the Amanda run and N is a sequence number in case more than one run is
 made on the same day (0 for the first run, 1 for the second, etc). This file is
 in the directory specified by the logdir amanda.conf parameter. It contains a
 summary of the run and is the basis for the e-mail report. In fact, amreport
 may be run by hand and given an old file to regenerate a report.
 Old amdump.NN files are removed by the amdump script. Old log.YYYYMMDD.N files
 are not automatically removed and should be cleared out periodically by hand.
-Keeping a full tape cycle is a good idea. If the tape cycle is 40 and AMANDA is
+Keeping a full tape cycle is a good idea. If the tape cycle is 40 and Amanda is
 run once a day, the following command would do the job:
 
        
@@ -1323,13 +1328,13 @@ While amdump is running, amstatus can track how far along it is. amstatus may
 also be used afterward to generate statistics on how many dumpers were used,
 what held things up and so on.
 When a tape error happens on the last tape allowed in a run (as set by
-runtapes), AMANDA continues to do backups into the holding disks. This is
+runtapes), Amanda continues to do backups into the holding disks. This is
 called degraded mode. By default, full dumps are not done and any that were
 scheduled have a partial done instead. A portion of the holding disk area may
 be allocated to do full dumps during degraded mode by reducing the value of the
 parameter reserve in amanda.conf below 100%.
 A tape server crash may also leave images in the holding disks. Run amflush, as
-the AMANDA user, to flush images in the holding disk to the next tape after
+the Amanda user, to flush images in the holding disk to the next tape after
 correcting any problems. It goes through the same tape request mechanism as
 amdump. If more than one set of dumps are in the holding disk area, amflush
 prompts to choose one to write or to write them all. amflush generates an e-
@@ -1342,14 +1347,14 @@ happened and the tape may need to be replaced the next time through the tape
 cycle.
 To swap out a partially bad tape, wait until it is about to be used again so
 any valid images can still be retrieved. Then swap the tapes, run amrmtape on
-the old tape and run amlabel on the replacement so it has a proper AMANDA
+the old tape and run amlabel on the replacement so it has a proper Amanda
 label.
 If a tape is marked to not be reused with the no-reuse suboption of amadmin,
-such as one that has been removed or is failing, AMANDA may want a freshly
+such as one that has been removed or is failing, Amanda may want a freshly
 labeled tape on the next run to get the number of tapes back up to the full
 tape cycle.
-If a tape goes completely bad, use amrmtape to make AMANDA forget about it. As
-with marking a tape no-reuse, this may reduce the number of tapes AMANDA has in
+If a tape goes completely bad, use amrmtape to make Amanda forget about it. As
+with marking a tape no-reuse, this may reduce the number of tapes Amanda has in
 use below the tape cycle and it may request a newly labeled tape on the next
 run.
 
@@ -1363,7 +1368,7 @@ Adding Tapes at a Particular Position in the Cycle
   make them the same for Daily-099 and Daily-100.
 * Update the tapecycle amanda.conf parameter if new tapes are being added.
 
-These steps let AMANDA know about all tapes, including those that do not have
+These steps let Amanda know about all tapes, including those that do not have
 data yet. When the cycle gets to the last old tape (Daily-099), the next tape
 used will be the first new one (Daily-100). A new option is planned for amlabel
 to do these steps automatically.
@@ -1376,21 +1381,21 @@ possibilities. To redo a few areas that failed during the normal run, edit the
 disklist file by hand to comment out all the other entries, run amdump, then
 restore the disklist file.
 Use the force suboption of amadmin to schedule a full dump of an area on the
-next run. Run this as the AMANDA user, not root. AMANDA automatically detects
+next run. Run this as the Amanda user, not root. Amanda automatically detects
 new disklist entries and schedules an initial full dump. But for areas that go
 through a major change, such as an operating system upgrade or full restore,
-force AMANDA to do a full dump to get things back into sync.
-AMANDA does not automatically notice new client areas, so keep the disklist in
-sync by hand. AMANDA usually notices areas that are removed and reports an
+force Amanda to do a full dump to get things back into sync.
+Amanda does not automatically notice new client areas, so keep the disklist in
+sync by hand. Amanda usually notices areas that are removed and reports an
 error as a reminder to remove the entry from the disklist. Use the delete
-suboption of amadmin (as the AMANDA user) to make AMANDA completely forget
+suboption of amadmin (as the Amanda user) to make Amanda completely forget
 about an area, but wait until the information is not needed for restores. This
 does not remove the entry from the disklist file \14 that must be done by hand.
-Non\14AMANDA backups may still be done with AMANDA installed, but do not let the
+Non\14Amanda backups may still be done with Amanda installed, but do not let the
 client dump program update its database. For vendor dump programs, this usually
 means not using the u flag, or saving and restoring /etc/dumpdates. For GNU-tar
 it means the --listed-incremental flag (if used) should not point to the same
-file AMANDA uses.
+file Amanda uses.
 As with all backup systems, verify the resulting tapes, if not each one then at
 least periodically or by random sample. The amverify script does a reasonably
 good job of making sure tapes are readable and images are valid. For GNU-tar
@@ -1401,19 +1406,19 @@ vendor dump images from other operating systems, amverify can tell if the image
 is readable from tape but not whether it is valid.
 Tape drives are notorious for being able to read only what they wrote, so run
 amverify on another machine with a different drive, if possible, so an
-alternate is available if the primary drive fails. Make a copy of the AMANDA
+alternate is available if the primary drive fails. Make a copy of the Amanda
 configuration directory on the other machine to be able to run amverify. This
-copy is also a good way to have a backup of the AMANDA configuration and
+copy is also a good way to have a backup of the Amanda configuration and
 database in case the tape server machine needs to be recovered.
 
-Advanced AMANDA Configuration
+Advanced Amanda Configuration
 
-Once you have AMANDA running for a while, you may choose to do some additional
+Once you have Amanda running for a while, you may choose to do some additional
 advanced configuration.
 
 Adjust the Backup Cycle
 
-Several dumptype parameters control the backup level AMANDA picks for a run:
+Several dumptype parameters control the backup level Amanda picks for a run:
 
 
   dumpcycle
@@ -1443,7 +1448,7 @@ dumptype to 0:
        
 
        
-To run full dumps by hand outside of AMANDA (perhaps they are too large for the
+To run full dumps by hand outside of Amanda (perhaps they are too large for the
 normal tape capacity, or need special processing), create a new dumptype and
 set strategy to incronly:
 
@@ -1455,7 +1460,7 @@ set strategy to incronly:
        
        
 
-Tell AMANDA when a full dump of the area has been done with the force suboption
+Tell Amanda when a full dump of the area has been done with the force suboption
 of amadmin. Take care to do full dumps often enough that the tape cycle does
 not wrap around and overwrite the last good non-full backups.
 To never do full dumps (such as an area easily regenerated from vendor media),
@@ -1471,18 +1476,18 @@ create a new dumptype and set strategy to nofull:
 
 Only level 1 backups of such areas are done, so wrapping around the tape cycle
 is not a problem.
-To do periodic archival full dumps, create a new AMANDA configuration with its
+To do periodic archival full dumps, create a new Amanda configuration with its
 own set of tapes but the same disklist as the normal configuration (e.g.
 symlink them together). Copy amanda.conf, setting all dumpcycle values to 0 and
 record to no, e.g. in the global dumptype. If a changer is used, set runtapes
 very high so tape capacity is not a planning restriction. Disable the normal
-AMANDA run, or set the hold file as described in "Operating AMANDA", so AMANDA
+Amanda run, or set the hold file as described in "Operating Amanda", so Amanda
 does not try to process the same client from two configurations at the same
 time.
 
 Adjust Parallelism
 
-AMANDA starts several dumper processes and keeps as many as possible running at
+Amanda starts several dumper processes and keeps as many as possible running at
 once. The following options control their activity:
 
 
@@ -1506,16 +1511,16 @@ tape server has multiple network connections, an amanda.conf interface section
 may be set up for each one and clients allocated to a particular interface with
 field five of the disklist. Individual interfaces take precedence over the
 general netusage bandwidth limit and follow the same guidelines described above
-in "Configuring AMANDA": the limit is imposed when deciding whether to start a
-dump, but once a dump starts, AMANDA lets underlying network components do any
+in "Configuring Amanda": the limit is imposed when deciding whether to start a
+dump, but once a dump starts, Amanda lets underlying network components do any
 throttling.
-Individual AMANDA interface definitions do not control which physical
+Individual Amanda interface definitions do not control which physical
 connection is used. That is left up to the operating system network software.
-While it's common to give an AMANDA interface definition the same name as a
+While it's common to give an Amanda interface definition the same name as a
 physical connection, e.g. le0, it might be better to use logical names such as
 back-door-atm to avoid confusion.
 The starttime dumptype parameter delays a backup some amount of time after
-AMANDA is started. The value is entered as HHMM, so 230, for instance, would
+Amanda is started. The value is entered as HHMM, so 230, for instance, would
 wait 2.5 hours. This may be used to delay backups of some areas until they are
 known to be idle.
 
@@ -1586,13 +1591,13 @@ Other common status indicators are:
   start-wait
       All remaining dumps are delayed until a specific time of day.
 
-If the tape server machine has multiple tape drives, more than one AMANDA
+If the tape server machine has multiple tape drives, more than one Amanda
 configuration may run at the same time. Clients and holding disks should be
 assigned to only one configuration, however.
-AMANDA waits a fixed amount of time for a client to respond with dump size
+Amanda waits a fixed amount of time for a client to respond with dump size
 estimates. The default is five minutes per area on the client. For instance, if
-a client has four areas to back up (entries in disklist), AMANDA waits at most
-20 minutes for the estimates. During dumping, AMANDA aborts a dump if the
+a client has four areas to back up (entries in disklist), Amanda waits at most
+20 minutes for the estimates. During dumping, Amanda aborts a dump if the
 client stops sending data for 30 minutes. Various conditions, such as slow
 clients, which dump program is used and characteristics of the area, may cause
 timeouts. The values may be changed with the amanda.conf etimeout parameter for
@@ -1635,19 +1640,19 @@ contents are omitted. For instance:
       their contents, but dump the OLD directory entry itself.
 
 
-Restoring with AMANDA
+Restoring with Amanda
 
 Remember that no one cares if you can back up ?only if you can restore.
 
 Configuring and Using amrecover
 
-One way to restore items with AMANDA is with amrecover on the client. Before
-amrecover can work, AMANDA must run with the dumptype index parameter set to
+One way to restore items with Amanda is with amrecover on the client. Before
+amrecover can work, Amanda must run with the dumptype index parameter set to
 yes and the amindexd and amidxtaped services must be installed and enabled to
 inetd, usually on the tape server machine (the default build sequence installs
-them). Also, add the client to .amandahosts (or .rhosts) for the AMANDA user on
+them). Also, add the client to .amandahosts (or .rhosts) for the Amanda user on
 the server machine. Since amrecover must run as root on the client, the entry
-must list root as the remote user, not the AMANDA user. amrecover should not be
+must list root as the remote user, not the Amanda user. amrecover should not be
 made setuid-root because it would open up catalogues of the entire system to
 everyone.
 For this example, user jj has requested two files, both named molecule.dat, in
@@ -1662,7 +1667,7 @@ the area and start amrecover:
          # amrecover Daily
          AMRECOVER Version 2.4.1p1.
          Contacting server on amanda.cc.purdue.edu ...
-         220 amanda AMANDA index server (2.4.1p1) ready.
+         220 amanda Amanda index server (2.4.1p1) ready.
          200 Access OK
          Setting restore date to       today (1999-01-18)
          200 Working date set to 1999-01-18.
@@ -1779,7 +1784,7 @@ The compressed size values here may be ignored because this particular
 configuration uses hardware compression so no software compression data are
 available.
 A third way to know what tape has an image is to generate a tape table of
-contents with amtoc after each AMANDA run:
+contents with amtoc after each Amanda run:
 
        
            #  partition                        lvl  size[Kb]  method
@@ -1796,13 +1801,13 @@ contents with amtoc after each AMANDA run:
 A printed report similar to the amtoc output may be automatically generated by
 amreport for each run with the lbl-templ tapetype parameter in amanda.conf
 using the example/3hole.ps template.
-The find and info suboptions to amadmin need the AMANDA log files and database.
+The find and info suboptions to amadmin need the Amanda log files and database.
 These are not usually large amounts of information and a copy should be pushed
-after each amdump run to an alternate machine that also has the AMANDA tape
+after each amdump run to an alternate machine that also has the Amanda tape
 server software installed so they are available if the primary tape server
 machine dies. Tools like rdist (ftp://usc.edu/pub/rdist/) or rsync (ftp://
 samba.anu.edu.au/pub/rsync/) are useful.
-If AMANDA was built using --with-db=text (the default), the database is stored
+If Amanda was built using --with-db=text (the default), the database is stored
 in a set of text files under the directory listed in the infofile amanda.conf
 parameter. Here is the file that matches the above info amadmin output:
 
@@ -1922,13 +1927,13 @@ arbitrary size chunks of data available through a pipeline:
        
 
 
-Restoring Without AMANDA
+Restoring Without Amanda
 
-The AMANDA tape format is deliberately simple and restoring data can be done
-without any AMANDA tools if necessary. The first tape file is a volume label
+The Amanda tape format is deliberately simple and restoring data can be done
+without any Amanda tools if necessary. The first tape file is a volume label
 with the tape VSN and date it was written. It is not in ANSI VOL1 format, but
 is plain text. Each file after that contains one image using 32 KByte blocks.
-The first block is an AMANDA header with client, area and options used to
+The first block is an Amanda header with client, area and options used to
 create the image. As with the volume label, the header is not in ANSI format,
 but is plain text. The image follows, starting at the next tape block, until
 end of file.
@@ -1942,7 +1947,7 @@ available, position the tape to the image, then use dd to read it:
        
        
 
-The skip=1 option tells dd to skip over the AMANDA file header. Without the of=
+The skip=1 option tells dd to skip over the Amanda file header. Without the of=
 option, dd writes the image to standard output, which can be piped to the
 decompression program, if needed, and then to the client restore program.
 Since the image header is text, it may be viewed with:
@@ -1961,7 +1966,7 @@ vendor ufsdump program:
 
        
        
-             AMANDA: FILE 19981206 pete.cc.purdue.edu / lev 1
+             Amanda: FILE 19981206 pete.cc.purdue.edu / lev 1
              comp N program /usr/sbin/ufsdump
        
        
@@ -1979,5 +1984,5 @@ the principles and techniques are familiar when disaster strikes.
 -------------------------------------------------------------------------------
 
 Prev                           Up                     Next
-Part IV. Various Information  Home  Chapter 17. AMANDA FAQ
+Part IV. Various Information  Home  Chapter 19. Amanda FAQ
 
index 20e1d197ddc889e0093ee0777570a08066af0bf9..72ade71f042b6b1762c453c0383a0ec304450245 100644 (file)
@@ -5,42 +5,42 @@ Prev                    Next
 -------------------------------------------------------------------------------
 
 
-Various Information
+Part IV. Various Information
 
 
 
-Additional information about AMANDA
+Additional information about Amanda
 
-Here you find various other documents like the AMANDA FAQ, the Top Ten
-Questions and the AMANDA-Wishlist. You can also find the last AMANDA-Survey in
+Here you find various other documents like the Amanda FAQ, the Top Ten
+Questions and the Amanda-Wishlist. You can also find the last Amanda-Survey in
 here (although it still needs formatting ... sorry, Jon ...). The latest
-addition is the "famous" AMANDA-chapter by John R. Jackson.
+addition is the "famous" Amanda-chapter by John R. Jackson.
 Table of Contents
 
 
-  16._Using_AMANDA
+  18._Using_Amanda
 
 
         An_Introduction
 
-        AMANDA_Features
+        Amanda_Features
 
-        Future_Capabilities_of_AMANDA
+        Future_Capabilities_of_Amanda
 
-        AMANDA_Resources
+        Amanda_Resources
 
-        Installing_AMANDA
+        Installing_Amanda
 
 
               Install_Related_Packages
 
               Perform_Preliminary_Setup
 
-              Configure_the_AMANDA_Build
+              Configure_the_Amanda_Build
 
-              Build_and_Install_AMANDA
+              Build_and_Install_Amanda
 
-              Configuring_AMANDA
+              Configuring_Amanda
 
               Decide_on_a_Tape_Server
 
@@ -68,7 +68,7 @@ Table of Contents
 
               Run_amdump
 
-              Read_AMANDA's_Reports
+              Read_Amanda's_Reports
 
               Monitor_Tape_and_Holding_Disk_Status
 
@@ -77,7 +77,7 @@ Table of Contents
               Miscellanous_Operational_Notes
 
 
-        Advanced_AMANDA_Configuration
+        Advanced_Amanda_Configuration
 
 
               Adjust_the_Backup_Cycle
@@ -89,20 +89,20 @@ Table of Contents
               Excluding_Files
 
 
-        Restoring_with_AMANDA
+        Restoring_with_Amanda
 
 
               Configuring_and_Using_amrecover
 
               Using_amrestore
 
-              Restoring_Without_AMANDA
+              Restoring_Without_Amanda
 
 
 
-  17._AMANDA_FAQ
+  19._Amanda_FAQ
 
-  18._Collection_of_the_top_ten_AMANDA_questions._And_answers.
+  20._Collection_of_the_top_ten_Amanda_questions._And_answers.
 
 
         Reason_for_starting_this_list.
@@ -132,12 +132,11 @@ Table of Contents
         ...
 
 
-  19._AMANDA_WISHLIST
-
-  20._AMANDA_Survey_Results
+  21._Amanda_WISHLIST
 
 -------------------------------------------------------------------------------
 
-Prev                               Up                       Next
-Chapter 15. How to use a wrapper  Home  Chapter 16. Using AMANDA
+Prev                                                                 Next
+Chapter 17. How to use different auth with Home  Chapter 18. Using Amanda
+Amanda 
 
index 517b5d2f6aa1c8fa8bf335d1f530028efa251275..b23ed3ed16624114bbb40b9d64c20c8909db384b 100644 (file)
@@ -1,10 +1,10 @@
 
-         Chapter 26. Virtual Tape API
+         Chapter 27. Virtual Tape API
 Prev  Part V. Technical Background  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 26. Virtual Tape API
+Chapter 27. Virtual Tape API
 
 
 Stefan G. Weichinger
@@ -17,7 +17,7 @@ Note
 
 Refer to http://www.amanda.org/docs/vtape-api.html for the current version of
 this document.
-The upper level AMANDA code (including some of the other tape_xxx routines)
+The upper level Amanda code (including some of the other tape_xxx routines)
 calls the following routines which implement a virtual tape table:
 
 * int tape_access(filename, mode) Acts like access(2) on possibly virtual
@@ -61,5 +61,5 @@ but we hope to add a "rmt" (remote tape client), and possibly "dvd" types soon.
 -------------------------------------------------------------------------------
 
 Prev                              Up                                     Next
-Chapter 25. AMANDA Security API  Home  Chapter 27. Using Kerberos with AMANDA
+Chapter 26. Amanda Security API  Home  Chapter 28. Using Kerberos with Amanda
 
index 6aee12ce21d2308e0bde95bd19825832d599f028..49c018adc4a80e209fdd721b2a60dc962a5f811b 100644 (file)
@@ -1,13 +1,13 @@
 
-      Chapter 30. What once was new
+      Chapter 31. What once was new
 Prev  Part VI. Historical files  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 30. What once was new
+Chapter 31. What once was new
 
 
-AMANDA Core Team
+Amanda Core Team
 
 Original text
 AMANDA Core Team
@@ -20,7 +20,7 @@ AMANDA Core Team
 Table of Contents
 
 
-  What's_new_in_AMANDA_2.3
+  What's_new_in_Amanda_2.3
 
 
         Indexing_backups_for_easier_restore
@@ -40,7 +40,7 @@ Table of Contents
         amadmin_import/export
 
 
-  What's_new_in_AMANDA_2.2
+  What's_new_in_Amanda_2.2
 
 
         Client_side_setup_has_changed
@@ -82,14 +82,14 @@ Note
 Refer to http://www.amanda.org/docs/whatwasnew.html for the current version of
 this document.
 
- What's new in AMANDA 2.3
+ What's new in Amanda 2.3
 
-This document contains notes on new features in AMANDA 2.3 that may not yet be
+This document contains notes on new features in Amanda 2.3 that may not yet be
 fully documented elsewhere.
 
  Indexing backups for easier restore
 
-Read more about this in the file named Indexing_with_AMANDA.
+Read more about this in the file named Indexing_with_Amanda.
 
  Samba Support
 
@@ -97,7 +97,7 @@ Read more about this in the file named Backup_PC_hosts_using_Samba.
 
  GnuTar Support
 
-AMANDA now supports dumps made via GnuTAR. To use this, set your dumptypes set
+Amanda now supports dumps made via GnuTAR. To use this, set your dumptypes set
 the program name to "GNUTAR":
 
   dumptype tar-client {
@@ -107,13 +107,13 @@ the program name to "GNUTAR":
        
 
 Since Gnu TAR does not maintain a dumpdates file itself, nor give an estimate
-of backup size, those need to be done within AMANDA. AMANDA maintains an /etc/
+of backup size, those need to be done within Amanda. Amanda maintains an /etc/
 amandates file to track the backup dates analogously to how dump does it.
 NOTE: if your /etc directory is not writable by your dumpuser, you'll have to
 create the empty file initially by hand, and make it writable by your dumpuser
 ala /etc/dumpdates.
 NOTE: Since tar traverses the directory hierarchy and reads files as a regular
-user would, it must run as root. The two new AMANDA programs calcsize and
+user would, it must run as root. The two new Amanda programs calcsize and
 runtar therefore must be installed setuid root. I've made them as simple as
 possible to to avoid potential security holes.
 
@@ -138,7 +138,7 @@ If the "maxdumps" parameter isn't given in the dumptypes, the default is used.
 The idea is that maxdumps is set roughly proportional to the speed of the
 client host. You probably wont get much benefit from setting it very high, but
 all but the slowest hosts should be able to handle a maxdumps of at least 2.
-AMANDA doesn't really have any per-host parameters, just per-disk, so the per-
+Amanda doesn't really have any per-host parameters, just per-disk, so the per-
 client-host maxdumps is taken from the last disk listed for that host.
 Just to make things more complicated, I've added the ability to specify a
 "spindle number" for each filesystem in the disklist file. For example:
@@ -155,7 +155,7 @@ Just to make things more complicated, I've added the ability to specify a
 The spindle number represents the disk number, eg every filesystem on sd0 can
 get a spindle number of 0, everything on sd1 gets spindle 1, etc (but there's
 no enforced requirement that there be a match with the underlying hardware
-situation). Now, even with a high maxdumps, AMANDA will refrain from scheduling
+situation). Now, even with a high maxdumps, Amanda will refrain from scheduling
 two disks on the same spindle at the same time, which would just slow them both
 down by adding a lot of seeks.
 The default spindle if you don't specify one is -1, which is defined to be a
@@ -191,7 +191,7 @@ filemark.
  Bottleneck determination
 
 I've made some experimental changes to driver to determine what the bottleneck
-is at any time. Since AMANDA tries to do many things at once, it's hard to
+is at any time. Since Amanda tries to do many things at once, it's hard to
 pinpoint a single bottleneck, but I "think" I've got it down well enough to say
 something useful. For now it just outputs the current bottleneck as part of its
 "driver: state" line in the debug output, but once I'm comfortable with its
@@ -217,47 +217,47 @@ going to long-long or some other non-portable type for the size.
  amadmin import/export
 
 amadmin now has "import" and "export" commands, to convert the curinfo database
-to/from text format, for: moving an AMANDA server to a different arch,
+to/from text format, for: moving an Amanda server to a different arch,
 compressing the database after deleting lots of hosts, or editing one or all
 entries in batch form or via a script.
 
- What's new in AMANDA 2.2
+ What's new in Amanda 2.2
 
 
 Note
 
 Here's the old 2.2.x stuff from this file. I'm pretty sure most of this is in
 the mainline documentation already.
-This document contains notes on new features in AMANDA 2.2 that may not yet be
+This document contains notes on new features in Amanda 2.2 that may not yet be
 fully documented elsewhere.
 
  Client side setup has changed
 
 The new /etc/services lines are:
 
-  amanda       10080/udp               # bsd security AMANDA daemon
-  kamanda      10081/udp               # krb4 security AMANDA daemon
+  amanda       10080/udp               # bsd security Amanda daemon
+  kamanda      10081/udp               # krb4 security Amanda daemon
 
 The new /etc/inetd.conf lines are:
 
   amanda  dgram udp wait /usr/local/libexec/amanda/amandad amandad
   kamanda dgram udp wait /usr/local/libexec/amanda/amandad amandad -krb4
 
-(you don't need the vanilla AMANDA lines if you are using kerberos for
+(you don't need the vanilla Amanda lines if you are using kerberos for
 everything, and vice-versa)
 
  Version suffixes on executables
 
 The new USE_VERSION_SUFFIXES define in options.h controls whether to install
-the AMANDA executables with the version number attached to the name, eg
+the Amanda executables with the version number attached to the name, eg
 "amdump-2.2.1". I recommend that you leave this defined, since this allows
-multiple versions to co-exist - particularly important while AMANDA 2.2 is
+multiple versions to co-exist - particularly important while Amanda 2.2 is
 under development. You can always symlink the names without the version suffix
 to the version you want to be your "production" version.
 
  Kerberos
 
-Read the comments in Using_Kerberos_with_AMANDA for how to configure the
+Read the comments in Using_Kerberos_with_Amanda for how to configure the
 kerberos version. With KRB4_SECURITY defined, there are two new dumptype
 options:
 
@@ -284,15 +284,15 @@ Note
 
 sgw: This is OLD syntax now ...
 
-       diskdir "/AMANDA2/AMANDA/work"  # where the holding disk is
+       diskdir "/Amanda2/Amanda/work"  # where the holding disk is
        disksize 880 MB                 # how much space can we use on it
 
-       diskdir "/dumps/AMANDA/work"    # a second holding disk!
+       diskdir "/dumps/Amanda/work"    # a second holding disk!
        disksize 1500 MB
        
 
-AMANDA will load-balance between the two disks as long as there is space.
-AMANDA now also actually stats files to get a more accurate view of available
+Amanda will load-balance between the two disks as long as there is space.
+Amanda now also actually stats files to get a more accurate view of available
 and used disk space while running.
 
  Remote self-checks
@@ -309,9 +309,9 @@ System V shared memory primitives are no longer required on the server side, if
 your system has a version of mmap() that will allocate anonymous memory. BSD
 4.4 systems (and OSF/1) have an explicitly anonymous mmap() type, but others
 (like SunOS) support the trick of mmap'ing /dev/zero for the same effect.
-AMANDA should work with both varieties.
+Amanda should work with both varieties.
 Defined HAVE_SYSVSHM or HAVE_MMAP (or both) in config.h. If you have both,
-SYSVSHM is selected (simply because this code in AMANDA is more mature, not
+SYSVSHM is selected (simply because this code in Amanda is more mature, not
 because the sysv stuff is better).
 
  gzip support
@@ -339,20 +339,20 @@ For example:
 
  Initial tape-changer support included
 
-A new amanda.conf parameter, tpchanger, controls whether AMANDA communicates
+A new amanda.conf parameter, tpchanger, controls whether Amanda communicates
 with a tape changer program to load tapes rather than just opening the tapedev
 itself. The tpchanger parameter is a string which specifies the name of a
-program that follows the API specified in AMANDA_Tape_Changer_Support. Read
+program that follows the API specified in Amanda_Tape_Changer_Support. Read
 that for more information.
 
  Generic tape changer wrapper script
 
-An initial tape-changer glue script, chg-generic.sh, implements the AMANDA
+An initial tape-changer glue script, chg-generic.sh, implements the Amanda
 changer API using an array of tape devices to simulate a tape changer, with the
 device names specified via a conf file. This script can be quickly customized
 by inserting calls tape-changer-specific programs at appropriate places, making
 support for new changers painless. If you know what command to execute to get
-your changer to put a particular tape in the drive, you can get AMANDA to
+your changer to put a particular tape in the drive, you can get Amanda to
 support your changer.
 The generic script works as-is for sites that want to cascade between two or
 more tape drives hooked directly up to the tape server host. It also should
@@ -364,12 +364,12 @@ documented sample.
 
  New command amtape
 
-amtape is the user front-end to the AMANDA tape changer support facilities. The
+amtape is the user front-end to the Amanda tape changer support facilities. The
 operators can use amtape to load tapes for restores, position the changer, see
-what AMANDA tapes are loaded in the tape rack, and see which tape would be
+what Amanda tapes are loaded in the tape rack, and see which tape would be
 picked by taper for the next amdump run.
 No man page yet, but running amtape with no arguments gives a detailed usage
-statement. See AMANDA_Tape_Changer_Support for more info.
+statement. See Amanda_Tape_Changer_Support for more info.
 
 Note
 
@@ -378,14 +378,14 @@ sgw: The manpage exists now.
  Changer support added to command amlabel
 
 The amlabel command now takes an optional slot argument for labeling particular
-tapes in the tape rack. See AMANDA_Tape_Changer_Support for more info.
+tapes in the tape rack. See Amanda_Tape_Changer_Support for more info.
 
  Tape changer support improved
 
-The specs in AMANDA_Tape_Changer_Support have been updated, and the code
-changed to match. The major difference is that AMANDA no longer assumes slots
+The specs in Amanda_Tape_Changer_Support have been updated, and the code
+changed to match. The major difference is that Amanda no longer assumes slots
 in the tape rack are numbered from 0 to N-1. They can be numbered or labeled in
-any manner that suits your tape-changer, AMANDA doesn't care what the actual
+any manner that suits your tape-changer, Amanda doesn't care what the actual
 slot names are. Also added "first" and "last" slot specifiers, and an -eject
 command.
 The chg-generic.sh tape changer script now has new "firstslot", "lastslot", and
@@ -397,7 +397,7 @@ generic.conf for more info.
  A few words about multi-tape runs
 
 I'm still holding back on support for multiple tapes in one run. I'm not yet
-completely happy with how AMANDA should handle splitting dumps across tapes (eg
+completely happy with how Amanda should handle splitting dumps across tapes (eg
 when end-of-tape is encountered in the middle of a long dump). For example,
 this creates issues for amrestore, which currently doesn't know about
 configurations or tape changers --- on purpose, so that you can do restores on
@@ -405,7 +405,7 @@ any machine with a tape drive, not just the server, and so that you can recover
 with no online databases present.
 However, because the current snapshot DOES support tape changers, and multiple
 runs in one day, some of the benefit of multi-tape runs can be had by simply
-running AMANDA several times in a row. Eg, to fill three tapes per night, you
+running Amanda several times in a row. Eg, to fill three tapes per night, you
 can put
 
   amdump <conf>; amdump <conf>; amdump <conf>
@@ -418,7 +418,7 @@ should work.
  Big planner changes
 
 The support for writing to multiple tapes in one run is almost finished now.
-See Multitape_support_in_AMANDA_2.2 for an outline of the design. The planner
+See Multitape_support_in_Amanda_2.2 for an outline of the design. The planner
 support for this is included in this snapshot, but the taper part is not.
 There is a new amanda.conf variable "runtapes" which specifies the number of
 tapes to use on each amdump run. For now this should stay at 1, the default.
@@ -428,7 +428,7 @@ but still work for now. "maxcycle" was never used, and "mincycle" is now called
 There are two visible differences in the new planner: First, planner now thinks
 in real-time, rather than by the number of tapes as before. That is, a
 filesystem is due for a full backup once every <dumpcycle> days, regardless of
-how many times AMANDA is run in that interval. As a consequence, you need to
+how many times Amanda is run in that interval. As a consequence, you need to
 make sure the dumpcycle variable marks real time instead of the number of days.
 For example, previously "mincycle 10" worked for a two week cycle if you ran
 amdump only on weekdays (for 10 runs in a cycle). Now a two week cycle must be
@@ -444,25 +444,25 @@ brings a machine or disk down for some days.
 
  Level-0 dumps allowed with no tape
 
-If there is no tape present (or the tape drive fails during dumping), AMANDA
+If there is no tape present (or the tape drive fails during dumping), Amanda
 switches to degraded mode. In degraded mode, level-0 dumps are not allowed.
 This can be a pain for unattended sites over the weekend (especially when there
-is a large holding disk that can hold any necessary dumps). AMANDA now supports
-a new configuration file directive, "reserve". This tells AMANDA to reserve
+is a large holding disk that can hold any necessary dumps). Amanda now supports
+a new configuration file directive, "reserve". This tells Amanda to reserve
 that percentage of total holding disk space for degraded mode dumps. Example:
 your total holding disk space adds up to 8.4GB. If you specify a reserve of 50,
 4.2GB (50%) of the holding disk space will be allowed to be used for regular
-dumps, but if that limit is hit, AMANDA will switch to degraded dumps. For
+dumps, but if that limit is hit, Amanda will switch to degraded dumps. For
 backward compatibility, if no 'reserve' keyword is present, 100 will be assumed
 (e.g. never do full dumps if degraded mode is in effect).
 
 Note
 
 This percentage applies from run to run, so, as in the previous example, when
-AMANDA runs the next day, if there is 3.8GB left on the holding disk, 1.9GB
+Amanda runs the next day, if there is 3.8GB left on the holding disk, 1.9GB
 will be reserved for degraded mode dumps (e.g. the percentage keeps sliding).
 -------------------------------------------------------------------------------
 
 Prev                         Up                                          Next
-Chapter 29. Upgrade Issues  Home  Chapter 31. Multitape support in AMANDA 2.2
+Chapter 30. Upgrade Issues  Home  Chapter 32. Multitape support in Amanda 2.2
 
index 245efd56d1d28f5d3bac9b8e2f19543a69e2b8d4..3905640d944ab000992435fd508a65eaabbaf24e 100644 (file)
@@ -1,13 +1,13 @@
 
-         Chapter 19. AMANDA WISHLIST
+         Chapter 21. Amanda WISHLIST
 Prev  Part IV. Various Information  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 19. AMANDA WISHLIST
+Chapter 21. Amanda WISHLIST
 
 
-AMANDA Core Team
+Amanda Core Team
 
 Original text
 AMANDA Core Team
@@ -38,11 +38,11 @@ You may find more up-to-date information at http://www.amanda.org/ongoing.php.
 If you have any ideas about any of the following, please send an e-mail note to
 mailto://amanda-users@amanda.org or mailto://amanda-hackers@amanda.org.
 Jean-Louis Martineau, Stefan G. Weichinger,
-AMANDA Core Team
+Amanda Core Team
 Oct. 2004.
 
 * Samba: Ports to non-Unix platforms, specifically Macs and PCs. The hooks are
-  in the AMANDA protocol to support non-dump backup programs, but no-one has
+  in the Amanda protocol to support non-dump backup programs, but no-one has
   volunteered to implement the client side. sgw: Mac OS X is able to run the
   client, so only the PC is left, and I suggest that we should go the SAMBA-
   way, I think. Samba is working well, is documented and developed further, so
@@ -56,14 +56,14 @@ Oct. 2004.
 
 
 * Samba: multiple exclusion-patterns. Since Samba 3.0.3 smbclient supports the
-  usage of multiple exclude-patterns. This would enable AMANDA to exclude more
+  usage of multiple exclude-patterns. This would enable Amanda to exclude more
   than one pattern per SMB-share, allowing to exclude pagefile.sys AND the
   registry-files, for example.
 
 
-* Instead of hard-coding the interface with tape devices in AMANDA, there
+* Instead of hard-coding the interface with tape devices in Amanda, there
   should be a higher level interface that allowed different storage devices to
-  be used. AMANDA should also be able to retain backups in disk, even after
+  be used. Amanda should also be able to retain backups in disk, even after
   they are taped, for faster restore of recently backed up data. It should also
   be possible to store a single backup in multiple tapes, for redundancy.
 
@@ -73,12 +73,8 @@ Oct. 2004.
   periodicaly if the dumper is still alive (in case the dumper hang).
 
 
-* image span / multiple tape. John Stange <building@nap.edu> is working on it.
-  His patch will very likely go into a development-branch.
-
-
 * retry failed backups in a single run. If backup fails because of active
-  filesystems or lack of memory, AMANDA could throw the failed backup away and
+  filesystems or lack of memory, Amanda could throw the failed backup away and
   run it again, instead of trying it again in the next run only.
 
 
@@ -87,11 +83,11 @@ Oct. 2004.
   period of time. This could be used to back up secure hosts, for instance.
 
 
-* Backups to remote tape devices (i.e., not in the main AMANDA server), as well
+* Backups to remote tape devices (i.e., not in the main Amanda server), as well
   as to remote filesystems should be supported.
 
 
-* multi-tape : AMANDA should be able to write to many tape at the same time.
+* multi-tape : Amanda should be able to write to many tape at the same time.
   Need some criteria to select which dump should go on which tape? By level,
   host name, ???
 
@@ -104,9 +100,6 @@ Oct. 2004.
   tape could be started first, while doing some dump to holding disk.
 
 
-* Autoflush to tape while doing estimate.
-
-
 * Keep files on holding disk after taped, that will permit faster recovery
   because they will be from holding disk, these dump will be erase when the
   same is needed for newer dump.
@@ -117,7 +110,7 @@ Oct. 2004.
 
 * chg-disk
   This script writes to disks which can be accessed in a parallel way (contrary
-  to the serial access to tapes). This could enable AMANDA to do writes and
+  to the serial access to tapes). This could enable Amanda to do writes and
   reads to several vtapes in parallel (e.g. doing an amrestore while the
   regular amdump is running).
   It would be helpful to have a script which generates the needed directory-
@@ -134,16 +127,12 @@ Oct. 2004.
 * It should be possible to re-generate databases and indexes from tapes.
 
 
-* AMANDA could append meta-data like databases and indexes to tape, so that
+* Amanda could append meta-data like databases and indexes to tape, so that
   each tape contains its own current indexes and everything to rebuild the
   server-config.
 
 
-* AMANDA should install man-pages for installed programs only.
-
-
-* We should provide for client-side configuration files, to specify default
-  tape server, index server, and perhaps even pathnames to some programs.
+* Amanda should install man-pages for installed programs only.
 
 
 * It should be possible to configure whether amidxtaped should decompress the
@@ -174,13 +163,6 @@ Oct. 2004.
   A new script to kill all process on client and server
 
 
-* Convert datestamp to timestamp everywhere, that will permit many run a day,
-  and be able to recover them easily. it's already done for holding disk.
-  (That's a big job, AMANDA use the datestamp sometimes as INT, sometime as
-  CHAR*, converting every thing to CHAR* is probably not very difficult, what
-  will be difficult will be to stay compatible with the old datestamp.)
-
-
 * Enhance the protocol between client-server to allow white-space and any
   character in DLE/exclude/include.
 
@@ -188,7 +170,7 @@ Oct. 2004.
 * More tools in amadmin. The administrator should be able to look at the
   database in various ways. Adding / deleting / moving disks and hosts should
   be done through amadmin instead of editing the disklist directly. This will
-  allow AMANDA to do some sanity checks for the operators, to make sure
+  allow Amanda to do some sanity checks for the operators, to make sure
   permissions are set up right, etc.
   Suggested by Chris Jones <cjones@honors.montana.edu>.
 
@@ -198,22 +180,22 @@ Oct. 2004.
   shell with a help facility (ala ckermit or gnuplot, if you've seen those).
 
 
-* A tape-verify pass after the AMANDA run (we already have one, but it doesn't
+* A tape-verify pass after the Amanda run (we already have one, but it doesn't
   work with dump as well as it does with GNU tar). Perhaps taper could
   calculate a CRC for each file and store that in the database, to be checked
   by the verifier.
 
 
-* More sophisticated tape management. Should AMANDA track tapes globally,
+* More sophisticated tape management. Should Amanda track tapes globally,
   counting the number of times tapes were used, and recommending retirement for
   tapes at the appropriate time?
 
 
 * Automatically notice that external dumps have been done. Sendsize could also
-  notice if a filesystem was dumped externally from AMANDA. Right now the
+  notice if a filesystem was dumped externally from Amanda. Right now the
   planner assumes that the incrementals it is doing are relative to the full
   dumps it is doing. If someone does a full dump of one of its filesystems (and
-  writes /etc/dumpdates) outside of AMANDA, data could be lost. Sun's Backup-
+  writes /etc/dumpdates) outside of Amanda, data could be lost. Sun's Backup-
   Copilot handles this well. We should too.
 
 
@@ -236,7 +218,7 @@ Oct. 2004.
   full [AUTOMATIC | SKIP | NOTIFY | FORCE | FIXED]
   incr [NONE | BUMP | NOBUMP]
   with the following values:
-  AUTOMATIC: follow AMANDA scheduling (allow promoted and delayed)
+  AUTOMATIC: follow Amanda scheduling (allow promoted and delayed)
   SKIP : full dump are done externally on an fixed schedule, dump nothing when
   a full is due (like skip-full).
   NOTIFY : full dumps are done externally, but are notified with the NOTIFY
@@ -249,15 +231,15 @@ Oct. 2004.
 
 
 * Remove all compiled options that can be moved to a (the?) configuration file.
-  (eg. GNU tar path, if configure can't find it, AMANDA should be able to use
+  (eg. GNU tar path, if configure can't find it, Amanda should be able to use
   GNU tar if the path is specified on a client config file) Many people would
   like this, it would maybe also bring us closer to the possibility of working
   and usable rpms?
 
 
 * Documentation:
-  There is pretty much going on with the AMANDA-docs. The docs have been
-  converted to Docbook/XML and form the new module xml-docs in the AMANDA-CVS-
+  There is pretty much going on with the Amanda-docs. The docs have been
+  converted to Docbook/XML and form the new module xml-docs in the Amanda-CVS-
   repository.
   The FAQ-O-Matic could be replaced by a Wiki. Suggested by Harlan Stenn
   <Harlan.Stenn@pfcs.com>.
@@ -268,7 +250,7 @@ Oct. 2004.
 The WISHLIST should get shortened.
 -------------------------------------------------------------------------------
 
-Prev                                   Up                                Next
-Chapter 18. Collection of the top ten Home  Chapter 20. AMANDA Survey Results
-AMANDA questions. And answers. 
+Prev                                          Up                           Next
+Chapter 20. Collection of the top ten Amanda Home  Part V. Technical Background
+questions. And answers. 
 
index 7731c94e118426415aa86f17d5c272a5ad0ea6d7..59ff851e798352c96bb8f5cf76825273aacea977 100644 (file)
@@ -1,13 +1,13 @@
 
-        Chapter 33. Y2K Compliance
+        Chapter 34. Y2K Compliancy
 Prev  Part VI. Historical files  Next
 
 -------------------------------------------------------------------------------
 
-Chapter 33. Y2K Compliance
+Chapter 34. Y2K Compliancy
 
 
-AMANDA Core Team
+Amanda Core Team
 
 Original text
 AMANDA Core Team
@@ -22,13 +22,13 @@ Note
 
 Refer to http://www.amanda.org/docs/y2k.html for the current version of this
 document.
-The AMANDA developers believe AMANDA is Y2K-compliant, as long as the
+The Amanda developers believe Amanda is Y2K-compliant, as long as the
 underlying operating system and C library are. The only date manipulations
-performed by AMANDA use C-language time manipulation functions and/or strings
+performed by Amanda use C-language time manipulation functions and/or strings
 where years are represented with the century-included notation.
 -------------------------------------------------------------------------------
 
 Prev                                   Up                               Next
-Chapter 32. Thoughts about a Strategy Home  Chapter 34. Usage of floppy tape
+Chapter 33. Thoughts about a Strategy Home  Chapter 35. Usage of floppy tape
 API                                                          drives on Linux
 
index 4bd48fdb5411dac03622b5597633ec696db021b2..f00725128260874eb992ba40d68c056818e80c0f 100644 (file)
@@ -1,10 +1,10 @@
 
-Chapter 34. Usage of floppy tape drives on Linux
+Chapter 35. Usage of floppy tape drives on Linux
 Prev  Part VI. Historical files             Next
 
 -------------------------------------------------------------------------------
 
-Chapter 34. Usage of floppy tape drives on Linux
+Chapter 35. Usage of floppy tape drives on Linux
 
 
 Albrecht Gebhardt
@@ -21,11 +21,11 @@ Note
 
 Refer to http://www.amanda.org/docs/zftape.html for the current version of this
 document.
-AMANDA now supports the ftape driver version 3.04d (see http://www-
+Amanda now supports the ftape driver version 3.04d (see http://www-
 math.math.rwth-aachen.de/~LBFM/claus/ftape ). It adjusts the blocksize
 automatically to 32k and supports QIC volume tables.
 It uses only one open() call for writing backups to one tape, so the "busy"-
-lamp of the drive will be on all the time. (With normal AMANDA code it would be
+lamp of the drive will be on all the time. (With normal Amanda code it would be
 off in pauses between two files written to tape.)
 For volume table support you have to get libvtblc first (available at ftp://
 pc02-stat.sci.uni-klu.ac.at/pub/Linux/libvtblc.) This library contains the
@@ -55,7 +55,7 @@ like (listed with vtblc utility from ftape):
   %
     4 VTBL alpha sda6 0            00:00:00 03/15/98     1907     8092   11.45
   %
-    5 VTBL AMANDA Tape End         01:45:15 03/16/98     8093     8094    0.00
+    5 VTBL Amanda Tape End         01:45:15 03/16/98     8093     8094    0.00
   %
 
 With lvtblc, currently available with the libvtblc library, you can list the
@@ -72,17 +72,17 @@ vtblc):
     2 VTBL gamma sda2 0                                  00:00:00 03/15/98
     3 VTBL alpha sda2 0                                  00:00:00 03/15/98
     4 VTBL alpha sda6 0                                  00:00:00 03/15/98
-    5 VTBL AMANDA Tape End                               01:45:15 03/16/98
+    5 VTBL Amanda Tape End                               01:45:15 03/16/98
 
-Note on datestamps: volume 0 (AMANDA label): reflects the time of starting the
-backup volume i (backup files): AMANDA datestamps of the backup files last
+Note on datestamps: volume 0 (Amanda label): reflects the time of starting the
+backup volume i (backup files): Amanda datestamps of the backup files last
 volume (end marker) : reflects the time of finishing the backup
 I tested this on a Linux machine (P90 / 96Mb RAM / 256 Mb swap) with two other
 clients (Linux / WfW) using
 
 * Linux Kernel 2.0.33,
 * ftape 3.04d,
-* AMANDA 2.4.0b6p4
+* Amanda 2.4.0b6p4
 
 with an internal Iomega Ditto 3200 (TR-3) drive attached to an Iomega Ditto
 Dash controller (at 2000 Kbps). My tapetype follows:
@@ -105,5 +105,5 @@ waste 29 kb.
 -------------------------------------------------------------------------------
 
 Prev                         Up                   Next
-Chapter 33. Y2K Compliancy  Home  Part VII. Appendixes
+Chapter 34. Y2K Compliancy  Home  Part VII. Appendixes
 
index d4914037f9a319eb691605d1e4c6060f0134a5ae..9a52d5df82fd172cba40833c487c5532a13e460d 100644 (file)
@@ -63,11 +63,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -75,6 +78,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
index 397e009ccf48db7f79591003fe76fbfa808a9d26..e22862bac033dfea481160d1471ae078a4a874e2 100644 (file)
@@ -1,7 +1,10 @@
 # Makefile for sample configuration files
 
-noinst_DATA = amanda.conf
+noinst_DATA = amanda.conf \
+               amanda-client.conf
 
 EXTRA_DIST =   chg-multi.conf chg-scsi.conf config.site disklist \
                DLT.ps EXB-8500.ps HP-DAT.ps 8.5x11.ps 3hole.ps DIN-A4.ps \
                chg-mcutil.conf
+
+
index 322acc4d31e9bc2b1b0743bac38f154e4fdff0ae..4321fe4348894d714d0a29468b9cb32d25b5042c 100644 (file)
@@ -41,7 +41,8 @@ host_triplet = @host@
 target_triplet = @target@
 subdir = example
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
-       $(srcdir)/amanda.conf.in $(srcdir)/chg-mcutil.conf.in
+       $(srcdir)/amanda-client.conf.in $(srcdir)/amanda.conf.in \
+       $(srcdir)/chg-mcutil.conf.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
        $(top_srcdir)/configure.in
@@ -49,7 +50,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config/config.h
-CONFIG_CLEAN_FILES = amanda.conf chg-mcutil.conf
+CONFIG_CLEAN_FILES = amanda.conf chg-mcutil.conf amanda-client.conf
 SOURCES =
 DIST_SOURCES =
 DATA = $(noinst_DATA)
@@ -61,11 +62,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -73,6 +77,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -253,7 +259,9 @@ target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
-noinst_DATA = amanda.conf
+noinst_DATA = amanda.conf \
+               amanda-client.conf
+
 EXTRA_DIST = chg-multi.conf chg-scsi.conf config.site disklist \
                DLT.ps EXB-8500.ps HP-DAT.ps 8.5x11.ps 3hole.ps DIN-A4.ps \
                chg-mcutil.conf
@@ -294,6 +302,8 @@ amanda.conf: $(top_builddir)/config.status $(srcdir)/amanda.conf.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 chg-mcutil.conf: $(top_builddir)/config.status $(srcdir)/chg-mcutil.conf.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amanda-client.conf: $(top_builddir)/config.status $(srcdir)/amanda-client.conf.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 
 mostlyclean-libtool:
        -rm -f *.lo
diff --git a/example/amanda-client.conf.in b/example/amanda-client.conf.in
new file mode 100644 (file)
index 0000000..0a10e65
--- /dev/null
@@ -0,0 +1,34 @@
+###  !!! WARNING !!!  !!! WARNING !!!  !!! WARNING !!!  !!! WARNING !!!  ###
+###                                                                      ###
+###  This file is not meant to be installed "as is", and in fact, it     ###
+###  WILL NOT WORK!  You must go through it and make changes appropriate ###
+###  to your own situation.  See the documentation in this file, in the  ###
+###  "man amanda" man page, in the "docs" directory and at the Amanda    ###
+###  web page (www.amanda.org).                                          ###
+###                                                                      ###
+###  !!! WARNING !!!  !!! WARNING !!!  !!! WARNING !!!  !!! WARNING !!!  ###
+
+#
+# amanda.conf - sample Amanda client configuration file.
+#
+# This file normally goes in @CONFIG_DIR@/amanda-client.conf.
+#
+
+conf "@DEFAULT_CONFIG@"                # your config name
+
+index_server "@DEFAULT_SERVER@"        # your amindexd server
+tape_server  "@DEFAULT_TAPE_SERVER@"   # your amidxtaped server
+tapedev      "@DEFAULT_TAPE_DEVICE@"           # your tape device
+
+#   auth       - authentication scheme to use between server and client.
+#                Valid values are "bsd", "krb4", "krb5" and "ssh".  
+#                Default: [auth "bsd"]
+auth "bsd"
+
+ssh_keys ""                    # your ssh keys file if you use ssh auth
+
+# You may include other amanda configuration files, so you can share
+# dumptypes, tapetypes and interface definitions among several
+# configurations.
+
+#includefile "@CONFIG_DIR@/amanda-client.conf.main"
index 1baa5095eeb9cb6e8ca4fc756d80a194ac61a94c..1a2891ccaff867f87b222594a182d5b1e8147305 100644 (file)
@@ -1,23 +1,8 @@
-###  !!! WARNING !!!  !!! WARNING !!!  !!! WARNING !!!  !!! WARNING !!!  ###
-###                                                                      ###
-###  This file is not meant to be installed "as is", and in fact, it     ###
-###  WILL NOT WORK!  You must go through it and make changes appropriate ###
-###  to your own situation.  See the documentation in this file, in the  ###
-###  "man amanda" man page, in the "docs" directory and at the Amanda    ###
-###  web page (www.amanda.org).                                          ###
-###                                                                      ###
-###  !!! WARNING !!!  !!! WARNING !!!  !!! WARNING !!!  !!! WARNING !!!  ###
+# amanda.conf - sample Amanda configuration file. See amanda.conf(5) for 
+# details
 
-#
-# amanda.conf - sample Amanda configuration file.  This started off life as
-#               the actual config file in use at CS.UMD.EDU.
-#
-# If your configuration is called, say, "csd", then this file normally goes
-# in @CONFIG_DIR@/csd/amanda.conf.
-#
-
-org "@DEFAULT_CONFIG@"         # your organization name for reports
-mailto "@CLIENT_LOGIN@"                # space separated list of operators at your site
+org     "@DEFAULT_CONFIG@"     # your organization name for reports
+mailto          "@CLIENT_LOGIN@"       # space separated list of operators at your site
 dumpuser "@CLIENT_LOGIN@"      # the user to run dumps under
 
 inparallel 4           # maximum dumpers that will run in parallel (max 63)
@@ -35,14 +20,15 @@ dumporder "sssS"    # specify the priority order of each dumper
 
 taperalgo first                # The algorithm used to choose which dump image to send
                        # to the taper.
-
-                       # Possible values: [first|firstfit|largest|largestfit|smallest|last]
+                       # Possible values: 
+                       # [first|firstfit|largest|largestfit|smallest|last]
                        # Default: first. 
-
                        # first         First in - first out.
-                       # firstfit      The first dump image that will fit on the current tape.
+                       # firstfit      The first dump image that will fit 
+                        #               on the current tape.
                        # largest       The largest dump image.
-                       # largestfit    The largest dump image that will fit on the current tape.
+                       # largestfit    The largest dump image that will fit 
+                        #               on the current tape.
                        # smallest      The smallest dump image.
                        # last          Last in - first out.
 
@@ -69,20 +55,20 @@ bumpdays 1          # minimum days at each level
 bumpmult 4             # threshold = bumpsize * bumpmult^(level-1)
 
 etimeout 300           # number of seconds per filesystem for estimates.
-#etimeout -600         # total number of seconds for estimates.
-# a positive number will be multiplied by the number of filesystems on
-# each host; a negative number will be taken as an absolute total time-out.
-# The default is 5 minutes per filesystem.
-
 dtimeout 1800          # number of idle seconds before a dump is aborted.
-
 ctimeout 30            # maximum number of seconds that amcheck waits
                        # for each client host
  
-tapebufs 20
-# A positive integer telling taper how many 32k buffers to allocate.
-# WARNING! If this is set too high, taper will not be able to allocate
-# the memory and will die.  The default is 20 (640k).
+tapebufs 20             # A positive integer telling taper how many 
+                        # 32k buffers to allocate.  The default is 20 (640k).
+
+# By default, Amanda can only track at most one run per calendar day. When
+# the usetimestamps option is enabled, however, Amanda can track as many
+# runs as you care to make.
+# WARNING: This option is not backward-compatible. Do not enable it if you
+#          intend to downgrade your server installation to Amanda community 
+#          edition 2.5
+usetimestamps yes
 
 
 # Specify tape device and/or tape changer.  If you don't have a tape
@@ -95,16 +81,15 @@ tapebufs 20
 # parameter.  Some rely on a configuration file (changerfile) to
 # obtain more information about tape devices, number of slots, etc;
 # others just need to store some data in files, whose names will start
-# with changerfile.  For more information about individual tape
-# changers, read docs/TAPE.CHANGERS.
+# with changerfile.  
 
 # At most one changerfile entry must be defined; select the most
 # appropriate one for your configuration.  If you select man-changer,
 # keep the first one; if you decide not to use a tape changer, you may
 # comment them all out.
 
-runtapes 1             # number of tapes to be used in a single run of amdump
-tpchanger "chg-manual" # the tape-changer glue script
+runtapes 1                     # number of tapes to be used in a single run of amdump
+tpchanger "chg-manual"         # the tape-changer glue script
 tapedev "@DEFAULT_TAPE_DEVICE@"        # the no-rewind tape device to be used
 rawtapedev "@DEFAULT_RAW_TAPE_DEVICE@" # the raw device to be used (ftape only)
 #changerfile "@CONFIG_DIR@/@DEFAULT_CONFIG@/changer"
@@ -148,9 +133,9 @@ amrecover_changer "@DEFAULT_TAPE_DEVICE@"   # amrecover will use the changer if yo
 holdingdisk hd1 {
     comment "main holding disk"
     directory "/dumps/amanda"  # where the holding disk is
-    use -100 Mb                # how much space can we use on it
-                       # a non-positive value means:
-                       #        use all space but that value
+    use -100 Mb                        # how much space can we use on it
+                               # a non-positive value means:
+                               # use all space but that value
     chunksize 1Gb      # size of chunk if you want big dump to be
                        # dumped on multiple files on holding disks
                        #  N Kb/Mb/Gb split images in chunks of size N
@@ -219,8 +204,8 @@ autoflush no #
 # you have selected some database format other than the `text' default)
 infofile "@CONFIG_DIR@/@DEFAULT_CONFIG@/curinfo"       # database DIRECTORY
 logdir   "@CONFIG_DIR@/@DEFAULT_CONFIG@"               # log directory
-indexdir "@CONFIG_DIR@/@DEFAULT_CONFIG@/index" # index directory
-#tapelist "@CONFIG_DIR/@DEFAULT_CONFIG@/tapelist"      # list of used tapes
+indexdir "@CONFIG_DIR@/@DEFAULT_CONFIG@/index"         # index directory
+#tapelist "@CONFIG_DIR@/@DEFAULT_CONFIG@/tapelist"     # list of used tapes
 # tapelist is stored, by default, in the directory that contains amanda.conf
 
 # tapetypes
@@ -375,7 +360,7 @@ define tapetype MIMSY-MEGATAPE {
 #                              it takes only a few seconds but the result is not 
 #                              accurate if your disk usage changes from day to day.
 #                Default: [client]
-#   encrypt     - specify encryption of the backed up data. Valid values are:
+#   encrypt  - specify encryption of the backed up data. Valid values are:
 #                "none"   - don't encrypt the dump output.
 #                "client" - encrypt on the client using the program specified by 
 #                            client_encrypt "PROG".
@@ -411,7 +396,10 @@ define tapetype MIMSY-MEGATAPE {
 #                going to be backed up.
 #                Default: include all files
 #   holdingdisk        - should the holding disk be used for this dump.  Useful for
-#                dumping the holding disk itself.  Default: [holdingdisk yes]
+#                dumping the holding disk itself.  Default: [holdingdisk auto]
+#                "never"    - Never use the holding disk.
+#                "auto"     - Use the holding disk if possible.
+#                "required" - Always use the holding disk.
 #   ignore     - do not back this filesystem up.  Useful for sharing a single
 #                disklist in several configurations.
 #   index      - keep an index of the files backed up.  Default: [index no]
@@ -429,8 +417,8 @@ define tapetype MIMSY-MEGATAPE {
 #                mode", as many incrementals as will fit on the holding disk
 #                are done, higher priority first, to insure the important
 #                disks are at least dumped.  Default: [priority medium]
-#   program    - specify the dump system to use.  Valid values are "DUMP" and
-#                "GNUTAR".  Default: [program "DUMP"].
+#   program    - specify the dump system to use.  Valid values are "DUMP",
+#                 or "GNUTAR".  Default: [program "DUMP"].
 #   record     - record the backup in the time-stamp-database of the backup
 #                program (e.g. /etc/dumpdates for DUMP or
 #                @GNUTAR_LISTED_INCREMENTAL_DIRX@ for GNUTAR.).
@@ -507,6 +495,7 @@ define dumptype always-full {
     dumpcycle 0
 }
 
+# Dumptypes for gnutar
 define dumptype root-tar {
     global
     program "GNUTAR"
@@ -555,7 +544,7 @@ define dumptype comp-user-tar-span {
 define dumptype holding-disk {
     global
     comment "The master-host holding disk itself"
-    holdingdisk no # do not use the holding disk
+    holdingdisk never # do not use the holding disk
     priority medium
 }
 
@@ -629,21 +618,46 @@ define dumptype comp-test {
 define dumptype custom-compress {
    global
    program "GNUTAR"
-   comment "test dump with custom client compression"
+   comment "custom client compression dumped with tar"
    compress client custom
    client_custom_compress "/usr/bin/bzip2"
 }
 
-define dumptype encrypt-fast {
+define dumptype server-encrypt-fast {
    global
    program "GNUTAR"
-   comment "test dump with fast client compression and server symmetric encryption"
+   comment "fast client compression and server symmetric encryption"
    compress client fast
    encrypt server
-   server_encrypt "/usr/local/sbin/amcrypt"
+   server_encrypt "/usr/sbin/amcrypt"
    server_decrypt_option "-d"
 }
 
+define dumptype client-encrypt-nocomp {
+   global
+   program "GNUTAR"
+   comment "no compression and client symmetric encryption"
+   compress none
+   encrypt client
+   client_encrypt "/usr/sbin/amcrypt"
+   client_decrypt_option "-d"
+}
+
+
+# To use gpg public-key encryption, gpg does compress with zlib by default.
+# Thus, no need to specify compress
+
+#define dumptype gpg-encrypt {
+#    global
+#    program "GNUTAR"
+#    comment "server public-key encryption, dumped with tar"
+#    compress none
+#    encrypt server
+#    server_encrypt "/usr/sbin/amgpgcrypt"
+#    server_decrypt_option "-d"
+#}
+
+
 # network interfaces
 #
 # These are referred to by the disklist file.  They define the attributes
index b824964cc4809e15f8f5b7290f3cb249ebf7c92b..97e42314b07b676763762972cd3a3094d0224574 100644 (file)
@@ -26,7 +26,7 @@
 #
 
 mcutil mcutil          #location of the mcutil program
-tape null:     # use ntape for norewind
+tape   # use ntape for norewind
                        # {a|m|h|c} suffixes should NOT 
                        # be tape device since they all
                        # implement hardware compression
index 1eea354f27a3ddb7bfccddf0b9be8072a7b7783d..bfe2c2e9dd4642ebd6baaa3b7a0086f1f5850904 100644 (file)
@@ -2,12 +2,16 @@
 
 transform =    s,x,x,;
 
+if WANT_AMPLOT
 AMPLOT_MAN8_PAGES = amplot.8
+endif
 
 COMMON_MAN8_PAGES = amanda.8
 
-COMMON_MAN5_PAGES = amanda.conf.5
+COMMON_MAN5_PAGES = amanda.conf.5 \
+                   amanda-client.conf.5
 
+#if WANT_SERVER
 SERVER_MAN8_PAGES = amadmin.8 \
                    amcheck.8 \
                    amcheckdb.8 \
@@ -29,7 +33,10 @@ SERVER_MAN8_PAGES = amadmin.8 \
                    amverifyrun.8 \
                    amfetchdump.8 \
                    amcrypt.8 \
-                   amaespipe.8
+                   amaespipe.8 \
+                   amcrypt-ossl.8 \
+                   amcrypt-ossl-asym.8
+#endif
 
 if WANT_RECOVER
 RECOVER_MAN8_PAGES = amrecover.8
@@ -39,26 +46,14 @@ if WANT_RESTORE
 RESTORE_MAN8_PAGES = amrestore.8
 endif
 
-man8_MANS = $(COMMON_MAN8_PAGES)
+man8_MANS = $(COMMON_MAN8_PAGES) \
+           $(AMPLOT_MAN8_PAGES) \
+           $(SERVER_MAN8_PAGES) \
+           $(RECOVER_MAN8_PAGES) \
+           $(RESTORE_MAN8_PAGES)
 
 man5_MANS = $(COMMON_MAN5_PAGES)
 
-if WANT_AMPLOT
-man8_MANS += $(AMPLOT_MAN8_PAGES)
-endif
-
-if WANT_SERVER
-man8_MANS += $(SERVER_MAN8_PAGES)
-endif
-
-if WANT_RECOVER
-man8_MANS += $(RECOVER_MAN8_PAGES)
-endif
-
-if WANT_RESTORE
-man8_MANS += $(RESTORE_MAN8_PAGES)
-endif
-
 ALL_MAN_PAGES = $(AMPLOT_MAN8_PAGES) \
           $(COMMON_MAN5_PAGES) \
           $(COMMON_MAN8_PAGES) \
@@ -77,26 +72,43 @@ EXTRA_XML = xslt/expand-sambadoc.xsl \
             xslt/settings.xsl \
            entities/global.entities \
            entities/xinclude.dtd
-           
 
 EXTRA_DIST = $(ALL_MAN_PAGES) $(MAN_XML) $(EXTRA_XML)
 
-if HAVE_XSLTPROC
-
 GEN_XML = $(ALL_MAN_PAGES:%=xml-source/%.proc.xml)
 
 MOSTLYCLEANFILES = $(GEN_XML)
 MAINTAINERCLEANFILES = $(ALL_MAN_PAGES)
 
+if BUILD_MAN_PAGES
+if   HAVE_XSLTPROC
 xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
        $(XSLTPROC) --path $(srcdir)/xslt/ --xinclude --stringparam latex.imagebasedir "$*/" --stringparam noreference 1 --output $@ $(srcdir)/xslt/expand-sambadoc.xsl $<
 
 %: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
        $(XSLTPROC) --path $(srcdir)/xslt/ --output $@ man.xsl $<
 
-endif
-# ^- HAVE_XSLTPROC
+else    # !HAVE_XSLTPROC
 
+xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+       @echo WARNING: $@ can not be generated: xsltproc is not available.
+
+%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+       @echo WARNING: $@ can not be generated: xsltproc is not available.
+
+endif  # HAVE_XSLTPROC
+
+else  # !BUILD_MAN_PAGES
+
+xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+       @echo  Build of $@ skipped.
+
+%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+       @echo  Build of $@ skipped.
+
+endif # BUILD_MAN_PAGES
+
+if BUILD_MAN_PAGES
 install-data-hook:
        @list="$(man8_MANS)"; \
        for p in $$list; do \
@@ -115,3 +127,10 @@ install-data-hook:
                chgrp $(SETUID_GROUP) $$pa; \
        done
 
+else  # !BUILD_MAN_PAGES
+
+install:
+       @echo Skipping man page installation.
+
+endif
+
index 11c65180664e96a0803581b4ed83c7a44805e2b4..7f6f5a6d6fd4767667359f715ebdd5cd1a19569a 100644 (file)
@@ -37,10 +37,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
-@WANT_AMPLOT_TRUE@am__append_1 = $(AMPLOT_MAN8_PAGES)
-@WANT_SERVER_TRUE@am__append_2 = $(SERVER_MAN8_PAGES)
-@WANT_RECOVER_TRUE@am__append_3 = $(RECOVER_MAN8_PAGES)
-@WANT_RESTORE_TRUE@am__append_4 = $(RESTORE_MAN8_PAGES)
 subdir = man
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -67,11 +63,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -79,6 +78,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -259,9 +260,13 @@ target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
-AMPLOT_MAN8_PAGES = amplot.8
+@WANT_AMPLOT_TRUE@AMPLOT_MAN8_PAGES = amplot.8
 COMMON_MAN8_PAGES = amanda.8
-COMMON_MAN5_PAGES = amanda.conf.5
+COMMON_MAN5_PAGES = amanda.conf.5 \
+                   amanda-client.conf.5
+
+
+#if WANT_SERVER
 SERVER_MAN8_PAGES = amadmin.8 \
                    amcheck.8 \
                    amcheckdb.8 \
@@ -283,12 +288,19 @@ SERVER_MAN8_PAGES = amadmin.8 \
                    amverifyrun.8 \
                    amfetchdump.8 \
                    amcrypt.8 \
-                   amaespipe.8
+                   amaespipe.8 \
+                   amcrypt-ossl.8 \
+                   amcrypt-ossl-asym.8
 
+#endif
 @WANT_RECOVER_TRUE@RECOVER_MAN8_PAGES = amrecover.8
 @WANT_RESTORE_TRUE@RESTORE_MAN8_PAGES = amrestore.8
-man8_MANS = $(COMMON_MAN8_PAGES) $(am__append_1) $(am__append_2) \
-       $(am__append_3) $(am__append_4)
+man8_MANS = $(COMMON_MAN8_PAGES) \
+           $(AMPLOT_MAN8_PAGES) \
+           $(SERVER_MAN8_PAGES) \
+           $(RECOVER_MAN8_PAGES) \
+           $(RESTORE_MAN8_PAGES)
+
 man5_MANS = $(COMMON_MAN5_PAGES)
 ALL_MAN_PAGES = $(AMPLOT_MAN8_PAGES) \
           $(COMMON_MAN5_PAGES) \
@@ -307,9 +319,9 @@ EXTRA_XML = xslt/expand-sambadoc.xsl \
            entities/xinclude.dtd
 
 EXTRA_DIST = $(ALL_MAN_PAGES) $(MAN_XML) $(EXTRA_XML)
-@HAVE_XSLTPROC_TRUE@GEN_XML = $(ALL_MAN_PAGES:%=xml-source/%.proc.xml)
-@HAVE_XSLTPROC_TRUE@MOSTLYCLEANFILES = $(GEN_XML)
-@HAVE_XSLTPROC_TRUE@MAINTAINERCLEANFILES = $(ALL_MAN_PAGES)
+GEN_XML = $(ALL_MAN_PAGES:%=xml-source/%.proc.xml)
+MOSTLYCLEANFILES = $(GEN_XML)
+MAINTAINERCLEANFILES = $(ALL_MAN_PAGES)
 all: all-am
 
 .SUFFIXES:
@@ -484,7 +496,7 @@ installdirs:
        for dir in "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \
          test -z "$$dir" || $(mkdir_p) "$$dir"; \
        done
-install: install-am
+@BUILD_MAN_PAGES_TRUE@install: install-am
 install-exec: install-exec-am
 install-data: install-data-am
 uninstall: uninstall-am
@@ -510,6 +522,7 @@ maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
        @echo "it deletes files that may require special tools to rebuild."
        -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+@BUILD_MAN_PAGES_FALSE@install-data-hook:
 clean: clean-am
 
 clean-am: clean-generic clean-libtool mostlyclean-am
@@ -572,31 +585,44 @@ uninstall-man: uninstall-man5 uninstall-man8
        uninstall-info-am uninstall-man uninstall-man5 uninstall-man8
 
 
-@HAVE_XSLTPROC_TRUE@xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
-@HAVE_XSLTPROC_TRUE@   $(XSLTPROC) --path $(srcdir)/xslt/ --xinclude --stringparam latex.imagebasedir "$*/" --stringparam noreference 1 --output $@ $(srcdir)/xslt/expand-sambadoc.xsl $<
-
-@HAVE_XSLTPROC_TRUE@%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
-@HAVE_XSLTPROC_TRUE@   $(XSLTPROC) --path $(srcdir)/xslt/ --output $@ man.xsl $<
-
-# ^- HAVE_XSLTPROC
-
-install-data-hook:
-       @list="$(man8_MANS)"; \
-       for p in $$list; do \
-               pa=$(DESTDIR)$(man8dir)/`echo $$p|sed '$(transform)'`; \
-               echo chown $(BINARY_OWNER) $$pa; \
-               chown $(BINARY_OWNER) $$pa; \
-               echo chgrp $(SETUID_GROUP) $$pa; \
-               chgrp $(SETUID_GROUP) $$pa; \
-       done
-       @list="$(man5_MANS)"; \
-       for p in $$list; do \
-               pa=$(DESTDIR)$(man5dir)/`echo $$p|sed '$(transform)'`; \
-               echo chown $(BINARY_OWNER) $$pa; \
-               chown $(BINARY_OWNER) $$pa; \
-               echo chgrp $(SETUID_GROUP) $$pa; \
-               chgrp $(SETUID_GROUP) $$pa; \
-       done
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_TRUE@xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_TRUE@     $(XSLTPROC) --path $(srcdir)/xslt/ --xinclude --stringparam latex.imagebasedir "$*/" --stringparam noreference 1 --output $@ $(srcdir)/xslt/expand-sambadoc.xsl $<
+
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_TRUE@%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_TRUE@     $(XSLTPROC) --path $(srcdir)/xslt/ --output $@ man.xsl $<
+
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_FALSE@xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_FALSE@    @echo WARNING: $@ can not be generated: xsltproc is not available.
+
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_FALSE@%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_FALSE@    @echo WARNING: $@ can not be generated: xsltproc is not available.
+
+@BUILD_MAN_PAGES_FALSE@xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+@BUILD_MAN_PAGES_FALSE@        @echo  Build of $@ skipped.
+
+@BUILD_MAN_PAGES_FALSE@%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+@BUILD_MAN_PAGES_FALSE@        @echo  Build of $@ skipped.
+
+@BUILD_MAN_PAGES_TRUE@install-data-hook:
+@BUILD_MAN_PAGES_TRUE@ @list="$(man8_MANS)"; \
+@BUILD_MAN_PAGES_TRUE@ for p in $$list; do \
+@BUILD_MAN_PAGES_TRUE@         pa=$(DESTDIR)$(man8dir)/`echo $$p|sed '$(transform)'`; \
+@BUILD_MAN_PAGES_TRUE@         echo chown $(BINARY_OWNER) $$pa; \
+@BUILD_MAN_PAGES_TRUE@         chown $(BINARY_OWNER) $$pa; \
+@BUILD_MAN_PAGES_TRUE@         echo chgrp $(SETUID_GROUP) $$pa; \
+@BUILD_MAN_PAGES_TRUE@         chgrp $(SETUID_GROUP) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ done
+@BUILD_MAN_PAGES_TRUE@ @list="$(man5_MANS)"; \
+@BUILD_MAN_PAGES_TRUE@ for p in $$list; do \
+@BUILD_MAN_PAGES_TRUE@         pa=$(DESTDIR)$(man5dir)/`echo $$p|sed '$(transform)'`; \
+@BUILD_MAN_PAGES_TRUE@         echo chown $(BINARY_OWNER) $$pa; \
+@BUILD_MAN_PAGES_TRUE@         chown $(BINARY_OWNER) $$pa; \
+@BUILD_MAN_PAGES_TRUE@         echo chgrp $(SETUID_GROUP) $$pa; \
+@BUILD_MAN_PAGES_TRUE@         chgrp $(SETUID_GROUP) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ done
+
+@BUILD_MAN_PAGES_FALSE@install:
+@BUILD_MAN_PAGES_FALSE@        @echo Skipping man page installation.
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
index 6385236d4be8faa895d99caae241e66a33f6d2c8..6680037cd0cc7fb6497c0978a4faf59d49591216 100644 (file)
@@ -22,7 +22,8 @@
 amadmin - administrative interface to control Amanda backups
 .SH "SYNOPSIS"
 .HP 8
-\fBamadmin\fR \fIconfig\fR \fIcommand\fR [\fIcommand\fR \fIoptions\fR]
+\fBamadmin\fR \fIconfig\fR \fIcommand\fR [\fIcommand\fR\fIoptions\fR] [-o \fIconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 \fBAmadmin\fR
@@ -193,6 +194,10 @@ Display the database record for each of the
 on
 \fBhostname\fR
 (or all hosts). Mostly used for debugging.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .SH "EXAMPLES"
 .PP
 Request three specific file systems on
index b90de956e146d628eca5a8314324d9629bd1c041..b8d5ed12368e37f8a48da97155d7ee66b5c95f66 100644 (file)
@@ -27,7 +27,8 @@ amaespipe - wrapper program for aespipe
 .PP
 \fBamaespipe\fR
 requires
-\fBaespipe\fR
+\fBaespipe\fR,
+\fBuuencode\fR
 and
 \fBgpg\fR
 to work. Aespipe is available from
diff --git a/man/amanda-client.conf.5 b/man/amanda-client.conf.5
new file mode 100644 (file)
index 0000000..90d23f2
--- /dev/null
@@ -0,0 +1,175 @@
+.\"Generated by db2man.xsl. Don't modify this, modify the source.
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "AMANDA-CLIENT.CONF" 5 "" "" ""
+.SH "NAME"
+amanda-client.conf - Client configuration file for Amanda, the Advanced Maryland Automatic Network Disk Archiver
+.SH "DESCRIPTION"
+.PP
+\fIamanda-client.conf\fR
+is the client configuration file for
+\fBAmanda\fR. This manpage lists the relevant sections and parameters of this file for quick reference.
+.PP
+The files
+\fB<CONFIG_DIR>/amanda-client.conf\fR
+and
+\fB<CONFIG_DIR>/<config>/amanda-client.conf\fR
+are loaded.
+.SH "PARAMETERS"
+.PP
+There are a number of configuration parameters that control the behavior of the
+\fBAmanda\fR
+programs. All have default values, so you need not specify the parameter in
+\fBamanda-client.conf\fR
+if the default is suitable.
+.PP
+Lines starting with # are ignored, as are blank lines. Comments may be placed on a line with a directive by starting the comment with a #. The remainder of the line is ignored.
+.PP
+Keywords are case insensitive, i.e.
+\fBauth\fR
+and
+\fBAuth\fR
+are treated the same.
+.PP
+Integer arguments may have one of the following (case insensitive) suffixes, some of which have a multiplier effect:
+.SS "POSSIBLE SUFFIXES"
+.TP
+\fBb byte bytes\fR
+Some number of bytes.
+.TP
+\fBbps\fR
+Some number of bytes per second.
+.TP
+\fBk kb kbyte kbytes kilobyte kilobytes\fR
+Some number of kilobytes (bytes*1024).
+.TP
+\fBkps kbps\fR
+Some number of kilobytes per second (bytes*1024).
+.TP
+\fBm mb meg mbyte mbytes megabyte megabytes\fR
+Some number of megabytes (bytes*1024*1024).
+.TP
+\fBmps mbps\fR
+Some number of megabytes per second (bytes*1024*1024).
+.TP
+\fBg gb gbyte gbytes gigabyte gigabytes\fR
+Some number of gigabytes (bytes*1024*1024*1024).
+.TP
+\fBtape tapes\fR
+Some number of tapes.
+.TP
+\fBday days\fR
+Some number of days.
+.TP
+\fBweek weeks\fR
+Some number of weeks (days*7).
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+\fBNote\fR
+The value
+\fBinf\fR
+may be used in most places where an integer is expected
+to mean an infinite amount.
+
+Boolean arguments may have any of the values
+\fBy\fR,
+\fByes\fR,
+\fBt\fR,
+\fBtrue\fR
+or
+\fBon\fR
+to indicate a true state, or
+\fBn\fR,
+\fBno\fR,
+\fBf\fR,
+\fBfalse\fR
+or
+\fBoff\fR
+to indicate a false state. If no argument is given,
+\fBtrue\fR
+is assumed.
+.SS "PARAMETERS"
+.TP
+\fBconf\fR \fB string\fR
+Default:
+\fBSet by configure\fR. The conf use by amrecover.
+.TP
+\fBindex_server\fR \fB string\fR
+Default:
+\fBSet by configure\fR. The amindexd server amrecover will connect to.
+.TP
+\fBtape_server\fR \fB string\fR
+Default:
+\fBSet by configure\fR. The amidxtaped server amrecover will connect to.
+.TP
+\fBtapedev\fR \fB string\fR
+Default:
+\fBSet by configure\fR. The tapedev amrecover will use.
+.TP
+\fBauth\fR \fB string\fR
+Default:
+\fBbsd\fR. Type of authorization to perform between tape server and backup client hosts.
+.sp
+\fBbsd\fR, bsd authorization with udp initial connection and one tcp connection by data stream.
+.sp
+\fBbsdtcp\fR, bsd authorization but use only one tcp connection.
+.sp
+\fBbsdudp\fR, like bsd, but will use only one tcp connection for all data stream.
+.sp
+\fBkrb4\fR
+to use Kerberos-IV authorization.
+.sp
+\fBkrb5\fR
+to use Kerberos-V authorization.
+.sp
+\fBrsh\fR
+to use rsh authorization.
+.sp
+\fBssh\fR
+to use OpenSSH authorization.
+.TP
+\fBssh_keys\fR \fB string\fR
+Default:
+\fBNo default\fR. The key file the ssh auth will use, it must be the private key. If this parameter is not specified, then the deafult ssh key will be used.
+.TP
+\fBgnutar_list_dir\fR \fB string\fR
+Default from configure
+\fB--with-gnutar-listdir=DIR\fR. The directory where gnutar keep its state file.
+.TP
+\fBamandates\fR \fB string\fR
+Default:
+\fB/etc/amandates\fR. The file where amanda keep the last date of each dumplevel.
+.SH "AUTHOR"
+.PP
+James da Silva,
+<jds@amanda.org>: Original text
+.PP
+Stefan G. Weichinger,
+<sgw@amanda.org>, maintainer of the
+\fBAmanda\fR-documentation: XML-conversion, major update, splitting
+.SH "SEE ALSO"
+.PP
+\fBamanda\fR(8),
+\fBamanda.conf\fR(5),
+\fBamcrypt\fR(8),
+\fBaespipe\fR(1),
+
index 3112bba52d2734bee9eb08035b136c5e342c52e0..26e4951577697deb4d85465d11ae8ed0d09c9f65 100644 (file)
@@ -437,7 +437,7 @@ is used for most disks, but use of the holding disk needs to be disabled for the
 
 \fBhostname diskname\fR [ \fBdiskdevice\fR ] {
   normal
-  holdingdisk no
+  holdingdisk never
 } [ \fBspindle\fR [ \fBinterface\fR ] ]
 .fi
 .SH "TAPE MANAGEMENT"
@@ -654,7 +654,9 @@ file is:
 \fBhostname\fR
 [
 \fBusername\fR
-]
+[
+\fBservice\fR
+]*]
 .sp
 If
 \fBusername\fR
@@ -664,6 +666,19 @@ is ommitted, it defaults to the user running
 or
 \fBxinetd\fR
 configuration file.
+.sp
+The
+\fBservice\fR
+is a list of the service the client is authorized to execute:
+\fBamdump\fR,
+\fBnoop\fR,
+\fBselfcheck\fR,
+\fBsendsize\fR,
+\fBsendbackup\fR,
+\fBamindexd\fR,
+\fBamidxtaped\fR.
+\fBamdump\fR
+is a shortcut for "noop selfcheck sendsize sendbackup"
 .TP
 Kerberos
 \fBAmanda\fR
@@ -681,10 +696,13 @@ with share names, (clear text) passwords and (optional) domain names, in that or
 .nf
 
   //some-pc/home normalpw
-  //another-pc/disk otheruser%otherpw.fi
-With clear text passwords, this file should obviously be tightly protected. It only needs to be readable by the
-\fBAmanda\fR-user on the Samba server.
-.sp
+  //another-pc/disk otheruser%otherpw
+.fi
+
+
+With clear text passwords, this file should obviously be tightly protected.
+It only needs to be readable by the \fBAmanda\fR-user on the Samba server.
+
 You can find further information in the
 \fBdocs/SAMBA\fRfile that comes with an
 \fBAmanda\fR
@@ -739,6 +757,19 @@ A
 expression is a range expression where we only match the prefix. Leading ^ is removed. Trailing $ forces an exact match.
 20001212-14match all dates beginning with 20001212, 20001213 or 2000121420001212-4same as previous20001212-24match all dates between 20001212 and 200012242000121match all dates that start with 2000121 (20001210-20001219)2match all dates that start with 2 (20000101-29991231)2000-10match all dates between 20000101-20101231200010$match only 200010.PP
 
+.SH "CONFIGURATION OVERWRITE"
+.PP
+Most command allow to overwrite any configuration parameter on the command line with the -o option.
+.PP
+-o NAME=value
+.PP
+eg. -o runtapes=2
+.PP
+eg. -o DUMPTYPE:no-compress:compress="server fast"
+.PP
+eg. -o TAPETYPE:HP-DAT:length=2000m
+.PP
+eg. -o INTERFACE:local:use="2000 kbps"
 .SH "AUTHOR"
 .PP
 James da Silva,
@@ -752,6 +783,7 @@ Stefan G. Weichinger,
 .PP
 \fBamadmin\fR(8),
 \fBamanda.conf\fR(5),
+\fBamanda-client.conf\fR(5),
 \fBamcheck\fR(8),
 \fBamcheckdb\fR(8),
 \fBamcleanup\fR(8),
index 18eed23282f7c8c4e9fdf6b169ac2f07e4755088..a545f9f7e74d192cead24387bc8d02c95f63d5a2 100644 (file)
@@ -25,6 +25,10 @@ amanda.conf - Main configuration file for Amanda, the Advanced Maryland Automati
 \fIamanda.conf\fR
 is the main configuration file for
 \fBAmanda\fR. This manpage lists the relevant sections and parameters of this file for quick reference.
+.PP
+The file
+\fB<CONFIG_DIR>/<config>/amanda.conf\fR
+is loaded.
 .SH "PARAMETERS"
 .PP
 There are a number of configuration parameters that control the behavior of the
@@ -167,6 +171,12 @@ It is considered good administrative practice to set the
 \fBtapecycle\fR
 parameter slightly lower than the actual number of tapes in rotation. This allows the administrator to more easily cope with damaged or misplaced tapes or schedule adjustments that call for slight adjustments in the rotation order.
 .TP
+\fBusetimestamps\fR \fB bool\fR
+Default:
+\fBNo\fR. By default, Amanda can only track at most one run per calendar day. When this option is enabled, however, Amanda can track as many runs as you care to make.
+.sp
+\fBWARNING\fR: This option is not backward-compatible. Do not enable it if you intend to downgrade your server installation to Amanda community edition 2.5.0
+.TP
 \fBlabel_new_tapes\fR \fB string\fR
 Default: not set. When set, this directive will cause
 \fBAmanda\fR
@@ -180,19 +190,6 @@ tapes you may have, and may also ERASE any near-failing tapes. Use with caution.
 When using this directive, specify the template for new tape labels. The template should contain some number of contiguous '%' characters, which will be replaced with a generated number. Be sure to specify enough '%' characters that you do not run out of tape labels. Example:
 label_new_tapes "DailySet1-%%%"
 .TP
-\fBlabel_new_tapes\fR \fB string\fR
-
-=======
-  Default: not set. When set, this directive will cause
-\fBAmanda\fR
-to automatically write an Amanda tape label to any black tape she encounters. This option is DANGEROUS because when set,
-\fBAmanda\fR
-will ERASE any non-\fBAmanda\fR
-tapes you may have, and may also ERASE any near-failing tapes. Use with caution.
-.sp
-When using this directive, specify the template for new tape labels. The template should contain some number of contiguous '%' characters, which will be replaced with a generated number. Be sure to specify enough '%' characters that you do not run out of tape labels. Example:
-label_new_tapes "DailySet1-%%%"
-.TP
 \fBdumpuser\fR \fB string\fR
 Default:
 \fBamanda\fR. The login name
@@ -519,11 +516,11 @@ Default:
 .TP
 \fBamrecover_do_fsf\fR \fB bool\fR
 Default:
-\fBoff\fR. Amrecover will call amrestore with the -f flag for faster positioning of the tape.
+\fBon\fR. Amrecover will call amrestore with the -f flag for faster positioning of the tape.
 .TP
 \fBamrecover_check_label\fR \fB bool\fR
 Default:
-\fBoff\fR. Amrecover will call amrestore with the -l flag to check the label.
+\fBon\fR. Amrecover will call amrestore with the -l flag to check the label.
 .TP
 \fBamrecover_changer\fR \fB string\fR
 Default: ''. Amrecover will use the changer if you use 'settape <string>' and that string is the same as the amrecover_changer setting.
@@ -605,7 +602,8 @@ file may define one or more holding disks used as buffers to hold backup images
 holdingdisk \fBname\fR {
     \fBholdingdisk-option\fR \fBholdingdisk-value\fR
     ...
-}.fi
+}
+.fi
 .PP
 \fBName\fR
 is a logical name for this holding disk.
@@ -693,15 +691,32 @@ The dumptype options and values are:
 Default:
 \fBbsd\fR. Type of authorization to perform between tape server and backup client hosts.
 .sp
+\fBbsd\fR, bsd authorization with udp initial connection and one tcp connection by data stream.
+.sp
+\fBbsdtcp\fR, bsd authorization but use only one tcp connection.
+.sp
+\fBbsdudp\fR, like bsd, but will use only one tcp connection for all data stream.
+.sp
 \fBkrb4\fR
 to use Kerberos-IV authorization.
 .sp
 \fBkrb5\fR
 to use Kerberos-V authorization.
 .sp
+\fBrsh\fR
+to use rsh authorization.
+.sp
 \fBssh\fR
 to use OpenSSH authorization.
 .TP
+\fBamandad_path\fR \fB string\fR
+Default:
+\fB$libexec/amandad\fR. Specify the amandad path of the client, only use with rsh/ssh authentification.
+.TP
+\fBclient_username\fR \fB string\fR
+Default:
+\fBCLIENT_LOGIN\fR. Specify the username to connect on the client, only use with rsh/ssh authentification.
+.TP
 \fBbumpsize\fR int
 Default:
 \fB10 Mbytes\fR. The minimum savings required to trigger an automatic bump from one incremental level to the next, expressed as size. If
@@ -848,7 +863,7 @@ Specify client_decrypt_option "decryption-parameter" Default: "-d"
 .sp
 decryption-parameter must not contain white space.
 .sp
-(See dumptype encrypt-fast in example/amanda.conf for reference)
+(See dumptype server-encrypt-fast in example/amanda.conf for reference)
 .TP
 &#8226;
 encrypt server
@@ -860,13 +875,15 @@ PROG must not contain white space.
 Specify server_decrypt_option "decryption-parameter" Default: "-d"
 .sp
 decryption-parameter must not contain white space.
+.sp
+(See dumptype client-encrypt-nocomp in example/amanda.conf for reference)
 .RE
 .PP
 Note that current logic assumes compression then encryption during backup(thus decrypt then uncompress during restore). So specifying client-encryption AND server-compression is not supported.
 \fBamcrypt\fR
 which is a wrapper of
 \fBaespipe\fR
-is provided as a reference encryption program.
+is provided as a reference symmetric encryption program.
 .TP
 \fBestimate\fR \fBclient|calcsize|server\fR
 Default:
@@ -948,15 +965,26 @@ for a backup of
 for a backup of
 \fI/usr/local\fR, and so on.
 .TP
-\fBholdingdisk\fR \fB boolean\fR
+\fBholdingdisk\fR [ \fBnever|auto|required]\fR ]
 Default:
-\fByes\fR. Whether a holding disk should be used for these backups or whether they should go directly to tape. If the holding disk is a portion of another file system that
+\fBauto\fR. Whether a holding disk should be used for these backups or whether they should go directly to tape. If the holding disk is a portion of another file system that
 \fBAmanda\fR
 is backing up, that file system should refer to a dumptype with
 \fBholdingdisk\fR
 set to
-\fBno\fR
+\fBnever\fR
 to avoid backing up the holding disk into itself.
+.RS
+.TP
+\fBnever\fR|no|false|off
+Never use a holdingdisk, the dump will always go directly to tape. There will be no dump if you have a tape error.
+.TP
+\fBauto\fR|yes|true|on
+Use the holding disk, unless there is a problem with the holding disk, the dump won't fit there or the medium doesn't require spooling (e.g., VFS device)
+.TP
+\fBrequired\fR
+Always dump to holdingdisk, never directly to tape. There will be no dump if it doesn't fit on holdingdisk
+.RE
 .TP
 \fBignore\fR \fB boolean\fR
 Default:
@@ -1349,6 +1377,7 @@ Stefan G. Weichinger,
 .SH "SEE ALSO"
 .PP
 \fBamanda\fR(8),
+\fBamanda-client.conf\fR(5),
 \fBamcrypt\fR(8),
 \fBaespipe\fR(1),
 
index 657df5610204fad9df8fa7adcbdbf1b23d2bc755..4483818789cf5a13b984bc18ac5b7681f1b71aa1 100644 (file)
 amcheck - run Amanda self-checks
 .SH "SYNOPSIS"
 .HP 8
-\fBamcheck\fR [-mwsclt] [-Maddress] \fIconfig\fR [\fIhost\fR [\fIdisk\fR...]...]
+\fBamcheck\fR [-am] [-w] [-sclt] [-M \fIaddress\fR]*
+     \fIconfig\fR [\fIhost\fR [\fIdisk\fR]*]*
+     [-o \fIconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 \fBAmcheck\fR
@@ -54,7 +57,7 @@ Run the tape server local and tape checks (same as
 \fB-lt\fR).
 .TP
 \fB-c\fR
-Run the client host checks.
+Run the client host checks.Multiple specific clients can be checked by specifying the client name.
 .TP
 \fB-l\fR
 Run the local tests (e.g. permissions) on the server host.
@@ -65,9 +68,7 @@ Run the tape tests on the server host.
 \fB-w\fR
 Enables a DESTRUCTIVE check for write-protection on the tape (which would otherwise cause the subsequent
 \fBamdump\fR
-to fail). If the tape is writable, this check causes all data after the tape label to be erased. If the label_new_tapes option is enabled, this check may ERASE any non-Amanda tape in the drive or changer. The check implies
-\fB-t\fR
-and is only made if the tape is otherwise correct.
+to fail). If the tape is writable, this check causes all data after the tape label to be erased. If the label_new_tapes option is enabled, this check may ERASE any non-Amanda tape in the drive or changer. The check enable the tape tests on the server host and is only made if the tape is otherwise correct.
 .TP
 \fB-m\fR
 Nothing is printed, but mail is sent if any errors are detected. The mail goes to the
@@ -85,7 +86,7 @@ Like
 \fB-m\fR
 but the mail is always sent.
 .TP
-\fB-M\fR\fIaddress\fR
+\fB-M\fR \fIaddress\fR
 Mail the report to
 \fBaddress\fR
 instead of the
@@ -93,6 +94,13 @@ instead of the
 value from
 \fBamanda.conf\fR. Implies
 \fB-m\fR.
+.TP
+\fIhost\fR [\fIdisk\fR]*
+Specify the host and disk on which the command will work.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .PP
 The default is
 \fB-cs\fR.
index 44a7682dfd6fcb4d4b627ee9c962c441f3b8dbef..0e2ed16b3efde5f9c1ae85fb7e5305a79f288528 100644 (file)
@@ -42,6 +42,10 @@ See the
 \fBamanda\fR(8)
 man page for more details about
 \fBAmanda\fR.
+.SH "OPTIONS"
+.TP
+\fB-k\fR
+Kill all Amanda processes.
 .SH "EXAMPLES"
 .PP
 This example runs the
diff --git a/man/amcrypt-ossl-asym.8 b/man/amcrypt-ossl-asym.8
new file mode 100644 (file)
index 0000000..ec21f6f
--- /dev/null
@@ -0,0 +1,96 @@
+.\"Generated by db2man.xsl. Don't modify this, modify the source.
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "AMCRYPT-OSSL-ASYM" 8 "" "" ""
+.SH "NAME"
+amcrypt-ossl-asym - crypt program for Amanda asymmetric data encryption using OpenSSL
+.SH "SYNOPSIS"
+.HP 18
+\fBamcrypt-ossl-asym\fR [-d]
+.SH "DESCRIPTION"
+.PP
+\fBamcrypt-ossl-asym\fR
+uses
+\fBOpenSSL\fR
+to encrypt and decrypt data. OpenSSL is available from
+www.openssl.org. OpenSSL offers a wide variety of cipher choices (
+\fBamcrypt-ossl-asym\fR
+defaults to 256-bit AES) and can use hardware cryptographic accelerators on several platforms.
+.PP
+\fBamcrypt-ossl-asym\fR
+will search for the OpenSSL program in the following directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+.SH "GENERATING PUBLIC AND PRIVATE KEYS"
+.PP
+RSA keys can be generated with the standard OpenSSL commands, e.g.:
+.nf
+
+$ cd /var/lib/amanda
+$ openssl genrsa -aes128 -out backup-privkey.pem 1024
+Generating RSA private key, 1024 bit long modulus
+[...]
+Enter pass phrase for backup-privkey.pem: \fBENTER YOUR PASS PHRASE\fR
+Verifying - Enter pass phrase for backup-key.pem: \fBENTER YOUR PASS PHRASE\fR
+
+$ openssl rsa -in backup-privkey.pem -pubout -out backup-pubkey.pem
+Enter pass phrase for backup-privkey.pem: \fBENTER YOUR PASS PHRASE\fR
+Writing RSA key
+
+.fi
+.PP
+To generate a private key without a passphrase, omit the
+\fB-aes128\fR
+option. See
+\fBopenssl_genrsa\fR(1)
+for more key generation options.
+.PP
+Note that it is always possible to generate the public key from the private key.
+.SH "KEY AND PASSPHRASE MANAGEMENT"
+.PP
+\fBamcrypt-ossl-asym\fR
+uses the
+\fBpublic key\fR
+to encrypt data. The security of the data does not depend on the confidentiality of the public key. The
+\fBprivate key\fR
+is used to decrypt data, and must be protected. Encrypted backup data cannot be recovered without the private key. The private key may optionally be encrypted with a passphrase.
+.PP
+While the public key must be online at all times to perorm backups, the private key and optional passphrase are only needed to restore data. It is recommended that the latter be stored offline all other times. For example, you could keep the private key on removable media, and copy it into place for a restore; or you could keep the private key online, encrypted with a passphrase that is present only for a restore.
+.PP
+OpenSSL's key derivation routines use a salt to guard against dictionary attacks on the pass phrase; still it is important to pick a pass phrase that is hard to guess. The Diceware method (see
+www.diceware.com) can be used to create passphrases that are difficult to guess and easy to remember.
+.SH "FILES"
+.TP
+/var/lib/amanda/backup-privkey.pem
+File containing the RSA private key. It should not be readable by any user other than the
+\fBAmanda\fR
+user.
+.TP
+/var/lib/amanda/backup-pubkey.pem
+File containing the RSA public key.
+.TP
+/var/lib/amanda/.am_passphrase
+File containing the passphrase. It should not be readable by any user other than the
+\fBAmanda\fR
+user.
+.SH "SEE ALSO"
+.PP
+\fBamanda\fR(8),
+\fBamanda.conf\fR(5),
+\fBopenssl\fR(1),
+\fBamcrypt-ossl\fR(8)
+
diff --git a/man/amcrypt-ossl.8 b/man/amcrypt-ossl.8
new file mode 100644 (file)
index 0000000..215cb09
--- /dev/null
@@ -0,0 +1,59 @@
+.\"Generated by db2man.xsl. Don't modify this, modify the source.
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "AMCRYPT-OSSL" 8 "" "" ""
+.SH "NAME"
+amcrypt-ossl - crypt program for Amanda symmetric data encryption using OpenSSL
+.SH "SYNOPSIS"
+.HP 13
+\fBamcrypt-ossl\fR [-d]
+.SH "DESCRIPTION"
+.PP
+\fBamcrypt-ossl\fR
+uses
+\fBOpenSSL\fR
+to encrypt and decrypt data. OpenSSL is available from
+www.openssl.org. OpenSSL offers a wide variety of cipher choices (
+\fBamcrypt-ossl\fR
+defaults to 256-bit AES) and can use hardware cryptographic accelerators on several platforms.
+.PP
+\fBamcrypt-ossl\fR
+will search for the OpenSSL program in the following directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+.SH "PASSPHRASE MANAGEMENT"
+.PP
+\fBamcrypt-ossl\fR
+uses the same pass phrase to encrypt and decrypt data. It is very important to store and protect the pass phrase properly. Encrypted backup data can
+\fBonly\fR
+be recovered with the correct passphrase.
+.PP
+OpenSSL's key derivation routines use a salt to guard against dictionary attacks on the pass phrase; still it is important to pick a pass phrase that is hard to guess. The Diceware method (see
+www.diceware.com) can be used to create passphrases that are difficult to guess and easy to remember.
+.SH "FILES"
+.TP
+/var/lib/amanda/.am_passphrase
+File containing the pass phrase. It should not be readable by any user other than the
+\fBAmanda\fR
+user.
+.SH "SEE ALSO"
+.PP
+\fBamanda\fR(8),
+\fBamanda.conf\fR(5),
+\fBopenssl\fR(1),
+\fBamcrypt-ossl-asym\fR(8)
+
index 3041dd15e8eb36c719a6814c9d04240c016e242d..649fc819568f5726c34d27d1e698368ff908f468 100644 (file)
@@ -27,7 +27,8 @@ amcrypt - reference crypt program for Amanda symmetric data encryption
 .PP
 \fBamcrypt\fR
 requires
-\fBaespipe\fR
+\fBaespipe\fR,
+\fBuuencode\fR
 and
 \fBgpg\fR
 to work. Aespipe is available from
index 884de3a142f74628865e1f59e5a01fe1aa97c0ff..39ea5c164c6003eae29bf482585dd5f18256bb56 100644 (file)
@@ -22,7 +22,9 @@
 amdump - back up all disks in an Amanda configuration
 .SH "SYNOPSIS"
 .HP 7
-\fBamdump\fR \fIconfig\fR [\fIhost\fR [\fIdisk\fR...]...]
+\fBamdump\fR \fIconfig\fR [\fIhost\fR [\fIdisk\fR]*]*
+     [-o \fIconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 \fBAmdump\fR
@@ -47,6 +49,14 @@ See the
 \fBamanda\fR(8)
 man page for more details about
 \fBAmanda\fR.
+.SH "OPTIONS"
+.TP
+\fIhost\fR [\fIdisk\fR]*
+Specify the host and disk on which the command will work.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .SH "EXAMPLE"
 .PP
 Here is a typical crontab entry. It runs
index d57ef675a5613bdacf7a8f4ee4b05dbbb49d567e..4d333869a165693a29fdeb938fa0ede0e519527a 100644 (file)
@@ -22,7 +22,8 @@
 amfetchdump - extract backup images from multiple Amanda tapes.
 .SH "SYNOPSIS"
 .HP 12
-\fBamfetchdump\fR [-pcClawns] [-d \fIdevice\fR] [-o \fIdirectory\fR] [-i \fIlogfile\fR] [-b \fIblocksize\fR] \fIconfig\fR \fIhostname\fR [\fIdisk\fR [ \fIdate\fR [ \fIlevel\fR [ \fIhostname\fR [...] ] ] ]]
+\fBamfetchdump\fR [-pcClawns] [-d \fIdevice\fR] [-O \fIdirectory\fR] [-i \fIlogfile\fR] [-b \fIblocksize\fR] \fIconfig\fR \fIhostname\fR [\fIdisk\fR [ \fIdate\fR [ \fIlevel\fR [ \fIhostname\fR [...] ] ] ]] [-o \fIconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 \fBAmfetchdump\fR
@@ -60,7 +61,7 @@ Pipe exactly one complete dump file to
 \fB-d\fR \fIdevice\fR
 Restore from this tape device instead of the default.
 .TP
-\fB-o\fR \fIdirectory\fR
+\fB-O\fR \fIdirectory\fR
 Output restored files to this directory, instead of to the current working directory.
 .TP
 \fB-c\fR
@@ -101,6 +102,10 @@ Do not fast-forward straight to needed files on tape. This will slow down most r
 .TP
 \fB-b\fR \fIblocksize\fR
 Force a particular block size when reading from tapes. This value will usually be autodetected, and should not normally need to be set.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .SH "EXAMPLES"
 .PP
 All the examples here assume your configuration is called
index d37950500174762ca138b09d3daf00f8b26d79ad..ec799afee0e9986a62d01c86231d7923cf4827a9 100644 (file)
 amflush - flush Amanda backup files from holding disk to tape
 .SH "SYNOPSIS"
 .HP 8
-\fBamflush\fR [-b] [-f] [-s] [-D \fIdatestamp\fR...] \fIconfig\fR [\fIhost\fR [\fIdisk\fR...]...]
+\fBamflush\fR [-b] [-f] [-s] [-D \fIdatestamp\fR]*
+     \fIconfig\fR [\fIhost\fR [\fIdisk\fR]*]*
+     [-o \fIconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 \fBAmflush\fR
@@ -66,6 +69,13 @@ specify a datestamp expression you want to flush, see the "DATESTAMP EXPRESSION"
 for a description.
 \fB-D 20001225-7\fR
 will flush all dumps from 25 december 2000 to 27 december 2000.
+.TP
+\fIhost\fR [\fIdisk\fR]*
+Specify the host and disk on which the command will work.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .PP
 You can specify many host/disk expressions, only disks that match an expression will be flushed. All disks are flushed if no expressions are given. see the "HOST & DISK EXPRESSION" section of
 \fBamanda\fR(8)
index fa4f2eaa71f8054dde0c0c2e869a84ac60628e76..bf0d35c503d7355316db6d32adbe38a8c2db7ed9 100644 (file)
@@ -22,7 +22,8 @@
 amgetconf - look up amanda.conf variables
 .SH "SYNOPSIS"
 .HP 10
-\fBamgetconf\fR [\fIconfig\fR] \fIparameter\fR
+\fBamgetconf\fR [\fIconfig\fR] \fIparameter\fR [-o \fIconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 \fBAmgetconf\fR
@@ -66,6 +67,11 @@ See the
 \fBamanda\fR(8)
 man page for more details about
 \fBAmanda\fR.
+.SH "OPTIONS"
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .SH "EXAMPLE"
 .PP
 Find out the path to the log file directory:
@@ -115,9 +121,7 @@ Parameter
 \fBparam\fR
 is not a known keyword (e.g. not a valid
 \fBamanda.conf\fR
-keyword). In this case,
-\fBamgetconf\fR
-will write "\fBBUGGY\fR" to stdout as the value.
+keyword).
 .SH "SEE ALSO"
 .PP
 \fBamanda\fR(8)
index 4a77231ee59836182e9c1d26b82d2ee332a60e5c..aca2ce0b45198d4887eaa6c69c4c26f327c6b67b 100644 (file)
@@ -22,7 +22,8 @@
 amlabel - label an Amanda tape
 .SH "SYNOPSIS"
 .HP 8
-\fBamlabel\fR [-f] \fIconfig\fR \fIlabel\fR [\fIslot\fR \fIslot\fR]
+\fBamlabel\fR [-f] \fIconfig\fR \fIlabel\fR [slot \fIslot\fR] [-o \fIconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 All
@@ -74,6 +75,11 @@ See the
 \fBamanda\fR(8)
 man page for more details about
 \fBAmanda\fR.
+.SH "OPTIONS"
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .SH "EXAMPLE"
 .PP
 Write an
index 32d4b15e44a2dfc8db3a70cfbfd9a7a118708356..40aa455c073eb4b94907f9ae05d66cc265fbc8a2 100644 (file)
@@ -22,7 +22,8 @@
 amrecover - Amanda index database browser
 .SH "SYNOPSIS"
 .HP 10
-\fBamrecover\fR [[-C ] \fIconfig\fR] [-s \fIindex-server\fR] [-t \fItape-server\fR] [-d \fItape-device\fR]
+\fBamrecover\fR [[-C] \fIconfig\fR] [-s \fIindex-server\fR] [-t \fItape-server\fR] [-d \fItape-device\fR] [-o \fIclientconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 \fBAmrecover\fR
@@ -36,6 +37,12 @@ from the root of the backed up filesystem, or use
 \fBlcd\fR
 to move into that directory, otherwise a directory tree that resembles the backed up filesystem will be created in the current directory. See the examples below for details.
 .PP
+Amrecover will read the
+\fBamanda-client.conf\fR
+file and the
+\fIconfig\fR\fB/amanda-client.conf\fR
+file.
+.PP
 See the
 \fBamanda\fR(8)
 man page for more details about
@@ -62,6 +69,10 @@ Host that runs the tape server daemon.
 .TP
 \fB-d tape-device\fR
 Tape device to use on the tape server host.
+.TP
+\fB-o\fR \fIclientconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .SH "COMMANDS"
 .PP
 \fBAmrecover\fR
@@ -75,8 +86,8 @@ of files to be extracted from the backup system. The following commands are avai
 \fBsethost hostname\fR
 Specifies which host to look at backup files for (default: the local host).
 .TP
-\fBsetdate YYYY-MM-DD\fR
-Set the date (default: today). File listing commands only return information on backup images for this day, for the day before with the next lower dump level, and so on, until the most recent level 0 backup on or before the specified date is encountered.
+\fBsetdate YYYY-MM-DD-HH-MM[-SS] | YYYY-MM-DD\fR
+Set the restore time (default: now). File listing commands only return information on backup images for this day, for the day before with the next lower dump level, and so on, until the most recent level 0 backup on or before the specified date is encountered.
 .sp
 For example, if:
 .sp
@@ -88,7 +99,9 @@ For example, if:
 
 .fi
 .sp
-then if 1997-07-08 is the requested date, files from the following days would be used:
+then the command
+\fBsetdate 1997-07-08-00\fR
+would yield files from the following days:
 .sp
 .nf
 
@@ -124,6 +137,10 @@ configuration file. The disk must be local to the host. If
 \fBmountpoint\fR
 is not specified, all pathnames will be relative to the (unknown) mount point instead of full pathnames.
 .TP
+\fBlisthost [diskdevice]\fR
+List all
+\fBhost\fR
+.TP
 \fBlistdisk [diskdevice]\fR
 List all
 \fBdiskname\fR
@@ -387,6 +404,12 @@ and
 commands will use $PAGER to display the file lists. Defaults to
 \fBmore\fR
 if PAGER is not set.
+.PP
+\fBAMANDA_SERVER\fR
+If set, $AMANDA_SERVER will be used as index-server. The value will take precedence over the compiled default, but will be overridden by the -s switch.
+.PP
+\fBAMANDA_TAPE_SERVER\fR
+If set, $AMANDA_TAPE_SERVER will be used as tape-server. The value will take precedence over the compiled default, but will be overridden by the -t switch.
 .SH "AUTHOR"
 .PP
 Alan M. McIvor
@@ -399,6 +422,7 @@ Stefan G. Weichinger,
 .SH "SEE ALSO"
 .PP
 \fBamanda\fR(8),
+\fBamanda-client.conf\fR(5),
 \fBamrestore\fR(8),
 \fBamfetchdump\fR(8),
 \fBreadline\fR(3)
index 2a44b0f8b489e1f233e7878e9c3358437a0af73a..469ecc301e1592466bd7937ff161eef9864a749f 100644 (file)
@@ -22,7 +22,8 @@
 amreport - generate a formatted output of statistics for an Amanda run
 .SH "SYNOPSIS"
 .HP 9
-\fBamreport\fR [\fIconfig\fR] [-l \fIlogfile\fR] [-f \fIoutputfile\fR] [-p \fIpostscriptfile\fR]
+\fBamreport\fR [\fIconfig\fR] [-i] [-M \fIaddress\fR] [-l \fIlogfile\fR] [-f \fIoutputfile\fR] [-p \fIpostscriptfile\fR] [-o \fIconfigoption\fR]*
+
 .SH "DESCRIPTION"
 .PP
 \fBAmreport\fR
@@ -39,6 +40,17 @@ man page for more details about
 \fBconfig\fR
 Name of the configuration to process.
 .TP
+\fB-i\fR
+Don't email the report.
+.TP
+\fB-M\fR \fIaddress\fR
+Mail the report to
+\fBaddress\fR
+instead of the
+\fBmailto\fR
+value from
+\fBamanda.conf\fR.
+.TP
 \fB-l\fR \fIlogfile\fR
 Name of the log file to parse to generate the report. If a log file is not specified, it defaults to the file:
 .PP
@@ -66,6 +78,10 @@ instead of to the
 command. This option has an effect only if the
 \fBlbl-templ\fR
 directive is specified in amanda.conf.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .SH "LABEL PRINTING"
 .PP
 \fBAmanda\fR
index feb8d4e4db429784aff7f9f41ef4f11d67c69af2..15849198be90a42b12e4852db4ec644c8579e251 100644 (file)
@@ -22,7 +22,7 @@
 amrestore - extract backup images from an Amanda tape
 .SH "SYNOPSIS"
 .HP 10
-\fBamrestore\fR [-r -c -C] [-b \fIblocksize\fR] [-f \fIfileno\fR] [-l \fIlabel\fR] [-p] [-h] \fItapedevice\fR \fIholdingfile\fR [\fIhostname\fR [\fIdiskname\fR [\fIdatestamp\fR [\fIhostname\fR [\fIdiskname\fR [\fIdatestamp\fR...]]]]]] 
+\fBamrestore\fR [-r -c -C] [-b \fIblocksize\fR] [-f \fIfileno\fR] [-l \fIlabel\fR] [-p] [-h] \fItapedevice\fR| \fIholdingfile\fR  [\fIhostname\fR [\fIdiskname\fR [\fIdatestamp\fR [\fIhostname\fR [\fIdiskname\fR [\fIdatestamp\fR ...]]]]]]
 .SH "DESCRIPTION"
 .PP
 \fBAmrestore\fR
@@ -163,6 +163,10 @@ may also be used to compress the result.
 uses the header to determine the restore program to use.
 .PP
 If a header is written (-r or -h), only 32 KBytes are output regardless of the tape blocksize. This makes the resulting image usable as a holding file.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
 .SH "EXAMPLES"
 .PP
 The following does an interactive restore of disk
index f1cced6b70f70a03e4ea995ce856e5ba29c04a4f..818b3182ff8899604d6a383cad3121f9011285c3 100644 (file)
@@ -22,7 +22,7 @@
 amtapetype - generate a tapetype definition.
 .SH "SYNOPSIS"
 .HP 11
-\fBamtapetype\fR [-h] [-c] [-o] [-b \fIblocksize\fR] [-e \fIestsize\fR] [-f \fItapedev\fR] [-t \fItypename\fR]
+\fBamtapetype\fR [-h] [-c] [-o] [-b \fIblocksize\fR] -e \fIestsize\fR [-f \fItapedev\fR] [-t \fItypename\fR]
 .SH "DESCRIPTION"
 .PP
 \fBamtapetype\fR
@@ -45,7 +45,7 @@ tape.
 record block size (default: 32k)
 .TP
 \fB-e\fR\fI estsize\fR
-estimated tape size (default: 1g == 1024m)
+estimated tape size (No default!)
 .TP
 \fB-f\fR\fI tapedev\fR
 tape device name (default: $TAPE) The device to perform the test.
@@ -58,7 +58,7 @@ Generate a tapetype definition for your tape device:
 .sp
 .nf
 
-% amtapetype -f /dev/nst0
+% amtapetype -f /dev/nst0 -e 150G
 
 .fi
 .SH "NOTES"
index 7adc417f9faa9e1fb884f8c4284eba44bce914f3..99f9e49240d71defa29b3643656c293a3b7aab93 100644 (file)
@@ -11,6 +11,7 @@
 <!-- IDs for AMANDA files-->
 <!ENTITY amandaddebug ' <filename>amandad.debug</filename>'>
 <!ENTITY amconf '<filename>amanda.conf</filename>'>
+<!ENTITY amclientconf '<filename>amanda-client.conf</filename>'>
 <!ENTITY amandahosts '<filename>.amandahosts</filename>'>
 <!ENTITY disklist '<filename>disklist</filename>'>
 <!ENTITY amandapass '<filename>/etc/amandapass</filename>'>
 <!ENTITY amcheckdb ' <command>amcheckdb</command>'>
 <!ENTITY amcleanup ' <command>amcleanup</command>'>
 <!ENTITY amcrypt ' <command>amcrypt</command>'>
+<!ENTITY amcryptsimple ' <command>amcryptsimple</command>'>
+<!ENTITY amcryptossl ' <command>amcrypt-ossl</command>'>
+<!ENTITY amcryptosslasym ' <command>amcrypt-ossl-asym</command>'>
+<!ENTITY amgpgcrypt ' <command>amgpgcrypt</command>'>
 <!ENTITY amdd ' <command>amdd</command>'>
+<!ENTITY amaddclient ' <command>amaddclient</command>'>
 <!ENTITY amdump ' <command>amdump</command>'>
 <!ENTITY amflush ' <command>amflush</command>'>
 <!ENTITY amgetconf ' <command>amgetconf</command>'>
@@ -39,6 +45,7 @@
 <!ENTITY amreport ' <command>amreport</command>'>
 <!ENTITY amrestore ' <command>amrestore</command>'>
 <!ENTITY amrmtape ' <command>amrmtape</command>'>
+<!ENTITY amserverconfig ' <command>amserverconfig</command>'>
 <!ENTITY amstatus ' <command>amstatus</command>'>
 <!ENTITY amtape ' <command>amtape</command>'>
 <!ENTITY amtapetype ' <command>amtapetype</command>'>
index ec1bd2c2b1fe2a8907627ec281abbced46a3e8c2..f87864efe92c2120796be78cac612db86c5a5d8e 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-   $Id: xinclude.dtd,v 1.1 2005/11/19 00:51:20 paddy_s Exp $
+   $Id: xinclude.dtd,v 1.2 2006/05/25 01:47:13 johnfranks Exp $
 
  The XInclude DTD is from
 
index 5cfc4b411a4d6c444fef7afd63d3fa4369c3b8a1..d98bd78e62868cfab88b21be5ab077ae9066142f 100644 (file)
@@ -24,7 +24,8 @@
   <command>amadmin</command>    
     <arg choice='plain'><replaceable>config</replaceable></arg>
     <arg choice='plain'><replaceable>command</replaceable></arg>
-    <arg choice='opt'><arg choice='plain'><replaceable>command</replaceable></arg><arg choice='plain'><replaceable>options</replaceable></arg></arg>
+    <group><replaceable><arg choice='plain'>command</arg><arg choice='plain'>options</arg></replaceable></group>
+    <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -245,6 +246,15 @@ on
 Mostly used for debugging.</para>
   </listitem>
   </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>"
+ section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+
 </variablelist>
 </refsect1>
 
index d08370e66bceee0da89a91b5dcc55489f77c036f..a902e5e88a72ff43258c48c59f980d5fae6169c4 100755 (executable)
@@ -25,7 +25,7 @@
 
 <refsect1><title>DESCRIPTION</title>
 <para>&amaespipe;
-requires <emphasis remap='B'>aespipe</emphasis> and <emphasis remap='B'>gpg</emphasis> to work.
+requires <emphasis remap='B'>aespipe</emphasis>, <emphasis remap='B'>uuencode</emphasis> and <emphasis remap='B'>gpg</emphasis> to work.
 Aespipe is available from <ulink url="http://loop-aes.sourceforge.net"/></para>
 <para>&amaespipe; will search for the aespipe program in the following directories:
 /usr/bin:/usr/local/bin:/sbin:/usr/sbin. </para>
diff --git a/man/xml-source/amanda-client.conf.5.xml b/man/xml-source/amanda-client.conf.5.xml
new file mode 100644 (file)
index 0000000..1433e20
--- /dev/null
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+                   "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"
+[
+  <!-- entities files to use -->
+  <!ENTITY % global_entities SYSTEM '../entities/global.entities'>
+  %global_entities;
+]>
+
+<refentry id='amanda-client.conf.5'>
+
+<refmeta>
+<refentrytitle>amanda-client.conf</refentrytitle>
+<manvolnum>5</manvolnum>
+</refmeta>
+<refnamediv>
+<refname>amanda-client.conf</refname>
+<refpurpose>Client configuration file for &A;, the Advanced Maryland Automatic Network Disk Archiver</refpurpose>
+</refnamediv>
+<!-- body begins here -->
+
+<refsect1><title>DESCRIPTION</title>
+<para>&amclientconf; is the client configuration file for &A;. This manpage lists the
+relevant sections and parameters of this file for quick reference.</para> 
+<para> The files <emphasis remap='B'>&lt;CONFIG_DIR&gt;/amanda-client.conf</emphasis> and <emphasis remap='B'>&lt;CONFIG_DIR&gt;/&lt;config&gt;/amanda-client.conf</emphasis> are loaded.</para>
+</refsect1>
+
+<refsect1><title>PARAMETERS</title>
+
+<para>There are a number of configuration parameters that control the
+behavior of the &A; programs.
+All have default values,
+so you need not specify the parameter in
+<emphasis remap='B'>amanda-client.conf</emphasis>
+if the default is suitable.</para>
+
+<para>Lines starting with # are ignored, as are blank lines.
+Comments may be placed on a line with a directive by starting
+the comment with a #.
+The remainder of the line is ignored.</para>
+
+<para>Keywords are case insensitive, i.e.
+<emphasis remap='B'>auth</emphasis>
+and
+<emphasis remap='B'>Auth</emphasis>
+are treated the same.</para>
+
+<para>Integer arguments may have one of the following (case insensitive) suffixes,
+some of which have a multiplier effect:</para>
+
+<refsect2><title>POSSIBLE SUFFIXES</title>
+
+<variablelist remap='TP'>
+  <varlistentry>
+  <term><emphasis remap='B'>b byte bytes</emphasis></term>
+  <listitem>
+<para>Some number of bytes.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>bps</emphasis></term>
+  <listitem>
+<para>Some number of bytes per second.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>k kb kbyte kbytes kilobyte kilobytes</emphasis></term>
+  <listitem>
+<para>Some number of kilobytes (bytes*1024).</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>kps kbps</emphasis></term>
+  <listitem>
+<para>Some number of kilobytes per second (bytes*1024).</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>m mb meg mbyte mbytes megabyte megabytes</emphasis></term>
+  <listitem>
+<para>Some number of megabytes (bytes*1024*1024).</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>mps mbps</emphasis></term>
+  <listitem>
+<para>Some number of megabytes per second (bytes*1024*1024).</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>g gb gbyte gbytes gigabyte gigabytes</emphasis></term>
+  <listitem>
+<para>Some number of gigabytes (bytes*1024*1024*1024).</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>tape tapes</emphasis></term>
+  <listitem>
+<para>Some number of tapes.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>day days</emphasis></term>
+  <listitem>
+<para>Some number of days.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>week weeks</emphasis></term>
+  <listitem>
+<para>Some number of weeks (days*7).</para>
+
+<note>The value
+<emphasis remap='B'>inf</emphasis>
+may be used in most places where an integer is expected
+to mean an infinite amount.
+
+<para>Boolean arguments may have any of the values
+<emphasis remap='B'>y</emphasis>,
+<emphasis remap='B'>yes</emphasis>,
+<emphasis remap='B'>t</emphasis>,
+<emphasis remap='B'>true</emphasis>
+or
+<emphasis remap='B'>on</emphasis>
+to indicate a true state, or
+<emphasis remap='B'>n</emphasis>,
+<emphasis remap='B'>no</emphasis>,
+<emphasis remap='B'>f</emphasis>,
+<emphasis remap='B'>false</emphasis>
+or
+<emphasis remap='B'>off</emphasis>
+to indicate a false state.
+If no argument is given,
+<emphasis remap='B'>true</emphasis>
+is assumed.
+</para>
+</note>
+  </listitem>
+  </varlistentry>
+</variablelist>
+</refsect2>
+
+<refsect2>
+<title>PARAMETERS</title>
+
+<variablelist remap='TP'>
+  <varlistentry>
+  <term><emphasis remap='B'>conf</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default:
+<emphasis remap='I'>Set by configure</emphasis>.
+The conf use by amrecover.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>index_server</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default:
+<emphasis remap='I'>Set by configure</emphasis>.
+The amindexd server amrecover will connect to.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>tape_server</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default:
+<emphasis remap='I'>Set by configure</emphasis>.
+The amidxtaped server amrecover will connect to.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>tapedev</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default:
+<emphasis remap='I'>Set by configure</emphasis>.
+The tapedev amrecover will use.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>auth</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default:
+<emphasis remap='I'>bsd</emphasis>.
+Type of authorization to perform between tape server and backup client hosts.</para>
+<para><emphasis remap='B'>bsd</emphasis>, bsd authorization with udp initial
+connection and one tcp connection by data stream.</para>
+<para><emphasis remap='B'>bsdtcp</emphasis>, bsd authorization but use only
+one tcp connection.</para>
+<para><emphasis remap='B'>bsdudp</emphasis>, like bsd, but will use only one
+tcp connection for all data stream.</para>
+<para><emphasis remap='B'>krb4</emphasis> to use Kerberos-IV
+authorization.</para>
+<para><emphasis remap='B'>krb5</emphasis> to use Kerberos-V
+authorization.</para>
+<para><emphasis remap='B'>rsh</emphasis> to use rsh
+authorization.</para>
+<para><emphasis remap='B'>ssh</emphasis> to use OpenSSH
+authorization.</para>
+
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>ssh_keys</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default:
+<emphasis remap='I'>No default</emphasis>.
+The key file the ssh auth will use, it must be the private key. If this parameter is not specified, then the deafult ssh key will be used.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>gnutar_list_dir</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default from configure 
+<emphasis remap='I'>--with-gnutar-listdir=DIR</emphasis>.
+The directory where gnutar keep its state file.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>amandates</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default: 
+<emphasis remap='I'>/etc/amandates</emphasis>.
+The file where amanda keep the last date of each dumplevel.</para>
+  </listitem>
+  </varlistentry>
+
+</variablelist>
+</refsect2>
+</refsect1>
+
+<refsect1><title>AUTHOR</title>
+<para>James da Silva, &email.jds;: Original text</para>
+<para>&maintainer.sgw;: XML-conversion, major update, splitting</para>
+</refsect1>
+
+<refsect1><title>SEE ALSO</title>
+<para>
+<citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amanda.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amcrypt</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>aespipe</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+</para>
+</refsect1>
+</refentry>
+
index 493bb74797296cbce4722f125b71ac5f8f637cc1..c4b161cc22baa015ee3575aaad2a64e00785aa6e 100644 (file)
@@ -629,7 +629,7 @@ a new dumptype:</para>
 <programlisting>
 <emphasis remap='I'>hostname diskname</emphasis> [ <emphasis remap='I'>diskdevice</emphasis> ] {
   normal
-  holdingdisk no
+  holdingdisk never
 } [ <emphasis remap='I'>spindle</emphasis> [ <emphasis remap='I'>interface</emphasis> ] ]
 </programlisting>
 
@@ -871,7 +871,9 @@ file is:</para>
 <para><emphasis remap='I'>hostname</emphasis>
 [
 <emphasis remap='I'>username</emphasis>
-]</para>
+[
+<emphasis remap='I'>service</emphasis>
+]*]</para>
 
 <para>If
 <emphasis remap='I'>username</emphasis>
@@ -882,6 +884,15 @@ i.e. the user listed in the
 or
 <emphasis remap='B'>xinetd</emphasis>
 configuration file.</para>
+<para>The <emphasis remap='I'>service</emphasis> is a list of the service the client is authorized to execute:
+<emphasis remap='B'>amdump</emphasis>,
+<emphasis remap='B'>noop</emphasis>,
+<emphasis remap='B'>selfcheck</emphasis>,
+<emphasis remap='B'>sendsize</emphasis>,
+<emphasis remap='B'>sendbackup</emphasis>,
+<emphasis remap='B'>amindexd</emphasis>,
+<emphasis remap='B'>amidxtaped</emphasis>.
+<emphasis remap='B'>amdump</emphasis> is a shortcut for "noop selfcheck sendsize sendbackup"</para>
   </listitem>
   </varlistentry>
   <varlistentry>
@@ -908,10 +919,11 @@ For instance:</para>
 
 <programlisting>
   //some-pc/home normalpw
-  //another-pc/disk otheruser%otherpw</programlisting>
+  //another-pc/disk otheruser%otherpw
+</programlisting>
 
-<para>With clear text passwords, this file should obviously be tightly protected.
-It only needs to be readable by the &A;-user on the Samba server.</para>
+With clear text passwords, this file should obviously be tightly protected.
+It only needs to be readable by the &A;-user on the Samba server.
 
 <para>You can find further information in the
 <emphasis remap='B'>docs/SAMBA</emphasis>
@@ -1025,6 +1037,18 @@ Leading ^ is removed. Trailing $ forces an exact match.</para>
 </informaltable>
 <para/>
 
+</refsect1>
+
+<refsect1><title>CONFIGURATION OVERWRITE</title>
+<para>Most command allow to overwrite any configuration parameter on
+the command line with the -o option.</para>
+<para>-o NAME=value</para>
+<para>eg. -o runtapes=2</para>
+<para>eg. -o DUMPTYPE:no-compress:compress="server fast"</para>
+<para>eg. -o TAPETYPE:HP-DAT:length=2000m</para>
+<para>eg. -o INTERFACE:local:use="2000 kbps"</para>
+
+
 </refsect1>
 
 <refsect1><title>AUTHOR</title>
@@ -1036,6 +1060,7 @@ Leading ^ is removed. Trailing $ forces an exact match.</para>
 <para>
 <citerefentry><refentrytitle>amadmin</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>amanda.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amanda-client.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>amcheck</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>amcheckdb</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>amcleanup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
index a608c3aad8e9bea1cee87b790a6e9aaa30595636..78057a4cea08e02b79eb6f064ef26f6d9eda6545 100644 (file)
@@ -22,6 +22,7 @@
 <refsect1><title>DESCRIPTION</title>
 <para>&amconf; is the main configuration file for &A;. This manpage lists the
 relevant sections and parameters of this file for quick reference.</para> 
+<para> The file <emphasis remap='B'>&lt;CONFIG_DIR&gt;/&lt;config&gt;/amanda.conf</emphasis> is loaded.</para>
 </refsect1>
 
 <refsect1><title>PARAMETERS</title>
@@ -227,32 +228,29 @@ with damaged or misplaced tapes or schedule adjustments that call for slight adj
   </varlistentry>
 
   <varlistentry>
-  <term><emphasis remap='B'>label_new_tapes</emphasis>
-        <emphasis remap='I'> string</emphasis></term>
-<listitem>
-    <para>Default: not set.
-When set, this directive will cause &A; to automatically write an &A;
-tape label to any blank tape she encounters. This option is DANGEROUS 
-because when set, &A; will ERASE any non-&A; tapes you may have, and may 
-also ERASE any near-failing tapes. Use with caution.</para>
-<para>When using this directive, specify the template for new tape 
-labels. The template should contain some number of contiguous '%' 
-characters, which will be replaced with a generated number. Be sure to 
-specify enough '%' characters that you do not run out of tape labels. 
-Example: 
-<markup>label_new_tapes "DailySet1-%%%"</markup>
-</para>
-</listitem>
-</varlistentry>
+  <term><emphasis remap='B'>usetimestamps</emphasis>
+       <emphasis remap='I'> bool</emphasis></term>
+    <listitem>
+      <para>Default: <emphasis remap='B'>No</emphasis>.
+By default, Amanda can only track at most one run per calendar day. When
+this option is enabled, however, Amanda can track as many runs as you care
+to make.
+      </para>
+      <para>
+<emphasis remap='B'>WARNING</emphasis>: This option is not backward-compatible.
+Do not enable it if you intend to downgrade your server installation to
+Amanda community edition 2.5.0
+      </para>
+    </listitem>
+  </varlistentry>
 
   <varlistentry>
-=======
   <term><emphasis remap='B'>label_new_tapes</emphasis>
         <emphasis remap='I'> string</emphasis></term>
 <listitem>
     <para>Default: not set.
-When set, this directive will cause &A; to automatically write an Amanda 
-tape label to any black tape she encounters. This option is DANGEROUS 
+When set, this directive will cause &A; to automatically write an &A;
+tape label to any blank tape she encounters. This option is DANGEROUS 
 because when set, &A; will ERASE any non-&A; tapes you may have, and may 
 also ERASE any near-failing tapes. Use with caution.</para>
 <para>When using this directive, specify the template for new tape 
@@ -787,7 +785,7 @@ Whether an amdump run will flush the dumps from holding disk to tape.</para>
   <term><emphasis remap='B'>amrecover_do_fsf</emphasis> <emphasis remap='I'> bool</emphasis></term>
   <listitem>
 <para>Default:
-<emphasis remap='I'>off</emphasis>.
+<emphasis remap='I'>on</emphasis>.
 Amrecover will call amrestore with the -f flag for faster positioning of the tape.</para>
   </listitem>
   </varlistentry>
@@ -795,7 +793,7 @@ Amrecover will call amrestore with the -f flag for faster positioning of the tap
   <term><emphasis remap='B'>amrecover_check_label</emphasis> <emphasis remap='I'> bool</emphasis></term>
   <listitem>
 <para>Default:
-<emphasis remap='I'>off</emphasis>.
+<emphasis remap='I'>on</emphasis>.
 Amrecover will call amrestore with the -l flag to check the label.</para>
   </listitem>
   </varlistentry>
@@ -881,7 +879,8 @@ The syntax is:</para>
 holdingdisk <emphasis remap='I'>name</emphasis> {
     <emphasis remap='I'>holdingdisk-option</emphasis> <emphasis remap='I'>holdingdisk-value</emphasis>
     <literal>...</literal>
-}</programlisting>
+}
+</programlisting>
 
 <para><emphasis remap='I'>Name</emphasis>
 is a logical name for this holding disk.</para>
@@ -991,16 +990,44 @@ are defined.</para>
 <para>Default:
 <emphasis remap='I'>bsd</emphasis>.
 Type of authorization to perform between tape server and backup client hosts.</para>
+<para><emphasis remap='B'>bsd</emphasis>, bsd authorization with udp initial
+connection and one tcp connection by data stream.</para>
+<para><emphasis remap='B'>bsdtcp</emphasis>, bsd authorization but use only
+one tcp connection.</para> 
+<para><emphasis remap='B'>bsdudp</emphasis>, like bsd, but will use only one
+tcp connection for all data stream.</para>
 <para><emphasis remap='B'>krb4</emphasis> to use Kerberos-IV
 authorization.</para>
 <para><emphasis remap='B'>krb5</emphasis> to use Kerberos-V
 authorization.</para>
+<para><emphasis remap='B'>rsh</emphasis> to use rsh
+authorization.</para>
 <para><emphasis remap='B'>ssh</emphasis> to use OpenSSH
 authorization.</para>
 
   </listitem>
   </varlistentry>
 
+  <varlistentry>
+  <term><emphasis remap='B'>amandad_path</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default:
+<emphasis remap='I'>$libexec/amandad</emphasis>.
+Specify the amandad path of the client, only use with rsh/ssh authentification.
+</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>client_username</emphasis> <emphasis remap='I'> string</emphasis></term>
+  <listitem>
+<para>Default:
+<emphasis remap='I'>CLIENT_LOGIN</emphasis>.
+Specify the username to connect on the client, only use with rsh/ssh authentification.
+</para>
+  </listitem>
+  </varlistentry>
+
 <!-- bumping parameters yanked from the global section above -->
 
   <varlistentry>
@@ -1171,13 +1198,14 @@ server host as it goes from the network into the holding disk or to tape.</para>
 <para>PROG must not contain white space.</para>
 <para>Specify client_decrypt_option &quot;decryption-parameter&quot; Default: &quot;-d&quot;</para>
 <para>decryption-parameter must not contain white space.</para>
-<para>(See dumptype encrypt-fast in example/amanda.conf for reference)</para>
+<para>(See dumptype server-encrypt-fast in example/amanda.conf for reference)</para>
 </listitem>
 <listitem><para>encrypt server</para>
 <para>Specify server_encrypt &quot;PROG&quot;</para>
 <para>PROG must not contain white space.</para>
 <para>Specify server_decrypt_option &quot;decryption-parameter&quot; Default: &quot;-d&quot;</para>
 <para>decryption-parameter must not contain white space.</para>
+<para>(See dumptype client-encrypt-nocomp in example/amanda.conf for reference)</para>
 </listitem>
 </itemizedlist>
 </listitem>
@@ -1186,7 +1214,7 @@ backup(thus decrypt then uncompress during restore). So specifying
 client-encryption AND server-compression is not supported.
 <emphasis remap='I'>amcrypt</emphasis> which is a wrapper of
            <emphasis remap='I'>aespipe</emphasis> is provided as a reference
-               encryption program.</para>
+               symmetric encryption program.</para>
 </varlistentry>
 
 
@@ -1271,17 +1299,39 @@ for a backup of <filename>/var</filename>,
 </varlistentry>
 
   <varlistentry>
-  <term><emphasis remap='B'>holdingdisk</emphasis> <emphasis remap='I'> boolean</emphasis></term>
+  <term><emphasis remap='B'>holdingdisk</emphasis> [ <emphasis remap='I'>never|auto|required]</emphasis> ]</term>
   <listitem>
 <para>Default:
-<emphasis remap='I'>yes</emphasis>.
+<emphasis remap='I'>auto</emphasis>.
 Whether a holding disk should be used for these backups or whether they should go directly to tape.
 If the holding disk is a portion of another file system that &A;
 is backing up, that file system should refer to a dumptype with
 <emphasis remap='B'>holdingdisk</emphasis>
 set to
-<emphasis remap='I'>no</emphasis>
+<emphasis remap='I'>never</emphasis>
 to avoid backing up the holding disk into itself.</para>
+
+  <variablelist remap='TP'>
+  <varlistentry>
+  <term><emphasis remap='B'>never</emphasis>|no|false|off</term>
+  <listitem>
+  <para>Never use a holdingdisk, the dump will always go directly to tape. There will be no dump if you have a tape error.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>auto</emphasis>|yes|true|on</term>
+  <listitem>
+  <para>Use the holding disk, unless there is a problem with the holding disk, the dump won't fit there or the medium doesn't require spooling (e.g., VFS device)</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>required</emphasis></term>
+  <listitem>
+  <para>Always dump to holdingdisk, never directly to tape. There will be no dump if it doesn't fit on holdingdisk</para>
+  </listitem>
+  </varlistentry>
+  </variablelist>
+
   </listitem>
   </varlistentry>
 
@@ -1803,6 +1853,7 @@ At the moment, this is of little use.</para>
 <refsect1><title>SEE ALSO</title>
 <para>
 <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amanda-client.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>amcrypt</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>aespipe</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
 </para>
index f4a17cba85b34662163a810c87da88410db69fea..e3b18d49773060503d9707ecac36845ce3abb354 100644 (file)
 <refsynopsisdiv>
 <cmdsynopsis>
   <command>amcheck</command>    
-    <arg choice='opt'>-mwsclt </arg>
-    <arg choice='opt'>-Maddress </arg>
+    <arg choice='opt'>-am</arg>
+    <arg choice='opt'>-w</arg>
+    <arg choice='opt'>-sclt</arg>
+    <group><arg choice='plain'>-M</arg><arg choice='plain'><replaceable>address</replaceable></arg></group>*
     <arg choice='plain'><replaceable>config</replaceable></arg>
-    <arg choice='opt' rep='repeat'><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt' rep='repeat'><replaceable>disk</replaceable></arg></arg>
-    
+    <group><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt'><replaceable>disk</replaceable></arg>*</group>*
+    <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -68,7 +70,8 @@ man page for more details about &A;.</para>
   <varlistentry>
   <term><option>-c</option></term>
   <listitem>
-<para>Run the client host checks.</para>
+<para>Run the client host checks.Multiple specific clients can be 
+checked by specifying the client name.</para>
   </listitem>
   </varlistentry>
   <varlistentry>
@@ -94,8 +97,7 @@ If the tape
 is writable, this check causes all data after the tape label to be
 erased. If the label_new_tapes option is enabled, this check may ERASE
 any non-Amanda tape in the drive or changer.
-The check implies
-<option>-t</option>
+The check enable the tape tests on the server host
 and is only made if the tape is otherwise correct.</para>
   </listitem>
   </varlistentry>
@@ -122,8 +124,9 @@ is set.</para>
 but the mail is always sent.</para>
   </listitem>
   </varlistentry>
+
   <varlistentry>
-  <term><option>-M</option><replaceable>address</replaceable></term>
+  <term><option>-M</option> <replaceable>address</replaceable></term>
   <listitem>
 <para>Mail the report to
 <emphasis remap='I'>address</emphasis>
@@ -135,6 +138,20 @@ Implies
 <option>-m</option>.</para>
   </listitem>
   </varlistentry>
+
+  <varlistentry>
+  <term><replaceable>host</replaceable> [<replaceable>disk</replaceable>]*</term>
+  <listitem>
+<para>Specify the host and disk on which the command will work.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
 </variablelist>
 
 <para>The default is
index 11a36bc890207ebf3c629dbfa4670872dd24415b..4d235cf07caf6136edc0c7e9c369040646b2062b 100644 (file)
@@ -45,6 +45,17 @@ must be run some time later (usually during system boot).</para>
 man page for more details about &A;.</para>
 </refsect1>
 
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+  <varlistentry>
+  <term><option>-k</option></term>
+  <listitem>
+   <para>Kill all Amanda processes.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+</refsect1>
+
 <refsect1><title>EXAMPLES</title>
 <para>This example runs the &A; cleanup process by hand after
 a failure.</para>
diff --git a/man/xml-source/amcrypt-ossl-asym.8.xml b/man/xml-source/amcrypt-ossl-asym.8.xml
new file mode 100644 (file)
index 0000000..736fcd6
--- /dev/null
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+                   "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"
+[
+  <!-- entities files to use -->
+  <!ENTITY % global_entities SYSTEM '../entities/global.entities'>
+  %global_entities;
+]>
+
+<refentry id='amcrypt-asym-ossl.8'>
+
+<refmeta>
+  <refentrytitle>amcrypt-ossl-asym</refentrytitle>
+  <manvolnum>8</manvolnum>
+</refmeta>
+<refnamediv>
+  <refname>amcrypt-ossl-asym</refname>
+  <refpurpose>crypt program for &A; asymmetric data encryption using OpenSSL</refpurpose>
+</refnamediv>
+<!-- body begins here -->
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>amcrypt-ossl-asym</command>    
+    <arg choice="opt">-d</arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+<refsect1>
+  <title>DESCRIPTION</title>
+  <para>
+    &amcryptosslasym; uses <emphasis remap='B'>OpenSSL</emphasis> to
+    encrypt and decrypt data. OpenSSL is available from <ulink
+    url="http://www.openssl.org/">www.openssl.org</ulink>. OpenSSL
+    offers a wide variety of cipher choices (&amcryptosslasym; defaults
+    to 256-bit AES) and can use hardware cryptographic accelerators on
+    several platforms.
+  </para>
+  <para>
+    &amcryptosslasym; will search for the OpenSSL program in the following
+    directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+  </para>
+</refsect1>
+<refsect1>
+  <title>GENERATING PUBLIC AND PRIVATE KEYS</title>
+  <para>
+    RSA keys can be generated with the standard OpenSSL commands, e.g.:
+  </para>
+  <programlisting>
+$ cd /var/lib/amanda
+$ openssl genrsa -aes128 -out backup-privkey.pem 1024
+Generating RSA private key, 1024 bit long modulus
+[...]
+Enter pass phrase for backup-privkey.pem: <emphasis remap='I'>ENTER YOUR PASS PHRASE</emphasis>
+Verifying - Enter pass phrase for backup-key.pem: <emphasis remap='I'>ENTER YOUR PASS PHRASE</emphasis>
+
+$ openssl rsa -in backup-privkey.pem -pubout -out backup-pubkey.pem
+Enter pass phrase for backup-privkey.pem: <emphasis remap='I'>ENTER YOUR PASS PHRASE</emphasis>
+Writing RSA key
+
+</programlisting>
+  <para>
+    To generate a private key without a passphrase, omit the
+    <option>-aes128</option> option. See
+    <citerefentry><refentrytitle>openssl_genrsa</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    for more key generation options.
+  </para>
+  <para>
+    Note that it is always possible to generate the public key from the
+    private key.
+  </para>
+</refsect1>
+<refsect1>
+  <title>KEY AND PASSPHRASE MANAGEMENT</title>
+  <para>
+    &amcryptosslasym; uses the <emphasis remap='I'>public key</emphasis>
+    to encrypt data. The security of the data does not depend on the
+    confidentiality of the public key. The <emphasis remap='I'>private
+    key</emphasis> is used to decrypt data, and must be protected.
+    Encrypted backup data cannot be recovered without the private key.
+    The private key may optionally be encrypted with a passphrase.
+  </para>
+  <para>
+    While the public key must be online at all times to perorm backups,
+    the private key and optional passphrase are only needed to restore
+    data. It is recommended that the latter be stored offline all other
+    times. For example, you could keep the private key on removable media,
+    and copy it into place for a restore; or you could keep the private
+    key online, encrypted with a passphrase that is present only for a
+    restore.
+  </para>
+  <para>
+    OpenSSL's key derivation routines use a salt to guard against
+    dictionary attacks on the pass phrase; still it is important to pick
+    a pass phrase that is hard to guess. The Diceware method (see <ulink
+    url="http://www.diceware.com/">www.diceware.com</ulink>) can
+    be used to create passphrases that are difficult to guess and easy to
+    remember.
+  </para>
+</refsect1>
+<refsect1>
+  <title>FILES</title>
+  <variablelist remap='TP'>
+    <varlistentry>
+      <term>/var/lib/amanda/backup-privkey.pem</term>
+      <listitem>
+       <para>
+         File containing the RSA private key. It should not be readable
+         by any user other than the &A; user.
+       </para>
+      </listitem>
+    </varlistentry>
+    <varlistentry>
+      <term>/var/lib/amanda/backup-pubkey.pem</term>
+      <listitem>
+       <para>
+         File containing the RSA public key.
+       </para>
+      </listitem>
+    </varlistentry>
+    <varlistentry>
+      <term>/var/lib/amanda/.am_passphrase</term>
+      <listitem>
+       <para>
+         File containing the passphrase. It should not be readable by
+         any user other than the &A; user.
+       </para>
+      </listitem>
+    </varlistentry>
+  </variablelist>
+</refsect1>
+<refsect1>
+  <title>SEE ALSO</title>
+  <para>
+    <citerefentry>
+      <refentrytitle>amanda</refentrytitle>
+      <manvolnum>8</manvolnum>
+    </citerefentry>,
+    <citerefentry>
+      <refentrytitle>amanda.conf</refentrytitle>
+      <manvolnum>5</manvolnum>
+    </citerefentry>,
+    <citerefentry>
+      <refentrytitle>openssl</refentrytitle>
+      <manvolnum>1</manvolnum>
+    </citerefentry>,
+    <citerefentry>
+      <refentrytitle>amcrypt-ossl</refentrytitle>
+      <manvolnum>8</manvolnum>
+    </citerefentry>
+  </para>
+</refsect1>
+
+</refentry>
diff --git a/man/xml-source/amcrypt-ossl.8.xml b/man/xml-source/amcrypt-ossl.8.xml
new file mode 100644 (file)
index 0000000..c6ced9e
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+                   "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"
+[
+  <!-- entities files to use -->
+  <!ENTITY % global_entities SYSTEM '../entities/global.entities'>
+  %global_entities;
+]>
+
+<refentry id='amcrypt-ossl.8'>
+
+<refmeta>
+  <refentrytitle>amcrypt-ossl</refentrytitle>
+  <manvolnum>8</manvolnum>
+</refmeta>
+<refnamediv>
+  <refname>amcrypt-ossl</refname>
+  <refpurpose>crypt program for &A; symmetric data encryption using OpenSSL</refpurpose>
+</refnamediv>
+<!-- body begins here -->
+<refsynopsisdiv>
+  <cmdsynopsis>
+    <command>amcrypt-ossl</command>    
+    <arg choice="opt">-d</arg>
+  </cmdsynopsis>
+</refsynopsisdiv>
+<refsect1>
+  <title>DESCRIPTION</title>
+  <para>
+    &amcryptossl; uses <emphasis remap='B'>OpenSSL</emphasis> to encrypt
+    and decrypt data.  OpenSSL is available from <ulink
+    url="http://www.openssl.org/">www.openssl.org</ulink>. OpenSSL
+    offers a wide variety of cipher choices (&amcryptossl; defaults to
+    256-bit AES) and can use hardware cryptographic accelerators on several
+    platforms.
+  </para>
+  <para>
+    &amcryptossl; will search for the OpenSSL program in the following
+    directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+  </para>
+</refsect1>
+<refsect1>
+  <title>PASSPHRASE MANAGEMENT</title>
+  <para>
+    &amcryptossl; uses the same pass phrase to encrypt and decrypt data.
+    It is very important to store and protect the pass phrase properly.
+    Encrypted backup data can <emphasis remap='B'>only</emphasis> be
+    recovered with the correct passphrase.
+  </para>
+  <para>
+    OpenSSL's key derivation routines use a salt to guard against
+    dictionary attacks on the pass phrase; still it is important to pick
+    a pass phrase that is hard to guess.  The Diceware method (see <ulink
+    url="http://www.diceware.com/">www.diceware.com</ulink>) can be used to create passphrases
+    that are difficult to guess and easy to remember.
+  </para>
+</refsect1>
+<refsect1>
+  <title>FILES</title>
+  <variablelist remap='TP'>
+    <varlistentry>
+      <term>/var/lib/amanda/.am_passphrase</term>
+      <listitem>
+       <para>
+         File containing the pass phrase. It should not be readable by any user other than the &A; user.
+       </para>
+      </listitem>
+    </varlistentry>
+  </variablelist>
+</refsect1>
+<refsect1>
+  <title>SEE ALSO</title>
+  <para>
+    <citerefentry>
+      <refentrytitle>amanda</refentrytitle>
+      <manvolnum>8</manvolnum>
+    </citerefentry>,
+    <citerefentry>
+      <refentrytitle>amanda.conf</refentrytitle>
+      <manvolnum>5</manvolnum>
+    </citerefentry>,
+    <citerefentry>
+      <refentrytitle>openssl</refentrytitle>
+      <manvolnum>1</manvolnum>
+    </citerefentry>,
+    <citerefentry>
+      <refentrytitle>amcrypt-ossl-asym</refentrytitle>
+      <manvolnum>8</manvolnum>
+    </citerefentry>
+  </para>
+</refsect1>
+
+</refentry>
index 8a12db1974324266a52ebb734d2da7781ef4009c..09db7be574a2766df764ae4bd0ae62e62b9c2813 100755 (executable)
@@ -26,7 +26,8 @@
 
 <refsect1><title>DESCRIPTION</title>
 <para>&amcrypt; 
-requires <emphasis remap='B'>aespipe</emphasis> and <emphasis
+requires <emphasis remap='B'>aespipe</emphasis>, <emphasis
+remap='B'>uuencode</emphasis> and <emphasis
 remap='B'>gpg</emphasis>  to work. Aespipe is available from <ulink
 url="http://loop-aes.sourceforge.net"/></para>
 <para>&amcrypt; will search for the aespipe program in the following directories:
index 72840c50c532b2640b81866cb633b0f58e417b10..2f60c9d2a5c14c36dfb4390f1f97a640f46ec5b1 100644 (file)
@@ -23,8 +23,8 @@
 <cmdsynopsis>
   <command>amdump</command>    
     <arg choice='plain'><replaceable>config</replaceable></arg>
-    <arg choice='opt' rep='repeat'><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt' rep='repeat'><replaceable>disk</replaceable></arg></arg>
-    
+    <group><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt'><replaceable>disk</replaceable></arg>*</group>*
+    <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -58,6 +58,26 @@ checks for the hold file every minute.</para>
 man page for more details about &A;.</para>
 </refsect1>
 
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+
+  <varlistentry>
+  <term><replaceable>host</replaceable> [<replaceable>disk</replaceable>]*</term>
+  <listitem>
+<para>Specify the host and disk on which the command will work.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+
+</variablelist>
+</refsect1>
+
 <refsect1><title>EXAMPLE</title>
 <para>Here is a typical crontab entry. It runs
 <command>amdump</command>
index a1fcdbe95c587e8474dae4ef5b2ffa930e35516f..39b2b3b3b3fa3034d76a4dd38d2fdae18cc10c90 100644 (file)
@@ -23,7 +23,7 @@
   <command>amfetchdump</command>
     <arg choice='opt'>-pcClawns</arg>
     <arg choice='opt'>-d <replaceable>device</replaceable></arg>
-    <arg choice='opt'>-o <replaceable>directory</replaceable></arg>
+    <arg choice='opt'>-O <replaceable>directory</replaceable></arg>
     <arg choice='opt'>-i <replaceable>logfile</replaceable></arg>
     <arg choice='opt'>-b <replaceable>blocksize</replaceable></arg>
     <arg choice='plain'><replaceable>config</replaceable></arg>
@@ -41,6 +41,7 @@
         </arg>
       </arg>
     </arg>
+    <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -94,7 +95,7 @@ facility).</para></listitem>
 <listitem><para> Restore from this tape device instead of the default.</para></listitem>
   </varlistentry>
   <varlistentry>
-    <term><option>-o</option>
+    <term><option>-O</option>
     <replaceable>directory</replaceable></term>
 <listitem><para>Output restored files to this directory, instead of to the
     current working directory.</para></listitem>
@@ -163,6 +164,15 @@ operation.</para></listitem>
     value will usually be autodetected, and should not normally need
     to be set.</para></listitem>
   </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>"
+ section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+
 </variablelist>
 </refsect1>
 
index 457cc42a8951ceacbb64ac768d19ea478c0b14a3..9ef7256a7624de5da0dec1f7964850956afb5b92 100644 (file)
 <refsynopsisdiv>
 <cmdsynopsis>
   <command>amflush</command>    
-    <arg choice='opt'>-b </arg>
-    <arg choice='opt'>-f </arg>
-    <arg choice='opt'>-s </arg>
-    <arg choice='opt' rep='repeat'><arg choice='plain'>-D </arg><arg choice='plain'><replaceable>datestamp</replaceable></arg></arg>
-    
+    <arg choice='opt'>-b</arg>
+    <arg choice='opt'>-f</arg>
+    <arg choice='opt'>-s</arg>
+    <group><arg choice='plain'>-D</arg><arg choice='plain'><replaceable>datestamp</replaceable></arg></group>*
     <arg choice='plain'><replaceable>config</replaceable></arg>
-    <arg choice='opt' rep='repeat'><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt' rep='repeat'><replaceable>disk</replaceable></arg></arg>
-    
+    <group><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt'><replaceable>disk</replaceable></arg>*</group>*
+    <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -97,6 +96,21 @@ will flush all
 dumps from 25 december 2000 to 27 december 2000.</para>
   </listitem>
   </varlistentry>
+
+  <varlistentry>
+  <term><replaceable>host</replaceable> [<replaceable>disk</replaceable>]*</term>
+  <listitem>
+<para>Specify the host and disk on which the command will work.</para>
+  </listitem>
+  </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+
 </variablelist>
 
 <para>You can specify many host/disk expressions, only disks that
index d824dde4f5eeb17745d3e7cc652c1341b5f4e6c3..0e758445286722f922a3fe95aaf47dadcd525996 100644 (file)
@@ -24,6 +24,7 @@
   <command>amgetconf</command>    
     <arg choice='opt'><replaceable>config</replaceable></arg>
     <arg choice='plain'><replaceable>parameter</replaceable></arg>
+    <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -81,6 +82,20 @@ followed by a colon (:) and the previously opened file name.</para>
 man page for more details about &A;.</para>
 </refsect1>
 
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+
+
+</variablelist>
+</refsect1>
+
 <refsect1><title>EXAMPLE</title>
 <para>Find out the path to the log file directory:</para>
 
@@ -127,9 +142,7 @@ is not a known keyword
 (e.g. not a valid
 <emphasis remap='I'>amanda.conf</emphasis>
 keyword).
-In this case,
-<command>amgetconf</command>
-will write &quot;<emphasis remap='B'>BUGGY</emphasis>&quot; to stdout as the value.</para>
+</para>
   </listitem>
   </varlistentry>
 </variablelist>
index 4a8e76e5fab44677989c3ccd2885f360fc3b6e8b..a19e40c932e6c3417b32dda0b0c562036821d332 100644 (file)
@@ -25,7 +25,8 @@
     <arg choice='opt'>-f </arg>
     <arg choice='plain'><replaceable>config</replaceable></arg>
     <arg choice='plain'><replaceable>label</replaceable></arg>
-    <arg choice='opt'><arg choice='plain'><replaceable>slot</replaceable></arg><arg choice='plain'><replaceable>slot</replaceable></arg></arg>
+    <group><arg choice='plain'>slot</arg><arg choice='plain'><replaceable>slot</replaceable></arg></group>
+    <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -78,6 +79,20 @@ will label the tape in the specified slot instead of the currently loaded tape.<
 man page for more details about &A;.</para>
 </refsect1>
 
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+
+
+</variablelist>
+</refsect1>
+
 <refsect1><title>EXAMPLE</title>
 <para>Write an &A; label with the string &quot;DMP000&quot; on
 the tape loaded in the device named in the
index a3b29d5efe1c0e787229807a6cff75e228dd158e..16c41e0752efbba8fe5883baf01cd8b2d21784d0 100644 (file)
 <refsynopsisdiv>
 <cmdsynopsis>
   <command>amrecover</command>    
-    <arg choice='opt'><arg choice='opt'>-C </arg><arg choice='plain'><replaceable>config</replaceable></arg></arg>
-    <arg choice='opt'><arg choice='plain'>-s </arg><arg choice='plain'><replaceable>index-server</replaceable></arg></arg>
-    <arg choice='opt'><arg choice='plain'>-t </arg><arg choice='plain'><replaceable>tape-server</replaceable></arg></arg>
-    <arg choice='opt'><arg choice='plain'>-d </arg><arg choice='plain'><replaceable>tape-device</replaceable></arg></arg>
+    <group><arg choice='opt'>-C </arg><arg choice='plain'><replaceable>config</replaceable></arg></group>
+    <group><arg choice='plain'>-s </arg><arg choice='plain'><replaceable>index-server</replaceable></arg></group>
+    <group><arg choice='plain'>-t </arg><arg choice='plain'><replaceable>tape-server</replaceable></arg></group>
+    <group><arg choice='plain'>-d </arg><arg choice='plain'><replaceable>tape-device</replaceable></arg></group>
+    <group><arg choice='plain'>-o </arg><arg choice='plain'><replaceable>clientconfigoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -44,6 +45,8 @@ to move into that directory, otherwise a directory tree that resembles
 the backed up filesystem will be created in the current directory.
 See the examples below for details.</para>
 
+<para>Amrecover will read the <emphasis remap='B'>amanda-client.conf</emphasis> file and the <replaceable>config</replaceable><emphasis remap='B'>/amanda-client.conf</emphasis> file.</para>
+
 <para>See the
 <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>
 man page for more details about &A;.</para>
@@ -78,6 +81,15 @@ client-custom-compressed tapes.</note>
 <para>Tape device to use on the tape server host.</para>
   </listitem>
   </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>clientconfigoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>"
+ section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+
 </variablelist>
 </refsect1>
 
@@ -101,9 +113,9 @@ The following commands are available:</para>
   </listitem>
   </varlistentry>
   <varlistentry>
-  <term><emphasis remap='B'>setdate YYYY-MM-DD</emphasis></term>
+  <term><emphasis remap='B'>setdate YYYY-MM-DD-HH-MM[-SS] | YYYY-MM-DD</emphasis></term>
   <listitem>
-<para>Set the date (default: today).
+<para>Set the restore time (default: now).
 File listing commands only return information on
 backup images for this day,
 for the day before with the next lower dump level,
@@ -120,8 +132,8 @@ the specified date is encountered.</para>
 1996-07-06 through 1997-07-08 were level 2 backups
 </literallayout> <!-- .fi -->
 
-<para>then if 1997-07-08 is the requested date,
-files from the following days would be used:</para>
+<para>then the command <emphasis remap='B'>setdate 1997-07-08-00</emphasis>
+would yield files from the following days:</para>
 
 <!-- .RS -->
 <literallayout remap='.nf'>
@@ -175,6 +187,13 @@ If
 <emphasis remap='I'>mountpoint</emphasis>
 is not specified, all pathnames will be relative to the (unknown)
 mount point instead of full pathnames.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='B'>listhost [diskdevice]</emphasis></term>
+  <listitem>
+<para>List all
+<emphasis remap='B'>host</emphasis></para>
   </listitem>
   </varlistentry>
   <varlistentry>
@@ -558,6 +577,16 @@ commands will use $PAGER to display the file lists.
 Defaults to
 <emphasis remap='I'>more</emphasis>
 if PAGER is not set.</para>
+<para><envar>AMANDA_SERVER</envar>
+If set, $AMANDA_SERVER will be used as index-server.
+The value will take precedence over the compiled default,
+but will be overridden by the -s switch.
+</para>
+<para><envar>AMANDA_TAPE_SERVER</envar>
+If set, $AMANDA_TAPE_SERVER will be used as tape-server.
+The value will take precedence over the compiled default,
+but will be overridden by the -t switch.
+</para>
 <!-- .RE -->
 </refsect1>
 
@@ -568,6 +597,7 @@ if PAGER is not set.</para>
 
 <refsect1><title>SEE ALSO</title>
 <para><citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amanda-client.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>amrestore</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>amfetchdump</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>readline</refentrytitle><manvolnum>3</manvolnum></citerefentry></para>
index b7fd827caa7e5dcda8de739a8cd5ba6016547834..fd9252b603df4ab54a9c278f07e603e95bbac718 100644 (file)
 <cmdsynopsis>
   <command>amreport</command>    
     <arg choice='opt'><replaceable>config</replaceable></arg>
-    <arg choice='opt'><arg choice='plain'>-l </arg><arg choice='plain'><replaceable>logfile</replaceable></arg></arg>
-    <arg choice='opt'><arg choice='plain'>-f </arg><arg choice='plain'><replaceable>outputfile</replaceable></arg></arg>
-    <arg choice='opt'><arg choice='plain'>-p </arg><arg choice='plain'><replaceable>postscriptfile</replaceable></arg></arg>
+    <arg choice='opt'>-i</arg>
+    <group><arg choice='plain'>-M</arg><arg choice='plain'><replaceable>address</replaceable></arg></group>
+    <group><arg choice='plain'>-l</arg><arg choice='plain'><replaceable>logfile</replaceable></arg></group>
+    <group><arg choice='plain'>-f</arg><arg choice='plain'><replaceable>outputfile</replaceable></arg></group>
+    <group><arg choice='plain'>-p</arg><arg choice='plain'><replaceable>postscriptfile</replaceable></arg></group>
+    <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -49,6 +52,24 @@ man page for more details about &A;.</para>
   <term><emphasis remap='I'>config</emphasis></term>
   <listitem>
 <para>Name of the configuration to process.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><option>-i</option></term>
+  <listitem>
+<para>Don't email the report.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><option>-M</option> <replaceable>address</replaceable></term>
+  <listitem>
+<para>Mail the report to
+<emphasis remap='I'>address</emphasis>
+instead of the
+<emphasis remap='B'>mailto</emphasis>
+value from
+<emphasis remap='I'>amanda.conf</emphasis>.
+</para>
   </listitem>
   </varlistentry>
   <varlistentry>
@@ -97,6 +118,14 @@ This option has an effect only if the
 directive is specified in amanda.conf.</para>
   </listitem>
   </varlistentry>
+
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+
 </variablelist>
 </refsect1>
 
index 21ba7bb5f1cf8cb6d3e5dd831c8cd3efa69c2c91..75304bebff12a0e16403d0a4627e02d01514f497 100644 (file)
 <refsynopsisdiv>
 <cmdsynopsis>
   <command>amrestore</command>    
-    <group choice='opt'><arg choice='plain'>-r </arg>
-       <arg choice='plain'>-c </arg>
-       <arg choice='plain'>-C </arg>
-    </group>
-    <arg choice='opt'><arg choice='plain'>-b </arg> <arg choice='plain'><replaceable>blocksize</replaceable></arg> </arg>
-    <arg choice='opt'><arg choice='plain'>-f </arg><arg choice='plain'><replaceable>fileno</replaceable></arg></arg>
-    <arg choice='opt'><arg choice='plain'>-l </arg><arg choice='plain'><replaceable>label</replaceable></arg></arg>
-    <arg choice='opt'>-p </arg>
-    <arg choice='opt'>-h </arg>
-    <group choice='plain'>
-       <arg choice='plain'><replaceable>tapedevice</replaceable></arg>
-       <arg choice='plain'><replaceable>holdingfile</replaceable></arg>
-       <arg choice='opt'><arg choice='plain'><replaceable>hostname</replaceable></arg>
-       <arg choice='opt'><arg choice='plain'><replaceable>diskname</replaceable></arg>
-       <arg choice='opt'><replaceable>datestamp</replaceable></arg> </arg></arg> ...
-    </group>
+    <group choice='opt'><arg choice='plain'>-r </arg><arg choice='plain'>-c </arg><arg choice='plain'>-C </arg></group>
+    <group><arg choice='plain'>-b</arg><arg choice='plain'><replaceable>blocksize</replaceable></arg></group>
+    <group><arg choice='plain'>-f</arg><arg choice='plain'><replaceable>fileno</replaceable></arg></group>
+    <group><arg choice='plain'>-l </arg><arg choice='plain'><replaceable>label</replaceable></arg></group>
+    <arg choice='opt'>-p</arg>
+    <arg choice='opt'>-h</arg>
+    <arg choice='plain'><arg choice='plain'><replaceable>tapedevice</replaceable></arg>|<arg choice='plain'><replaceable>holdingfile</replaceable></arg></arg>
+    <group><arg choice='plain'><replaceable>hostname</replaceable></arg><group><arg choice='plain'><replaceable>diskname</replaceable></arg><group><arg choice='plain'><replaceable>datestamp</replaceable></arg><group><arg choice='plain'><replaceable>hostname</replaceable></arg><group><arg choice='plain'><replaceable>diskname</replaceable></arg><group><arg choice='plain'><replaceable>datestamp</replaceable></arg><arg choice='plain'>...</arg></group></group></group></group></group></group>
 </cmdsynopsis>
 </refsynopsisdiv>
 
@@ -249,6 +241,16 @@ uses the header to determine the restore program to use.</para>
 <para>If a header is written (-r or -h),
 only 32 KBytes are output regardless of the tape blocksize.
 This makes the resulting image usable as a holding file.</para>
+
+<variablelist remap='TP'>
+  <varlistentry>
+  <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+  <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
 </refsect1>
 
 <refsect1><title>EXAMPLES</title>
index 6af7479da1b12018673ab20ded05cb091ab71975..4ee4aa8caa27f5cda56df78c2476934312905a77 100644 (file)
@@ -27,7 +27,7 @@
     <arg choice='opt'>-c </arg>
     <arg choice='opt'>-o </arg>
     <arg choice='opt'>-b <replaceable>blocksize</replaceable></arg>
-    <arg choice='opt'>-e <replaceable>estsize</replaceable></arg>
+    <arg choice='plain'>-e <replaceable>estsize</replaceable></arg>
     <arg choice='opt'>-f <replaceable>tapedev</replaceable></arg>
     <arg choice='opt'>-t <replaceable>typename</replaceable></arg>
 </cmdsynopsis>
@@ -69,7 +69,7 @@ This takes a few minutes only.</para>
   <varlistentry>
   <term><option>-e</option><replaceable> estsize</replaceable></term>
   <listitem>
-<para>estimated tape size (default: 1g == 1024m)</para>
+<para>estimated tape size (No default!)</para>
   </listitem>
   </varlistentry>
   <varlistentry>
@@ -94,7 +94,7 @@ The device to perform the test.</para>
 
 <!-- .RS -->
 <literallayout remap='.nf'>
-% amtapetype -f /dev/nst0
+% amtapetype -f /dev/nst0 -e 150G
 </literallayout></refsect1>
 
 <refsect1><title>NOTES</title>
diff --git a/oldrecover-src/Makefile.am b/oldrecover-src/Makefile.am
new file mode 100644 (file)
index 0000000..8571995
--- /dev/null
@@ -0,0 +1,76 @@
+# Makefile for Amanda file recovery programs.
+
+INCLUDES =     -I$(top_builddir)/common-src \
+               -I$(top_srcdir)/common-src   \
+               -I$(top_srcdir)/client-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
+LIB_EXTENSION = la
+
+sbin_PROGRAMS =                amoldrecover
+
+if WANT_RUNTIME_PSEUDO_RELOC
+AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+endif
+
+###
+# Because libamanda includes routines (e.g. regex) provided by some system
+# libraries, and because of the way libtool sets up the command line, we
+# need to list libamanda twice here, first to override the system library
+# routines, and second to pick up any references in the other libraries.
+###
+
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+       @LEXLIB@ \
+       ../client-src/libamclient.$(LIB_EXTENSION) \
+       $(READLINE_LIBS) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+amoldrecover_CSRC =    amrecover.c                                     \
+                       display_commands.c              extract_list.c  \
+                       help.c                          set_commands.c
+
+amoldrecover_SOURCES = $(amoldrecover_CSRC)    uparse.y        uscan.l
+
+noinst_HEADERS =       amrecover.h uparse.h
+
+AM_YFLAGS =            -d
+
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+
+uscan.$(OBJEXT): $(srcdir)/uscan.c
+       $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+uparse.$(OBJEXT): $(srcdir)/uparse.c
+       $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+
+install-exec-hook:
+       @list="$(sbin_PROGRAMS)"; \
+       for p in $$list; do \
+               pa=$(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \
+               echo chown $(BINARY_OWNER) $$pa; \
+               chown $(BINARY_OWNER) $$pa; \
+               echo chgrp $(SETUID_GROUP) $$pa; \
+               chgrp $(SETUID_GROUP) $$pa; \
+               echo chmod o-rwx $$pa; \
+               chmod o-rwx $$pa; \
+       done
+
+
+lint:
+       @ f="$(amoldrecover_CSRC)";                                             \
+       (cd ../common-src; make listlibsrc);                                    \
+       f="$$f "`cat ../common-src/listlibsrc.output`;                          \
+       (cd ../server-src; make listlibsrc);                                    \
+       f="$$f "`cat ../server-src/listlibsrc.output`;                          \
+       echo $(LINT) $$f;                                                       \
+       $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $$f;\
+       if [ $$? -ne 0 ]; then                                                  \
+           exit 1;                                                             \
+       fi;                                                                     \
+        exit 0
diff --git a/oldrecover-src/Makefile.in b/oldrecover-src/Makefile.in
new file mode 100644 (file)
index 0000000..ff8dca4
--- /dev/null
@@ -0,0 +1,675 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for Amanda file recovery programs.
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+sbin_PROGRAMS = amoldrecover$(EXEEXT)
+subdir = oldrecover-src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in uparse.c uparse.h uscan.c
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)"
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(sbin_PROGRAMS)
+am__objects_1 = amrecover.$(OBJEXT) display_commands.$(OBJEXT) \
+       extract_list.$(OBJEXT) help.$(OBJEXT) set_commands.$(OBJEXT)
+am_amoldrecover_OBJECTS = $(am__objects_1) uparse.$(OBJEXT) \
+       uscan.$(OBJEXT)
+amoldrecover_OBJECTS = $(am_amoldrecover_OBJECTS)
+amoldrecover_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+amoldrecover_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       ../client-src/libamclient.$(LIB_EXTENSION) \
+       $(am__DEPENDENCIES_1) ../common-src/libamanda.$(LIB_EXTENSION)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+LTLEXCOMPILE = $(LIBTOOL) --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) --mode=compile $(YACC) $(YFLAGS) \
+       $(AM_YFLAGS)
+SOURCES = $(amoldrecover_SOURCES)
+DIST_SOURCES = $(amoldrecover_SOURCES)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMANDA_DBGDIR = @AMANDA_DBGDIR@
+AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
+AMANDA_TMPDIR = @AMANDA_TMPDIR@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
+CAT = @CAT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHIO = @CHIO@
+CHS = @CHS@
+CLIENT_LOGIN = @CLIENT_LOGIN@
+CLIENT_SCRIPTS_OPT = @CLIENT_SCRIPTS_OPT@
+COMPRESS = @COMPRESS@
+CONFIGURE_COMMAND = @CONFIGURE_COMMAND@
+CONFIG_DIR = @CONFIG_DIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DB_EXT = @DB_EXT@
+DD = @DD@
+DEFAULT_CHANGER_DEVICE = @DEFAULT_CHANGER_DEVICE@
+DEFAULT_CONFIG = @DEFAULT_CONFIG@
+DEFAULT_RAW_TAPE_DEVICE = @DEFAULT_RAW_TAPE_DEVICE@
+DEFAULT_SERVER = @DEFAULT_SERVER@
+DEFAULT_TAPE_DEVICE = @DEFAULT_TAPE_DEVICE@
+DEFAULT_TAPE_SERVER = @DEFAULT_TAPE_SERVER@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOC_BUILD_DATE = @DOC_BUILD_DATE@
+DUMP = @DUMP@
+DUMPER_DIR = @DUMPER_DIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GETCONF = @GETCONF@
+GNUPLOT = @GNUPLOT@
+GNUTAR = @GNUTAR@
+GNUTAR_LISTED_INCREMENTAL_DIR = @GNUTAR_LISTED_INCREMENTAL_DIR@
+GNUTAR_LISTED_INCREMENTAL_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+HAVE_XSLTPROC_FALSE = @HAVE_XSLTPROC_FALSE@
+HAVE_XSLTPROC_TRUE = @HAVE_XSLTPROC_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LL_FMT = @LL_FMT@
+LN_S = @LN_S@
+LTALLOCA = @LTALLOCA@
+LTLIBOBJS = @LTLIBOBJS@
+MAILER = @MAILER@
+MAKEINFO = @MAKEINFO@
+MAXTAPEBLOCKSIZE = @MAXTAPEBLOCKSIZE@
+MCUTIL = @MCUTIL@
+MT = @MT@
+MTX = @MTX@
+MT_FILE_FLAG = @MT_FILE_FLAG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCAT = @PCAT@
+PERL = @PERL@
+PRINT = @PRINT@
+RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
+RESTORE = @RESTORE@
+SAMBA_CLIENT = @SAMBA_CLIENT@
+SERVICE_SUFFIX = @SERVICE_SUFFIX@
+SETUID_GROUP = @SETUID_GROUP@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNAPSHOT_STAMP = @SNAPSHOT_STAMP@
+STRIP = @STRIP@
+USE_VERSION_SUFFIXES = @USE_VERSION_SUFFIXES@
+VDUMP = @VDUMP@
+VERSION = @VERSION@
+VERSION_COMMENT = @VERSION_COMMENT@
+VERSION_MAJOR = @VERSION_MAJOR@
+VERSION_MINOR = @VERSION_MINOR@
+VERSION_PATCH = @VERSION_PATCH@
+VERSION_SUFFIX = @VERSION_SUFFIX@
+VRESTORE = @VRESTORE@
+VXDUMP = @VXDUMP@
+VXRESTORE = @VXRESTORE@
+WANT_AMPLOT_FALSE = @WANT_AMPLOT_FALSE@
+WANT_AMPLOT_TRUE = @WANT_AMPLOT_TRUE@
+WANT_CHG_SCSI_FALSE = @WANT_CHG_SCSI_FALSE@
+WANT_CHG_SCSI_TRUE = @WANT_CHG_SCSI_TRUE@
+WANT_CHIO_SCSI_FALSE = @WANT_CHIO_SCSI_FALSE@
+WANT_CHIO_SCSI_TRUE = @WANT_CHIO_SCSI_TRUE@
+WANT_CLIENT_FALSE = @WANT_CLIENT_FALSE@
+WANT_CLIENT_TRUE = @WANT_CLIENT_TRUE@
+WANT_RECOVER_FALSE = @WANT_RECOVER_FALSE@
+WANT_RECOVER_TRUE = @WANT_RECOVER_TRUE@
+WANT_RESTORE_FALSE = @WANT_RESTORE_FALSE@
+WANT_RESTORE_TRUE = @WANT_RESTORE_TRUE@
+WANT_RUNTIME_PSEUDO_RELOC_FALSE = @WANT_RUNTIME_PSEUDO_RELOC_FALSE@
+WANT_RUNTIME_PSEUDO_RELOC_TRUE = @WANT_RUNTIME_PSEUDO_RELOC_TRUE@
+WANT_SAMBA_FALSE = @WANT_SAMBA_FALSE@
+WANT_SAMBA_TRUE = @WANT_SAMBA_TRUE@
+WANT_SERVER_FALSE = @WANT_SERVER_FALSE@
+WANT_SERVER_TRUE = @WANT_SERVER_TRUE@
+WANT_SETUID_CLIENT_FALSE = @WANT_SETUID_CLIENT_FALSE@
+WANT_SETUID_CLIENT_TRUE = @WANT_SETUID_CLIENT_TRUE@
+WANT_SSH_SECURITY_FALSE = @WANT_SSH_SECURITY_FALSE@
+WANT_SSH_SECURITY_TRUE = @WANT_SSH_SECURITY_TRUE@
+WANT_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+ac_c = @ac_c@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_n = @ac_n@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+INCLUDES = -I$(top_builddir)/common-src \
+               -I$(top_srcdir)/common-src   \
+               -I$(top_srcdir)/client-src
+
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
+LIB_EXTENSION = la
+@WANT_RUNTIME_PSEUDO_RELOC_TRUE@AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+
+###
+# Because libamanda includes routines (e.g. regex) provided by some system
+# libraries, and because of the way libtool sets up the command line, we
+# need to list libamanda twice here, first to override the system library
+# routines, and second to pick up any references in the other libraries.
+###
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+       @LEXLIB@ \
+       ../client-src/libamclient.$(LIB_EXTENSION) \
+       $(READLINE_LIBS) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+amoldrecover_CSRC = amrecover.c                                        \
+                       display_commands.c              extract_list.c  \
+                       help.c                          set_commands.c
+
+amoldrecover_SOURCES = $(amoldrecover_CSRC)    uparse.y        uscan.l
+noinst_HEADERS = amrecover.h uparse.h
+AM_YFLAGS = -d
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .l .lo .o .obj .y
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  oldrecover-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  oldrecover-src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+            || test -f $$p1 \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+         else :; fi; \
+       done
+
+uninstall-sbinPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+         echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+         rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+       done
+
+clean-sbinPROGRAMS:
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+uparse.h: uparse.c
+       @if test ! -f $@; then \
+         rm -f uparse.c; \
+         $(MAKE) uparse.c; \
+       else :; fi
+amoldrecover$(EXEEXT): $(amoldrecover_OBJECTS) $(amoldrecover_DEPENDENCIES) 
+       @rm -f amoldrecover$(EXEEXT)
+       $(LINK) $(amoldrecover_LDFLAGS) $(amoldrecover_OBJECTS) $(amoldrecover_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrecover.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/display_commands.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_list.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_commands.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uparse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uscan.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+
+.l.c:
+       $(LEXCOMPILE) $<
+       sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@
+       rm -f $(LEX_OUTPUT_ROOT).c
+
+.y.c:
+       $(YACCCOMPILE) $<
+       if test -f y.tab.h; then \
+         to=`echo "$*_H" | sed \
+                -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
+                -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \
+         sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \
+            y.tab.h >$*.ht; \
+         rm -f y.tab.h; \
+         if cmp -s $*.ht $*.h; then \
+           rm -f $*.ht ;\
+         else \
+           mv $*.ht $*.h; \
+         fi; \
+       fi
+       if test -f y.output; then \
+         mv y.output $*.output; \
+       fi
+       sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@
+       rm -f y.tab.c
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(sbindir)"; do \
+         test -z "$$dir" || $(mkdir_p) "$$dir"; \
+       done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+       -rm -f uparse.c
+       -rm -f uparse.h
+       -rm -f uscan.c
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+       mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-sbinPROGRAMS
+       @$(NORMAL_INSTALL)
+       $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-sbinPROGRAMS ctags distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
+       install install-am install-data install-data-am install-exec \
+       install-exec-am install-exec-hook install-info install-info-am \
+       install-man install-sbinPROGRAMS install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags uninstall uninstall-am uninstall-info-am \
+       uninstall-sbinPROGRAMS
+
+
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+
+uscan.$(OBJEXT): $(srcdir)/uscan.c
+       $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+uparse.$(OBJEXT): $(srcdir)/uparse.c
+       $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+install-exec-hook:
+       @list="$(sbin_PROGRAMS)"; \
+       for p in $$list; do \
+               pa=$(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \
+               echo chown $(BINARY_OWNER) $$pa; \
+               chown $(BINARY_OWNER) $$pa; \
+               echo chgrp $(SETUID_GROUP) $$pa; \
+               chgrp $(SETUID_GROUP) $$pa; \
+               echo chmod o-rwx $$pa; \
+               chmod o-rwx $$pa; \
+       done
+
+lint:
+       @ f="$(amoldrecover_CSRC)";                                             \
+       (cd ../common-src; make listlibsrc);                                    \
+       f="$$f "`cat ../common-src/listlibsrc.output`;                          \
+       (cd ../server-src; make listlibsrc);                                    \
+       f="$$f "`cat ../server-src/listlibsrc.output`;                          \
+       echo $(LINT) $$f;                                                       \
+       $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $$f;\
+       if [ $$? -ne 0 ]; then                                                  \
+           exit 1;                                                             \
+       fi;                                                                     \
+        exit 0
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/oldrecover-src/amrecover.c b/oldrecover-src/amrecover.c
new file mode 100644 (file)
index 0000000..8066cad
--- /dev/null
@@ -0,0 +1,703 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: amrecover.c,v 1.7 2006/07/25 18:27:57 martinea Exp $
+ *
+ * an interactive program for recovering backed-up files
+ */
+
+#include "amanda.h"
+#include "version.h"
+//#ifdef HAVE_NETINET_IN_SYSTM_H
+//#include <netinet/in_systm.h>
+//#endif
+//#include <netinet/in.h>
+//#ifdef HAVE_NETINET_IP_H
+//#include <netinet/ip.h>
+//#endif
+#include "stream.h"
+#include "amfeatures.h"
+#include "amrecover.h"
+#include "getfsent.h"
+#include "dgram.h"
+#include "util.h"
+
+extern int process_line(char *line);
+int guess_disk(char *cwd, size_t cwd_len, char **dn_guess, char **mpt_guess);
+int get_line(void);
+int grab_reply(int show);
+void sigint_handler(int signum);
+int main(int argc, char **argv);
+
+#define USAGE "Usage: amoldrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>]\n"
+
+char *config = NULL;
+char *server_name = NULL;
+int server_socket;
+char *server_line = NULL;
+char *dump_datestamp = NULL;           /* date we are restoring */
+char *dump_hostname;                   /* which machine we are restoring */
+char *disk_name = NULL;                        /* disk we are restoring */
+char *mount_point = NULL;              /* where disk was mounted */
+char *disk_path = NULL;                        /* path relative to mount point */
+char dump_date[STR_SIZE];              /* date on which we are restoring */
+int quit_prog;                         /* set when time to exit parser */
+char *tape_server_name = NULL;
+int tape_server_socket;
+char *tape_device_name = NULL;
+am_feature_t *our_features = NULL;
+am_feature_t *indexsrv_features = NULL;
+am_feature_t *tapesrv_features = NULL;
+
+/* gets a "line" from server and put in server_line */
+/* server_line is terminated with \0, \r\n is striped */
+/* returns -1 if error */
+
+int
+get_line(void)
+{
+    char *line = NULL;
+    char *part = NULL;
+    size_t len;
+
+    while(1) {
+       if((part = areads(server_socket)) == NULL) {
+           int save_errno = errno;
+
+           if(server_line) {
+               fputs(server_line, stderr);     /* show the last line read */
+               fputc('\n', stderr);
+           }
+           if(save_errno != 0) {
+               fprintf(stderr, "%s: Error reading line from server: %s\n",
+                               get_pname(),
+                               strerror(save_errno));
+           } else {
+               fprintf(stderr, "%s: Unexpected end of file, check amindexd*debug on server %s\n",
+                       get_pname(),
+                       server_name);
+           }
+           errno = save_errno;
+           break;      /* exit while loop */
+       }
+       if(line) {
+           strappend(line, part);
+           amfree(part);
+       } else {
+           line = part;
+           part = NULL;
+       }
+       if((len = strlen(line)) > 0 && line[len-1] == '\r') {
+           line[len-1] = '\0';
+           server_line = newstralloc(server_line, line);
+           amfree(line);
+           return 0;
+       }
+       /*
+        * Hmmm.  We got a "line" from areads(), which means it saw
+        * a '\n' (or EOF, etc), but there was not a '\r' before it.
+        * Put a '\n' back in the buffer and loop for more.
+        */
+       strappend(line, "\n");
+    }
+    amfree(line);
+    amfree(server_line);
+    return -1;
+}
+
+
+/* get reply from server and print to screen */
+/* handle multi-line reply */
+/* return -1 if error */
+/* return code returned by server always occupies first 3 bytes of global
+   variable server_line */
+int
+grab_reply(
+    int                show)
+{
+    do {
+       if (get_line() == -1) {
+           return -1;
+       }
+       if(show) puts(server_line);
+    } while (server_line[3] == '-');
+    if(show) fflush(stdout);
+
+    return 0;
+}
+
+
+/* get 1 line of reply */
+/* returns -1 if error, 0 if last (or only) line, 1 if more to follow */
+int
+get_reply_line(void)
+{
+    if (get_line() == -1)
+       return -1;
+    return server_line[3] == '-';
+}
+
+
+/* returns pointer to returned line */
+char *
+reply_line(void)
+{
+    return server_line;
+}
+
+
+
+/* returns 0 if server returned an error code (ie code starting with 5)
+   and non-zero otherwise */
+int
+server_happy(void)
+{
+    return server_line[0] != '5';
+}
+
+
+int
+send_command(
+    char *     cmd)
+{
+    /*
+     * NOTE: this routine is called from sigint_handler, so we must be
+     * **very** careful about what we do since there is no way to know
+     * our state at the time the interrupt happened.  For instance,
+     * do not use any stdio or malloc routines here.
+     */
+    struct iovec msg[2];
+    ssize_t bytes;
+
+    memset(msg, 0, sizeof(msg));
+    msg[0].iov_base = cmd;
+    msg[0].iov_len = strlen(msg[0].iov_base);
+    msg[1].iov_base = "\r\n";
+    msg[1].iov_len = strlen(msg[1].iov_base);
+    bytes = (ssize_t)(msg[0].iov_len + msg[1].iov_len);
+
+    if (writev(server_socket, msg, 2) < bytes) {
+       return -1;
+    }
+    return (0);
+}
+
+
+/* send a command to the server, get reply and print to screen */
+int
+converse(
+    char *     cmd)
+{
+    if (send_command(cmd) == -1) return -1;
+    if (grab_reply(1) == -1) return -1;
+    return 0;
+}
+
+
+/* same as converse() but reply not echoed to stdout */
+int
+exchange(
+    char *     cmd)
+{
+    if (send_command(cmd) == -1) return -1;
+    if (grab_reply(0) == -1) return -1;
+    return 0;
+}
+
+
+/* basic interrupt handler for when user presses ^C */
+/* Bale out, letting server know before doing so */
+void
+sigint_handler(
+    int        signum)
+{
+    /*
+     * NOTE: we must be **very** careful about what we do here since there
+     * is no way to know our state at the time the interrupt happened.
+     * For instance, do not use any stdio routines here or in any called
+     * routines.  Also, use _exit() instead of exit() to make sure stdio
+     * buffer flushing is not attempted.
+     */
+    (void)signum;      /* Quiet unused parameter warning */
+
+    if (extract_restore_child_pid != -1)
+       (void)kill(extract_restore_child_pid, SIGKILL);
+    extract_restore_child_pid = -1;
+
+    (void)send_command("QUIT");
+    _exit(1);
+}
+
+
+void
+clean_pathname(
+    char *     s)
+{
+    size_t length;
+    length = strlen(s);
+
+    /* remove "/" at end of path */
+    if(length>1 && s[length-1]=='/')
+       s[length-1]='\0';
+
+    /* change "/." to "/" */
+    if(strcmp(s,"/.")==0)
+       s[1]='\0';
+
+    /* remove "/." at end of path */
+    if(strcmp(&(s[length-2]),"/.")==0)
+       s[length-2]='\0';
+}
+
+
+/* try and guess the disk the user is currently on.
+   Return -1 if error, 0 if disk not local, 1 if disk local,
+   2 if disk local but can't guess name */
+/* do this by looking for the longest mount point which matches the
+   current directory */
+int
+guess_disk (
+    char *     cwd,
+    size_t     cwd_len,
+    char **    dn_guess,
+    char **    mpt_guess)
+{
+    size_t longest_match = 0;
+    size_t current_length;
+    size_t cwd_length;
+    int local_disk = 0;
+    generic_fsent_t fsent;
+    char *fsname = NULL;
+    char *disk_try = NULL;
+
+    *dn_guess = NULL;
+    *mpt_guess = NULL;
+
+    if (getcwd(cwd, cwd_len) == NULL) {
+       return -1;
+       /*NOTREACHED*/
+    }
+    cwd_length = strlen(cwd);
+    dbprintf(("guess_disk: %d: \"%s\"\n", cwd_length, cwd));
+
+    if (open_fstab() == 0) {
+       return -1;
+       /*NOTREACHED*/
+    }
+
+    while (get_fstab_nextentry(&fsent))
+    {
+       current_length = fsent.mntdir ? strlen(fsent.mntdir) : (size_t)0;
+       dbprintf(("guess_disk: %d: %d: \"%s\": \"%s\"\n",
+                 longest_match,
+                 current_length,
+                 fsent.mntdir ? fsent.mntdir : "(mntdir null)",
+                 fsent.fsname ? fsent.fsname : "(fsname null)"));
+       if ((current_length > longest_match)
+           && (current_length <= cwd_length)
+           && (strncmp(fsent.mntdir, cwd, current_length) == 0))
+       {
+           longest_match = current_length;
+           *mpt_guess = newstralloc(*mpt_guess, fsent.mntdir);
+           if(strncmp(fsent.fsname,DEV_PREFIX,(strlen(DEV_PREFIX))))
+           {
+               fsname = newstralloc(fsname, fsent.fsname);
+            }
+           else
+           {
+               fsname = newstralloc(fsname,fsent.fsname+strlen(DEV_PREFIX));
+           }
+           local_disk = is_local_fstype(&fsent);
+           dbprintf(("guess_disk: local_disk = %d, fsname = \"%s\"\n",
+                     local_disk,
+                     fsname));
+       }
+    }
+    close_fstab();
+
+    if (longest_match == 0) {
+       amfree(*mpt_guess);
+       amfree(fsname);
+       return -1;                      /* ? at least / should match */
+    }
+
+    if (!local_disk) {
+       amfree(*mpt_guess);
+       amfree(fsname);
+       return 0;
+    }
+
+    /* have mount point now */
+    /* disk name may be specified by mount point (logical name) or
+       device name, have to determine */
+    printf("Trying disk %s ...\n", *mpt_guess);
+    disk_try = stralloc2("DISK ", *mpt_guess);         /* try logical name */
+    if (exchange(disk_try) == -1)
+       exit(1);
+    amfree(disk_try);
+    if (server_happy())
+    {
+       *dn_guess = stralloc(*mpt_guess);               /* logical is okay */
+       amfree(fsname);
+       return 1;
+    }
+    printf("Trying disk %s ...\n", fsname);
+    disk_try = stralloc2("DISK ", fsname);             /* try device name */
+    if (exchange(disk_try) == -1)
+       exit(1);
+    amfree(disk_try);
+    if (server_happy())
+    {
+       *dn_guess = stralloc(fsname);                   /* dev name is okay */
+       amfree(fsname);
+       return 1;
+    }
+
+    /* neither is okay */
+    amfree(*mpt_guess);
+    amfree(fsname);
+    return 2;
+}
+
+
+void
+quit(void)
+{
+    quit_prog = 1;
+    (void)converse("QUIT");
+}
+
+char *localhost = NULL;
+
+#ifdef DEFAULT_TAPE_SERVER
+# define DEFAULT_TAPE_SERVER_FAILOVER (DEFAULT_TAPE_SERVER)
+#else
+# define DEFAULT_TAPE_SERVER_FAILOVER (NULL)
+#endif
+
+int
+main(
+    int                argc,
+    char **    argv)
+{
+    in_port_t my_port;
+    struct servent *sp;
+    int i;
+    time_t timer;
+    char *lineread = NULL;
+    struct sigaction act, oact;
+    extern char *optarg;
+    extern int optind;
+    char cwd[STR_SIZE], *dn_guess = NULL, *mpt_guess = NULL;
+    char *service_name;
+    char *line = NULL;
+    struct tm *tm;
+
+    safe_fd(-1, 0);
+
+    set_pname("amoldrecover");
+
+    /* Don't die when child closes pipe */
+    signal(SIGPIPE, SIG_IGN);
+
+    dbopen(DBG_SUBDIR_CLIENT);
+
+#ifndef IGNORE_UID_CHECK
+    if (geteuid() != 0) {
+       erroutput_type |= ERR_SYSLOG;
+       error("amrecover must be run by root");
+       /*NOTREACHED*/
+    }
+#endif
+
+    localhost = alloc(MAX_HOSTNAME_LENGTH+1);
+    if (gethostname(localhost, MAX_HOSTNAME_LENGTH) != 0) {
+       error("cannot determine local host name\n");
+       /*NOTREACHED*/
+    }
+    localhost[MAX_HOSTNAME_LENGTH] = '\0';
+
+    config = newstralloc(config, DEFAULT_CONFIG);
+
+    dbrename(config, DBG_SUBDIR_CLIENT);
+
+    amfree(server_name);
+    server_name = getenv("AMANDA_SERVER");
+    if(!server_name) server_name = DEFAULT_SERVER;
+    server_name = stralloc(server_name);
+
+    amfree(tape_server_name);
+    tape_server_name = getenv("AMANDA_TAPESERVER");
+    if(!tape_server_name) tape_server_name = DEFAULT_TAPE_SERVER;
+    tape_server_name = stralloc(tape_server_name);
+
+    if (argc > 1 && argv[1][0] != '-')
+    {
+       /*
+        * If the first argument is not an option flag, then we assume
+        * it is a configuration name to match the syntax of the other
+        * Amanda utilities.
+        */
+       char **new_argv;
+
+       new_argv = (char **) alloc((size_t)((argc + 1 + 1) * sizeof(*new_argv)));
+       new_argv[0] = argv[0];
+       new_argv[1] = "-C";
+       for (i = 1; i < argc; i++)
+       {
+           new_argv[i + 1] = argv[i];
+       }
+       new_argv[i + 1] = NULL;
+       argc++;
+       argv = new_argv;
+    }
+    while ((i = getopt(argc, argv, "C:s:t:d:U")) != EOF)
+    {
+       switch (i)
+       {
+           case 'C':
+               config = newstralloc(config, optarg);
+               break;
+
+           case 's':
+               server_name = newstralloc(server_name, optarg);
+               break;
+
+           case 't':
+               tape_server_name = newstralloc(tape_server_name, optarg);
+               break;
+
+           case 'd':
+               tape_device_name = newstralloc(tape_device_name, optarg);
+               break;
+
+           case 'U':
+           case '?':
+               (void)printf(USAGE);
+               return 0;
+       }
+    }
+    if (optind != argc)
+    {
+       (void)fprintf(stderr, USAGE);
+       exit(1);
+    }
+
+    amfree(disk_name);
+    amfree(mount_point);
+    amfree(disk_path);
+    dump_date[0] = '\0';
+
+    /* Don't die when child closes pipe */
+    signal(SIGPIPE, SIG_IGN);
+
+    /* set up signal handler */
+    act.sa_handler = sigint_handler;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = 0;
+    if (sigaction(SIGINT, &act, &oact) != 0) {
+       error("error setting signal handler: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+
+    service_name = stralloc2("amandaidx", SERVICE_SUFFIX);
+
+    printf("AMRECOVER Version %s. Contacting server on %s ...\n",
+          version(), server_name);  
+    if ((sp = getservbyname(service_name, "tcp")) == NULL) {
+       error("%s/tcp unknown protocol", service_name);
+       /*NOTREACHED*/
+    }
+    amfree(service_name);
+    server_socket = stream_client_privileged(server_name,
+                                            (in_port_t)ntohs((in_port_t)sp->s_port),
+                                            0,
+                                            0,
+                                            &my_port,
+                                            0);
+    if (server_socket < 0) {
+       error("cannot connect to %s: %s", server_name, strerror(errno));
+       /*NOTREACHED*/
+    }
+    if (my_port >= IPPORT_RESERVED) {
+        aclose(server_socket);
+       error("did not get a reserved port: %d", my_port);
+       /*NOTREACHED*/
+    }
+
+#if 0
+    /*
+     * We may need root privilege again later for a reserved port to
+     * the tape server, so we will drop down now but might have to
+     * come back later.
+     */
+    setegid(getgid());
+    seteuid(getuid());
+#endif
+
+    /* get server's banner */
+    if (grab_reply(1) == -1) {
+        aclose(server_socket);
+       exit(1);
+    }
+    if (!server_happy())
+    {
+       dbclose();
+       aclose(server_socket);
+       exit(1);
+    }
+
+    /* do the security thing */
+    line = get_security();
+    if (converse(line) == -1) {
+        aclose(server_socket);
+       exit(1);
+    }
+    if (!server_happy()) {
+        aclose(server_socket);
+       exit(1);
+    }
+    memset(line, '\0', strlen(line));
+    amfree(line);
+
+    /* try to get the features from the server */
+    {
+       char *our_feature_string = NULL;
+       char *their_feature_string = NULL;
+
+       our_features = am_init_feature_set();
+       our_feature_string = am_feature_to_string(our_features);
+       line = stralloc2("FEATURES ", our_feature_string);
+       if(exchange(line) == 0) {
+           their_feature_string = stralloc(server_line+13);
+           indexsrv_features = am_string_to_feature(their_feature_string);
+       }
+       else {
+           indexsrv_features = am_set_default_feature_set();
+        }
+       amfree(our_feature_string);
+       amfree(their_feature_string);
+       amfree(line);
+    }
+
+    /* set the date of extraction to be today */
+    (void)time(&timer);
+    tm = localtime(&timer);
+    if (tm)
+       strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", tm);
+    else
+       error("BAD DATE");
+
+    printf("Setting restore date to today (%s)\n", dump_date);
+    line = stralloc2("DATE ", dump_date);
+    if (converse(line) == -1) {
+        aclose(server_socket);
+       exit(1);
+    }
+    amfree(line);
+
+    line = stralloc2("SCNF ", config);
+    if (converse(line) == -1) {
+        aclose(server_socket);
+       exit(1);
+    }
+    amfree(line);
+
+    if (server_happy())
+    {
+       /* set host we are restoring to this host by default */
+       amfree(dump_hostname);
+       set_host(localhost);
+       if (dump_hostname)
+       {
+            /* get a starting disk and directory based on where
+              we currently are */
+           switch (guess_disk(cwd, sizeof(cwd), &dn_guess, &mpt_guess))
+           {
+               case 1:
+                   /* okay, got a guess. Set disk accordingly */
+                   printf("$CWD '%s' is on disk '%s' mounted at '%s'.\n",
+                          cwd, dn_guess, mpt_guess);
+                   set_disk(dn_guess, mpt_guess);
+                   set_directory(cwd);
+                   if (server_happy() && strcmp(cwd, mpt_guess) != 0)
+                       printf("WARNING: not on root of selected filesystem, check man-page!\n");
+                   amfree(dn_guess);
+                   amfree(mpt_guess);
+                   break;
+
+               case 0:
+                   printf("$CWD '%s' is on a network mounted disk\n",
+                          cwd);
+                   printf("so you must 'sethost' to the server\n");
+                   /* fake an unhappy server */
+                   server_line[0] = '5';
+                   break;
+
+               case 2:
+               case -1:
+               default:
+                   printf("Use the setdisk command to choose dump disk to recover\n");
+                   /* fake an unhappy server */
+                   server_line[0] = '5';
+                   break;
+           }
+       }
+    }
+
+    quit_prog = 0;
+    do
+    {
+       if ((lineread = readline("amrecover> ")) == NULL) {
+           clearerr(stdin);
+           putchar('\n');
+           break;
+       }
+       if (lineread[0] != '\0') 
+       {
+           add_history(lineread);
+           process_line(lineread);     /* act on line's content */
+       }
+       amfree(lineread);
+    } while (!quit_prog);
+
+    dbclose();
+
+    aclose(server_socket);
+    return 0;
+}
+
+char *
+get_security(void)
+{
+    struct passwd *pwptr;
+
+    if((pwptr = getpwuid(getuid())) == NULL) {
+       error("can't get login name for my uid %ld", (long)getuid());
+       /*NOTREACHED*/
+    }
+    return stralloc2("SECURITY USER ", pwptr->pw_name);
+}
diff --git a/oldrecover-src/amrecover.h b/oldrecover-src/amrecover.h
new file mode 100644 (file)
index 0000000..538c855
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: amrecover.h,v 1.2 2006/05/25 01:47:13 johnfranks Exp $
+ *
+ * data structures and declarations for amrecover
+ */
+
+#include "amanda.h"
+#include "amfeatures.h"
+
+typedef struct DIR_ITEM
+{
+    char *date;
+    int  level;
+    char *tape;
+    char *path;
+    off_t  fileno;
+
+    struct DIR_ITEM *next;
+}
+DIR_ITEM;
+
+extern char *server_name;
+extern char *config;
+extern char *dump_datestamp;           /* date we are restoring */
+extern char *dump_hostname;            /* which machine we are restoring */
+extern char *disk_name;                        /* disk we are restoring */
+extern char *mount_point;              /* where disk was mounted */
+extern char *disk_path;                        /* path relative to mount point */
+extern char dump_date[STR_SIZE];       /* date on which we are restoring */
+extern int quit_prog;                  /* set when time to exit parser */
+extern char *tape_server_name;
+extern char *tape_device_name;
+extern am_feature_t *our_features;
+extern am_feature_t *indexsrv_features;
+extern am_feature_t *tapesrv_features;
+extern pid_t extract_restore_child_pid;
+
+extern void free_dir_item(DIR_ITEM *item);
+
+extern int converse(char *cmd);
+extern int exchange(char *cmd);
+extern int server_happy(void);
+extern int send_command(char *cmd);
+extern int get_reply_line(void);
+extern char *reply_line(void);
+
+extern void quit(void);
+
+extern void help_list(void);           /* list commands */
+
+extern void set_disk(char *dsk, char *mtpt);
+extern void list_disk(char *amdevice);
+extern void list_host(void);
+extern void set_host(const char *host);
+extern int set_date(char *date);
+extern void set_directory(char *dir);
+extern void cd_glob(char *dir);
+extern void cd_regex(char *dir);
+extern void cd_dir(char *dir, char *default_dir);
+extern void set_tape(char *tape);
+extern void show_directory(void);
+extern void set_mode(int mode);
+extern void show_mode(void);
+
+extern void list_disk_history(void);
+extern void list_directory(void);
+extern DIR_ITEM *get_dir_list(void);
+extern DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
+extern void suck_dir_list_from_server(void);
+extern void clear_dir_list(void);
+extern void clean_pathname(char *s);
+extern void display_extract_list(char *file);
+extern void clear_extract_list(void);
+extern int is_extract_list_nonempty(void);
+extern void add_glob(char *glob);
+extern void add_regex(char *regex);
+extern void add_file(char *path, char *regex);
+extern void delete_glob(char *glob);
+extern void delete_regex(char *regex);
+extern void delete_file(char *path, char *regex);
+
+extern void extract_files(void);
+
+#ifdef SAMBA_CLIENT
+#define SAMBA_SMBCLIENT 0
+#define SAMBA_TAR       1
+#endif
+
+extern char *get_security(void);
diff --git a/oldrecover-src/display_commands.c b/oldrecover-src/display_commands.c
new file mode 100644 (file)
index 0000000..0969a93
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: display_commands.c,v 1.3 2006/07/05 19:42:17 martinea Exp $
+ *
+ * implements the directory-display related commands in amrecover
+ */
+
+#include "amanda.h"
+#include "amrecover.h"
+#include "util.h"
+
+DIR_ITEM *get_dir_list(void);
+DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
+
+void clear_dir_list(void);
+void free_dir_item(DIR_ITEM *item);
+static int add_dir_list_item(char *date,
+                               int level,
+                               char *tape,
+                               off_t fileno,
+                               char *path);
+void list_disk_history(void);
+void suck_dir_list_from_server(void);
+void list_directory(void);
+
+static DIR_ITEM *dir_list = NULL;
+
+DIR_ITEM *
+get_dir_list(void)
+{
+    return dir_list;
+}
+
+DIR_ITEM *
+get_next_dir_item(
+    /*@keep@*/ DIR_ITEM *      this)
+{
+    return this->next;
+}
+
+
+void
+clear_dir_list(void)
+{
+    free_dir_item(dir_list); /* Frees all items from dir_list to end of list */
+    dir_list = NULL;
+}
+
+void
+free_dir_item(
+    DIR_ITEM * item)
+{
+    DIR_ITEM *next;
+
+    while (item != NULL) {
+       next = item->next;
+        amfree(item->date);
+        amfree(item->tape);
+        amfree(item->path);
+        amfree(item);
+       item = next;
+    }
+}
+
+/* add item to list if path not already on list */
+static int
+add_dir_list_item(
+    char *     date,
+    int                level,
+    char *     tape,
+    off_t      fileno,
+    char *     path)
+{
+    DIR_ITEM *next;
+
+    dbprintf(("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \""
+             OFF_T_FMT "\" \"%s\"\n",
+             date, level, tape, (OFF_T_FMT_TYPE)fileno, path));
+
+    next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+    memset(next, 0, sizeof(DIR_ITEM));
+
+    next->date = stralloc(date);
+    next->level = level;
+    next->tape = stralloc(tape);
+    next->fileno = fileno;
+    next->path = stralloc(path);
+
+    next->next = dir_list;
+    dir_list = next;
+
+    return 0;
+}
+
+
+void
+list_disk_history(void)
+{
+    if (converse("DHST") == -1)
+       exit(1);
+}
+
+
+void
+suck_dir_list_from_server(void)
+{
+    char *cmd = NULL;
+    char *err = NULL;
+    int i;
+    char *l = NULL;
+    char *date;
+    int level = 0;
+    off_t fileno = (off_t)-1;
+    char *tape, *tape_undo, tape_undo_ch = '\0';
+    char *dir, *qdir;
+    char *disk_path_slash = NULL;
+    char *disk_path_slash_dot = NULL;
+    char *s;
+    int ch;
+
+    if (disk_path == NULL) {
+       printf("Directory must be set before getting listing\n");
+       return;
+    } else if(strcmp(disk_path, "/") == 0) {
+       disk_path_slash = stralloc(disk_path);
+    } else {
+       disk_path_slash = stralloc2(disk_path, "/");
+    }
+
+    clear_dir_list();
+
+    cmd = stralloc2("OLSD ", disk_path);
+    if (send_command(cmd) == -1) {
+       amfree(cmd);
+       amfree(disk_path_slash);
+       exit(1);
+    }
+    amfree(cmd);
+    /* skip preamble */
+    if ((i = get_reply_line()) == -1) {
+       amfree(disk_path_slash);
+       exit(1);
+    }
+    if (i == 0)                                /* assume something wrong! */
+    {
+       amfree(disk_path_slash);
+       l = reply_line();
+       printf("%s\n", l);
+       return;
+    }
+    disk_path_slash_dot = stralloc2(disk_path_slash, ".");
+    amfree(cmd);
+    amfree(err);
+    tape_undo = NULL;
+    /* skip the last line -- duplicate of the preamble */
+    while ((i = get_reply_line()) != 0)
+    {
+       if (i == -1) {
+           amfree(disk_path_slash_dot);
+           amfree(disk_path_slash);
+           exit(1);
+       }
+       if(err) {
+           if(cmd == NULL) {
+               if(tape_undo) *tape_undo = tape_undo_ch;
+               tape_undo = NULL;
+               cmd = stralloc(l);      /* save for the error report */
+           }
+           continue;                   /* throw the rest of the lines away */
+       }
+       l = reply_line();
+       if (!server_happy())
+       {
+           printf("%s\n", l);
+           continue;
+       }
+#define sc "201-"
+       if (strncmp(l, sc, sizeof(sc)-1) != 0) {
+           err = "bad reply: not 201-";
+           continue;
+       }
+       s = l + sizeof(sc)-1;
+       ch = *s++;
+#undef sc
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           err = "bad reply: missing date field";
+           continue;
+       }
+       date = s - 1;
+       skip_non_whitespace(s, ch);
+       *(s - 1) = '\0';
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+           err = "bad reply: cannot parse level field";
+           continue;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           err = "bad reply: missing tape field";
+           continue;
+       }
+       tape = s - 1;
+       skip_non_whitespace(s, ch);
+       tape_undo = s - 1;
+       tape_undo_ch = *tape_undo;
+       *tape_undo = '\0';
+
+       if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_OLSD)) {
+           skip_whitespace(s, ch);
+           if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+                                   (OFF_T_FMT_TYPE *)&fileno) != 1) {
+               err = "bad reply: cannot parse fileno field";
+               continue;
+           }
+           skip_integer(s, ch);
+       }
+       else {
+           fileno = (off_t)-1;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           err = "bad reply: missing directory field";
+           continue;
+       }
+       qdir = s - 1;
+       dir = unquote_string(qdir);
+
+       /* add a '.' if it a the entry for the current directory */
+       if((strcmp(disk_path,dir)==0) || (strcmp(disk_path_slash,dir)==0)) {
+           amfree(dir);
+           dir = stralloc(disk_path_slash_dot);
+       }
+       add_dir_list_item(date, level, tape, fileno, dir);
+       amfree(dir);
+    }
+    amfree(disk_path_slash_dot);
+    amfree(disk_path_slash);
+    if(!server_happy()) {
+       puts(reply_line());
+    } else if(err) {
+       if(*err) {
+           puts(err);
+       }
+       if (cmd)
+          puts(cmd);
+       clear_dir_list();
+    }
+    amfree(cmd);
+}
+
+
+void
+list_directory(void)
+{
+    size_t i;
+    DIR_ITEM *item;
+    FILE *fp;
+    char *pager;
+    char *pager_command;
+    char *quoted;
+
+    if (disk_path == NULL) {
+       printf("Must select a disk before listing files; use the setdisk command.\n");
+       return;
+    }
+
+    if ((pager = getenv("PAGER")) == NULL)
+    {
+       pager = "more";
+    }
+    /*
+     * Set up the pager command so if the pager is terminated, we do
+     * not get a SIGPIPE back.
+     */
+    pager_command = stralloc2(pager, " ; /bin/cat > /dev/null");
+    if ((fp = popen(pager_command, "w")) == NULL)
+    {
+       printf("Warning - can't pipe through %s\n", pager);
+       fp = stdout;
+    }
+    amfree(pager_command);
+    i = strlen(disk_path);
+    if (i != 1)
+       i++;                            /* so disk_path != "/" */
+    for (item = get_dir_list(); item != NULL; item=get_next_dir_item(item)) {
+       quoted = quote_string(item->path + i);
+       fprintf(fp, "%s %s\n", item->date, quoted);
+       amfree(quoted);
+    }
+    apclose(fp);
+}
diff --git a/oldrecover-src/extract_list.c b/oldrecover-src/extract_list.c
new file mode 100644 (file)
index 0000000..5c5d92a
--- /dev/null
@@ -0,0 +1,2247 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: extract_list.c,v 1.6 2006/08/24 01:57:15 paddy_s Exp $
+ *
+ * implements the "extract" command in amrecover
+ */
+
+#include "amanda.h"
+#include "version.h"
+#include "amrecover.h"
+#include "fileheader.h"
+#include "dgram.h"
+#include "stream.h"
+#include "tapelist.h"
+#ifdef SAMBA_CLIENT
+#include "findpass.h"
+#endif
+#include "util.h"
+
+typedef struct EXTRACT_LIST_ITEM {
+    char *path;
+
+    struct EXTRACT_LIST_ITEM *next;
+}
+EXTRACT_LIST_ITEM;
+
+typedef struct EXTRACT_LIST {
+    char *date;                        /* date tape created */
+    int  level;                        /* level of dump */
+    char *tape;                        /* tape label */
+    off_t fileno;              /* fileno on tape */
+    EXTRACT_LIST_ITEM *files;  /* files to get off tape */
+
+    struct EXTRACT_LIST *next;
+}
+EXTRACT_LIST;
+
+#define SKIP_TAPE 2
+#define RETRY_TAPE 3
+
+char *dump_device_name = NULL;
+
+extern char *localhost;
+
+/* global pid storage for interrupt handler */
+pid_t extract_restore_child_pid = -1;
+
+static EXTRACT_LIST *extract_list = NULL;
+static int tape_control_sock = -1;
+static int tape_data_sock = -1;
+
+#ifdef SAMBA_CLIENT
+unsigned short samba_extract_method = SAMBA_TAR;
+#endif /* SAMBA_CLIENT */
+
+#define READ_TIMEOUT   240*60
+
+EXTRACT_LIST *first_tape_list(void);
+EXTRACT_LIST *next_tape_list(EXTRACT_LIST *list);
+int is_extract_list_nonempty(void);
+int length_of_tape_list(EXTRACT_LIST *tape_list);
+void add_file(char *path, char *regex);
+void add_glob(char *glob);
+void add_regex(char *regex);
+void clear_extract_list(void);
+void clean_tape_list(EXTRACT_LIST *tape_list);
+void clean_extract_list(void);
+void delete_file(char *path, char *regex);
+void delete_glob(char *glob);
+void delete_regex(char *regex);
+void delete_tape_list(EXTRACT_LIST *tape_list);
+void display_extract_list(char *file);
+void extract_files(void);
+void read_file_header(char *buffer,
+                       dumpfile_t *file,
+                       size_t buflen,
+                       int tapedev);
+void writer_intermediary(int ctl_fd, int data_fd, EXTRACT_LIST *elist);
+void writer_intermediary(int ctl_fd, int data_fd, EXTRACT_LIST *elist);
+
+static int add_extract_item(DIR_ITEM *ditem);
+static int delete_extract_item(DIR_ITEM *ditem);
+static int extract_files_setup(char *label, off_t fsf);
+static int okay_to_continue(int allow_tape,
+                       int allow_skip,
+                       int allow_retry);
+static int okay_to_continue(int, int,  int);
+static ssize_t read_buffer(int datafd,
+                       char *buffer,
+                       size_t buflen,
+                       long timeout_s);
+static void clear_tape_list(EXTRACT_LIST *tape_list);
+static void extract_files_child(int in_fd, EXTRACT_LIST *elist);
+static void send_to_tape_server(int tss, char *cmd);
+
+
+/*
+ * Function:  ssize_t read_buffer(datafd, buffer, buflen, timeout_s)
+ *
+ * Description:
+ *     read data from input file desciptor waiting up to timeout_s
+ *     seconds before returning data.
+ *
+ * Inputs:
+ *     datafd    - File descriptor to read from.
+ *     buffer    - Buffer to read into.
+ *     buflen    - Maximum number of bytes to read into buffer.
+ *     timeout_s - Seconds to wait before returning what was already read.
+ *
+ * Returns:
+ *      >0       - Number of data bytes in buffer.
+ *       0       - EOF
+ *      -1        - errno == ETIMEDOUT if no data available in specified time.
+ *                  errno == ENFILE if datafd is invalid.
+ *                  otherwise errno is set by select or read..
+ */
+
+static ssize_t
+read_buffer(
+    int                datafd,
+    char *     buffer,
+    size_t     buflen,
+    long       timeout_s)
+{
+    ssize_t size = 0;
+    fd_set readset;
+    struct timeval timeout;
+    char *dataptr;
+    ssize_t spaceleft;
+    int nfound;
+
+    if(datafd < 0 || datafd >= (int)FD_SETSIZE) {
+       errno = EMFILE;                                 /* out of range */
+       return -1;
+    }
+
+    dataptr = buffer;
+    spaceleft = (ssize_t)buflen;
+
+    do {
+        FD_ZERO(&readset);
+        FD_SET(datafd, &readset);
+        timeout.tv_sec = timeout_s;
+        timeout.tv_usec = 0;
+        nfound = select(datafd+1, &readset, NULL, NULL, &timeout);
+        if(nfound < 0 ) {
+            /* Select returned an error. */
+           fprintf(stderr,"select error: %s\n", strerror(errno));
+            size = -1;
+           break;
+        }
+
+       if (nfound == 0) {
+            /* Select timed out. */
+            if (timeout_s != 0)  {
+                /* Not polling: a real read timeout */
+                fprintf(stderr,"timeout waiting for restore\n");
+                fprintf(stderr,"increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n");
+            }
+            errno = ETIMEDOUT;
+            size = -1;
+           break;
+        }
+
+       if(!FD_ISSET(datafd, &readset))
+           continue;
+
+        /* Select says data is available, so read it.  */
+        size = read(datafd, dataptr, (size_t)spaceleft);
+        if (size < 0) {
+           if ((errno == EINTR) || (errno == EAGAIN)) {
+               continue;
+           }
+           if (errno != EPIPE) {
+               fprintf(stderr, "read_buffer: read error - %s",
+                   strerror(errno));
+               break;
+           }
+           size = 0;
+       }
+        spaceleft -= size;
+        dataptr += size;
+    } while ((size > 0) && (spaceleft > 0));
+
+    return ((((ssize_t)buflen-spaceleft) > 0) ? ((ssize_t)buflen-spaceleft) : size);
+}
+
+
+EXTRACT_LIST *
+first_tape_list(void)
+{
+    return extract_list;
+}
+
+EXTRACT_LIST *
+next_tape_list(
+    /*@keep@*/ EXTRACT_LIST *list)
+{
+    if (list == NULL)
+       return NULL;
+    return list->next;
+}
+
+static void
+clear_tape_list(
+    EXTRACT_LIST *     tape_list)
+{
+    EXTRACT_LIST_ITEM *this, *next;
+    
+
+    this = tape_list->files;
+    while (this != NULL)
+    {
+       next = this->next;
+        amfree(this->path);
+        amfree(this);
+       this = next;
+    }
+    tape_list->files = NULL;
+}
+
+
+/* remove a tape list from the extract list, clearing the tape list
+   beforehand if necessary */
+void
+delete_tape_list(
+    EXTRACT_LIST *     tape_list)
+{
+    EXTRACT_LIST *this, *prev;
+
+    if (tape_list == NULL)
+        return;
+
+    /* is it first on the list? */
+    if (tape_list == extract_list)
+    {
+       extract_list = tape_list->next;
+       clear_tape_list(tape_list);
+        amfree(tape_list->date);
+        amfree(tape_list->tape);
+       amfree(tape_list);
+       return;
+    }
+
+    /* so not first on list - find it and delete */
+    prev = extract_list;
+    this = extract_list->next;
+    while (this != NULL)
+    {
+       if (this == tape_list)
+       {
+           prev->next = tape_list->next;
+           clear_tape_list(tape_list);
+            amfree(tape_list->date);
+            amfree(tape_list->tape);
+           amfree(tape_list);
+           return;
+       }
+       prev = this;
+       this = this->next;
+    }
+    /*NOTREACHED*/
+}
+
+
+/* return the number of files on a tape's list */
+int
+length_of_tape_list(
+    EXTRACT_LIST *     tape_list)
+{
+    EXTRACT_LIST_ITEM *fn;
+    int n;
+
+    n = 0;
+    for (fn = tape_list->files; fn != NULL; fn = fn->next)
+       n++;
+
+    return n;
+}
+
+
+void
+clear_extract_list(void)
+{
+    while (extract_list != NULL)
+       delete_tape_list(extract_list);
+}
+
+
+void
+clean_tape_list(
+    EXTRACT_LIST *tape_list)
+{
+    EXTRACT_LIST_ITEM *fn1, *pfn1, *ofn1;
+    EXTRACT_LIST_ITEM *fn2, *pfn2, *ofn2;
+    int remove_fn1;
+    int remove_fn2;
+
+    pfn1 = NULL;
+    fn1 = tape_list->files;
+    while (fn1 != NULL) {
+       remove_fn1 = 0;
+
+       pfn2 = fn1;
+       fn2 = fn1->next;
+       while (fn2 != NULL && remove_fn1 == 0) {
+           remove_fn2 = 0;
+           if(strcmp(fn1->path, fn2->path) == 0) {
+               remove_fn2 = 1;
+           } else if (strncmp(fn1->path, fn2->path, strlen(fn1->path)) == 0 &&
+                      ((strlen(fn2->path) > strlen(fn1->path) &&
+                        fn2->path[strlen(fn1->path)] == '/') ||
+                      (fn1->path[strlen(fn1->path)-1] == '/'))) {
+               remove_fn2 = 1;
+           } else if (strncmp(fn2->path, fn1->path, strlen(fn2->path)) == 0 &&
+                      ((strlen(fn1->path) > strlen(fn2->path) &&
+                        fn1->path[strlen(fn2->path)] == '/')  ||
+                      (fn2->path[strlen(fn2->path)-1] == '/'))) {
+               remove_fn1 = 1;
+               break;
+           }
+
+           if (remove_fn2) {
+               dbprintf(("removing path %s, it is included in %s\n",
+                         fn2->path, fn1->path));
+               ofn2 = fn2;
+               fn2 = fn2->next;
+               amfree(ofn2->path);
+               amfree(ofn2);
+               pfn2->next = fn2;
+           } else if (remove_fn1 == 0) {
+               pfn2 = fn2;
+               fn2 = fn2->next;
+           }
+       }
+
+       if(remove_fn1 != 0) {
+           /* fn2->path is always valid */
+           /*@i@*/ dbprintf(("removing path %s, it is included in %s\n",
+           /*@i@*/           fn1->path, fn2->path));
+           ofn1 = fn1;
+           fn1 = fn1->next;
+           amfree(ofn1->path);
+           if(pfn1 == NULL) {
+               amfree(tape_list->files);
+               tape_list->files = fn1;
+           } else {
+               amfree(pfn1->next);
+               pfn1->next = fn1;
+           }
+       } else {
+           pfn1 = fn1;
+           fn1 = fn1->next;
+       }
+    }
+}
+
+
+void
+clean_extract_list(void)
+{
+    EXTRACT_LIST *this;
+
+    for (this = extract_list; this != NULL; this = this->next)
+       clean_tape_list(this);
+}
+
+
+/* returns -1 if error */
+/* returns  0 on succes */
+/* returns  1 if already added */
+static int
+add_extract_item(
+    DIR_ITEM * ditem)
+{
+    EXTRACT_LIST *this, *this1;
+    EXTRACT_LIST_ITEM *that, *curr;
+    char *ditem_path = NULL;
+
+    ditem_path = stralloc(ditem->path);
+    clean_pathname(ditem_path);
+
+    for (this = extract_list; this != NULL; this = this->next)
+    {
+       /* see if this is the list for the tape */      
+       if (this->level == ditem->level && strcmp(this->tape, ditem->tape) == 0)
+       {
+           /* yes, so add to list */
+           curr=this->files;
+           while(curr!=NULL)
+           {
+               if (strcmp(curr->path, ditem_path) == 0) {
+                   amfree(ditem_path);
+                   return 1;
+               }
+               curr=curr->next;
+           }
+           that = (EXTRACT_LIST_ITEM *)alloc(sizeof(EXTRACT_LIST_ITEM));
+            that->path = stralloc(ditem_path);
+           that->next = this->files;
+           this->files = that;         /* add at front since easiest */
+           amfree(ditem_path);
+           return 0;
+       }
+    }
+
+    /* so this is the first time we have seen this tape */
+    this = (EXTRACT_LIST *)alloc(sizeof(EXTRACT_LIST));
+    this->tape = stralloc(ditem->tape);
+    this->level = ditem->level;
+    this->fileno = ditem->fileno;
+    this->date = stralloc(ditem->date);
+    that = (EXTRACT_LIST_ITEM *)alloc(sizeof(EXTRACT_LIST_ITEM));
+    that->path = stralloc(ditem_path);
+    that->next = NULL;
+    this->files = that;
+
+    /* add this in date increasing order          */
+    /* because restore must be done in this order */
+    /* add at begining */
+    if(extract_list==NULL || strcmp(this->date,extract_list->date) < 0) 
+    {
+       this->next = extract_list;
+       extract_list = this;
+       amfree(ditem_path);
+       return 0;
+    }
+    for (this1 = extract_list; this1->next != NULL; this1 = this1->next)
+    {
+       /* add in the middle */
+       if(strcmp(this->date,this1->next->date) < 0)
+       {
+           this->next = this1->next;
+           this1->next = this;
+           amfree(ditem_path);
+           return 0;
+       }
+    }
+    /* add at end */
+    this->next = NULL;
+    this1->next = this;
+    amfree(ditem_path);
+    return 0;
+}
+
+
+/* returns -1 if error */
+/* returns  0 on deletion */
+/* returns  1 if not there */
+static int
+delete_extract_item(
+    DIR_ITEM * ditem)
+{
+    EXTRACT_LIST *this;
+    EXTRACT_LIST_ITEM *that, *prev;
+    char *ditem_path = NULL;
+
+    ditem_path = stralloc(ditem->path);
+    clean_pathname(ditem_path);
+
+    for (this = extract_list; this != NULL; this = this->next)
+    {
+       /* see if this is the list for the tape */      
+       if (this->level == ditem->level && strcmp(this->tape, ditem->tape) == 0)
+       {
+           /* yes, so find file on list */
+           that = this->files;
+           if (strcmp(that->path, ditem_path) == 0)
+           {
+               /* first on list */
+               this->files = that->next;
+                amfree(that->path);
+               amfree(that);
+               /* if list empty delete it */
+               if (this->files == NULL)
+                   delete_tape_list(this);
+               amfree(ditem_path);
+               return 0;
+           }
+           prev = that;
+           that = that->next;
+           while (that != NULL)
+           {
+               if (strcmp(that->path, ditem_path) == 0)
+               {
+                   prev->next = that->next;
+                    amfree(that->path);
+                   amfree(that);
+                   amfree(ditem_path);
+                   return 0;
+               }
+               prev = that;
+               that = that->next;
+           }
+           amfree(ditem_path);
+           return 1;
+       }
+    }
+
+    amfree(ditem_path);
+    return 1;
+}
+
+void
+add_glob(
+    char *     glob)
+{
+    char *regex;
+    char *regex_path;
+    char *s;
+    char *uqglob = unquote_string(glob);
+
+    regex = glob_to_regex(uqglob);
+    dbprintf(("add_glob (%s) -> %s\n", uqglob, regex));
+    if ((s = validate_regexp(regex)) != NULL) {
+       printf("%s is not a valid shell wildcard pattern: ", glob);
+       puts(s);
+    } else {
+        /*
+         * glob_to_regex() anchors the beginning of the pattern with ^,
+         * but we will be tacking it onto the end of the current directory
+         * in add_file, so strip that off.  Also, it anchors the end with
+         * $, but we need to match an optional trailing /, so tack that on
+         * the end.
+         */
+        regex_path = stralloc(regex + 1);
+        regex_path[strlen(regex_path) - 1] = '\0';
+        strappend(regex_path, "[/]*$");
+        add_file(uqglob, regex_path);
+        amfree(regex_path);
+    }
+    amfree(regex);
+    amfree(uqglob);
+}
+
+void
+add_regex(
+    char *     regex)
+{
+    char *s;
+    char *uqregex = unquote_string(regex);
+
+    if ((s = validate_regexp(uqregex)) != NULL) {
+       printf("%s is not a valid regular expression: ", regex);
+       puts(s);
+    } else {
+        add_file(uqregex, regex);
+    }
+    amfree(uqregex);
+}
+
+void add_file(
+    char *     path,
+    char *     regex)
+{
+    DIR_ITEM *ditem, lditem;
+    char *path_on_disk = NULL;
+    char *path_on_disk_slash = NULL;
+    char *cmd = NULL;
+    char *err = NULL;
+    int i;
+    ssize_t j;
+    char *dir, *dir_undo, dir_undo_ch = '\0';
+    char *ditem_path = NULL;
+    char *l = NULL;
+    int  added;
+    char *s, *fp, *quoted;
+    int ch;
+    int found_one;
+    int dir_entries;
+
+    if (disk_path == NULL) {
+       printf("Must select directory before adding files\n");
+       return;
+    }
+    memset(&lditem, 0, sizeof(lditem)); /* Prevent use of bogus data... */
+
+    dbprintf(("add_file: Looking for \"%s\"\n", regex));
+
+    if(strcmp(regex, "/[/]*$") == 0) { /* "/" behave like "." */
+       regex = "\\.[/]*$";
+    }
+    else if(strcmp(regex, "[^/]*[/]*$") == 0) {                /* "*" */
+       //regex = 
+       regex = "([^/.]|\\.[^/]+|[^/.][^/]*)[/]*$";
+    } else {
+       /* remove "/" at end of path */
+       j = (ssize_t)(strlen(regex) - 1);
+       while(j >= 0 && regex[j] == '/')
+           regex[j--] = '\0';
+    }
+
+    /* convert path (assumed in cwd) to one on disk */
+    if (strcmp(disk_path, "/") == 0) {
+        if (*regex == '/') {
+           /* No mods needed if already starts with '/' */
+           path_on_disk = stralloc(regex);
+       } else {
+           /* Prepend '/' */
+           path_on_disk = stralloc2("/", regex);
+       }
+    } else {
+       char *clean_disk_path = clean_regex(disk_path);
+       path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
+       amfree(clean_disk_path);
+    }
+
+    path_on_disk_slash = stralloc2(path_on_disk, "/");
+
+    dbprintf(("add_file: Converted path=\"%s\" to path_on_disk=\"%s\"\n",
+             regex, path_on_disk));
+
+    found_one = 0;
+    dir_entries = 0;
+    for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
+    {
+       dir_entries++;
+       quoted = quote_string(ditem->path);
+       dbprintf(("add_file: Pondering ditem->path=%s\n", quoted));
+       amfree(quoted);
+       if (match(path_on_disk, ditem->path)
+           || match(path_on_disk_slash, ditem->path))
+       {
+           found_one = 1;
+           j = (ssize_t)strlen(ditem->path);
+           if((j > 0 && ditem->path[j-1] == '/')
+              || (j > 1 && ditem->path[j-2] == '/' && ditem->path[j-1] == '.'))
+           {   /* It is a directory */
+               ditem_path = newstralloc(ditem_path, ditem->path);
+               clean_pathname(ditem_path);
+
+               cmd = stralloc2("ORLD ", ditem_path);
+               if(send_command(cmd) == -1) {
+                   amfree(cmd);
+                   amfree(ditem_path);
+                   amfree(path_on_disk);
+                   amfree(path_on_disk_slash);
+                   exit(1);
+               }
+               amfree(cmd);
+               cmd = NULL;
+               /* skip preamble */
+               if ((i = get_reply_line()) == -1) {
+                   amfree(ditem_path);
+                   amfree(path_on_disk);
+                   amfree(path_on_disk_slash);
+                   exit(1);
+               }
+               if(i==0) {              /* assume something wrong */
+                   amfree(ditem_path);
+                   amfree(path_on_disk);
+                   amfree(path_on_disk_slash);
+                   l = reply_line();
+                   printf("%s\n", l);
+                   return;
+               }
+               dir_undo = NULL;
+               added=0;
+                lditem.path = newstralloc(lditem.path, ditem->path);
+               /* skip the last line -- duplicate of the preamble */
+
+               while ((i = get_reply_line()) != 0) {
+                   if (i == -1) {
+                       amfree(ditem_path);
+                       amfree(path_on_disk);
+                       amfree(path_on_disk_slash);
+                       exit(1);
+                   }
+                   if(err) {
+                       if(cmd == NULL) {
+                           if(dir_undo) *dir_undo = dir_undo_ch;
+                           dir_undo = NULL;
+                           cmd = stralloc(l);  /* save for error report */
+                       }
+                       continue;       /* throw the rest of the lines away */
+                   }
+                   l=reply_line();
+                   if (!server_happy()) {
+                       puts(l);
+                       continue;
+                   }
+#define sc "201-"
+                   if(strncmp(l, sc, sizeof(sc)-1) != 0) {
+                       err = "bad reply: not 201-";
+                       continue;
+                   }
+
+                   s = l + sizeof(sc)-1;
+                   ch = *s++;
+#undef sc
+                   skip_whitespace(s, ch);
+                   if(ch == '\0') {
+                       err = "bad reply: missing date field";
+                       continue;
+                   }
+                    fp = s-1;
+                    skip_non_whitespace(s, ch);
+                    s[-1] = '\0';
+                    lditem.date = newstralloc(lditem.date, fp);
+                    s[-1] = (char)ch;
+
+                   skip_whitespace(s, ch);
+                   if(ch == '\0' || sscanf(s - 1, "%d", &lditem.level) != 1) {
+                       err = "bad reply: cannot parse level field";
+                       continue;
+                   }
+                   skip_integer(s, ch);
+
+                   skip_whitespace(s, ch);
+                   if(ch == '\0') {
+                       err = "bad reply: missing tape field";
+                       continue;
+                   }
+                    fp = s-1;
+                    skip_non_whitespace(s, ch);
+                    s[-1] = '\0';
+                    lditem.tape = newstralloc(lditem.tape, fp);
+                    s[-1] = (char)ch;
+
+                   if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_ORLD)) {
+                       skip_whitespace(s, ch);
+                       if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&lditem.fileno) != 1) {
+                           err = "bad reply: cannot parse fileno field";
+                           continue;
+                       }
+                       skip_integer(s, ch);
+                   }
+
+                   skip_whitespace(s, ch);
+                   if(ch == '\0') {
+                       err = "bad reply: missing directory field";
+                       continue;
+                   }
+                   dir = s - 1;
+                   skip_quoted_string(s, ch);
+                   dir_undo = s - 1;
+                   dir_undo_ch = *dir_undo;
+                   *dir_undo = '\0';
+
+                   switch(add_extract_item(&lditem)) {
+                   case -1:
+                       printf("System error\n");
+                       dbprintf(("add_file: (Failed) System error\n"));
+                       break;
+
+                   case  0:
+                       quoted = quote_string(lditem.path);
+                       printf("Added dir %s at date %s\n",
+                              quoted, lditem.date);
+                       dbprintf(("add_file: (Successful) Added dir %s at date %s\n",
+                                 quoted, lditem.date));
+                       amfree(quoted);
+                       added=1;
+                       break;
+
+                   case  1:
+                       break;
+                   }
+               }
+               if(!server_happy()) {
+                   puts(reply_line());
+               } else if(err) {
+                   if (*err)
+                       puts(err);
+                   if (cmd)
+                       puts(cmd);
+               } else if(added == 0) {
+                   quoted = quote_string(ditem_path);
+                   printf("dir %s already added\n", quoted);
+                   dbprintf(("add_file: dir %s already added\n", quoted));
+                   amfree(quoted);
+               }
+           }
+           else /* It is a file */
+           {
+               switch(add_extract_item(ditem)) {
+               case -1:
+                   printf("System error\n");
+                   dbprintf(("add_file: (Failed) System error\n"));
+                   break;
+
+               case  0:
+                   quoted = quote_string(ditem->path);
+                   printf("Added file %s\n", quoted);
+                   dbprintf(("add_file: (Successful) Added %s\n", quoted));
+                   amfree(quoted);
+                   break;
+
+               case  1:
+                   quoted = quote_string(ditem->path);
+                   printf("File %s already added\n", quoted);
+                   dbprintf(("add_file: file %s already added\n", quoted));
+                   amfree(quoted);
+                   break;
+               }
+           }
+       }
+    }
+    if (cmd != NULL)
+       amfree(cmd);
+    amfree(ditem_path);
+    amfree(path_on_disk);
+    amfree(path_on_disk_slash);
+
+    if(! found_one) {
+       quoted = quote_string(path);
+       printf("File %s doesn't exist in directory\n", quoted);
+       dbprintf(("add_file: (Failed) File %s doesn't exist in directory\n",
+                 quoted));
+       amfree(quoted);
+    }
+}
+
+
+void
+delete_glob(
+    char *     glob)
+{
+    char *regex;
+    char *regex_path;
+    char *s;
+    char *uqglob = unquote_string(glob);
+
+    regex = glob_to_regex(uqglob);
+    dbprintf(("delete_glob (%s) -> %s\n", uqglob, regex));
+    if ((s = validate_regexp(regex)) != NULL) {
+       printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+       puts(s);
+    } else {
+        /*
+         * glob_to_regex() anchors the beginning of the pattern with ^,
+         * but we will be tacking it onto the end of the current directory
+         * in add_file, so strip that off.  Also, it anchors the end with
+         * $, but we need to match an optional trailing /, so tack that on
+         * the end.
+         */
+        regex_path = stralloc(regex + 1);
+        regex_path[strlen(regex_path) - 1] = '\0';
+        strappend(regex_path, "[/]*$");
+        delete_file(uqglob, regex_path);
+        amfree(regex_path);
+    }
+    amfree(regex);
+    amfree(uqglob);
+}
+
+void
+delete_regex(
+    char *     regex)
+{
+    char *s;
+    char *uqregex = unquote_string(regex);
+
+    if ((s = validate_regexp(regex)) != NULL) {
+       printf("\"%s\" is not a valid regular expression: ", regex);
+       puts(s);
+    } else {
+       delete_file(uqregex, uqregex);
+    }
+    amfree(uqregex);
+}
+
+void
+delete_file(
+    char *     path,
+    char *     regex)
+{
+    DIR_ITEM *ditem, lditem;
+    char *path_on_disk = NULL;
+    char *path_on_disk_slash = NULL;
+    char *cmd = NULL;
+    char *err = NULL;
+    int i;
+    ssize_t j;
+    char *date;
+    char *tape, *tape_undo, tape_undo_ch = '\0';
+    char *dir_undo, dir_undo_ch = '\0';
+    int  level = 0;
+    off_t fileno;
+    char *ditem_path = NULL;
+    char *l = NULL;
+    int  deleted;
+    char *s;
+    int ch;
+    int found_one;
+    char *quoted;
+
+    if (disk_path == NULL) {
+       printf("Must select directory before deleting files\n");
+       return;
+    }
+    memset(&lditem, 0, sizeof(lditem)); /* Prevent use of bogus data... */
+
+    dbprintf(("delete_file: Looking for \"%s\"\n", path));
+
+    if (strcmp(regex, "[^/]*[/]*$") == 0) {
+       /* Looking for * find everything but single . */
+       regex = "([^/.]|\\.[^/]+|[^/.][^/]*)[/]*$";
+    } else {
+       /* remove "/" at end of path */
+       j = (ssize_t)(strlen(regex) - 1);
+       while(j >= 0 && regex[j] == '/') regex[j--] = '\0';
+    }
+
+    /* convert path (assumed in cwd) to one on disk */
+    if (strcmp(disk_path, "/") == 0) {
+        if (*regex == '/') {
+           if (strcmp(regex, "/[/]*$") == 0) {
+               /* We want "/" to match the directory itself: "/." */
+               path_on_disk = stralloc("/\\.[/]*$");
+           } else {
+               /* No mods needed if already starts with '/' */
+               path_on_disk = stralloc(regex);
+           }
+       } else {
+           /* Prepend '/' */
+           path_on_disk = stralloc2("/", regex);
+       }
+    } else {
+       char *clean_disk_path = clean_regex(disk_path);
+       path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
+       amfree(clean_disk_path);
+    }
+
+    path_on_disk_slash = stralloc2(path_on_disk, "/");
+
+    dbprintf(("delete_file: Converted path=\"%s\" to path_on_disk=\"%s\"\n",
+             regex, path_on_disk));
+    found_one = 0;
+    for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
+    {
+       quoted = quote_string(ditem->path);
+       dbprintf(("delete_file: Pondering ditem->path=%s\n", quoted));
+       amfree(quoted);
+       if (match(path_on_disk, ditem->path)
+           || match(path_on_disk_slash, ditem->path))
+       {
+           found_one = 1;
+           j = (ssize_t)strlen(ditem->path);
+           if((j > 0 && ditem->path[j-1] == '/')
+              || (j > 1 && ditem->path[j-2] == '/' && ditem->path[j-1] == '.'))
+           {   /* It is a directory */
+               ditem_path = newstralloc(ditem_path, ditem->path);
+               clean_pathname(ditem_path);
+
+               cmd = stralloc2("ORLD ", ditem_path);
+               if(send_command(cmd) == -1) {
+                   amfree(cmd);
+                   amfree(ditem_path);
+                   amfree(path_on_disk);
+                   amfree(path_on_disk_slash);
+                   exit(1);
+               }
+               amfree(cmd);
+               /* skip preamble */
+               if ((i = get_reply_line()) == -1) {
+                   amfree(ditem_path);
+                   amfree(path_on_disk);
+                   amfree(path_on_disk_slash);
+                   exit(1);
+               }
+               if(i==0)                /* assume something wrong */
+               {
+                   amfree(ditem_path);
+                   amfree(path_on_disk);
+                   amfree(path_on_disk_slash);
+                   l = reply_line();
+                   printf("%s\n", l);
+                   return;
+               }
+               deleted=0;
+                lditem.path = newstralloc(lditem.path, ditem->path);
+               amfree(cmd);
+               tape_undo = dir_undo = NULL;
+               /* skip the last line -- duplicate of the preamble */
+               while ((i = get_reply_line()) != 0)
+               {
+                   if (i == -1) {
+                       amfree(ditem_path);
+                       amfree(path_on_disk);
+                       amfree(path_on_disk_slash);
+                       exit(1);
+                   }
+                   if(err) {
+                       if(cmd == NULL) {
+                           if(tape_undo) *tape_undo = tape_undo_ch;
+                           if(dir_undo) *dir_undo = dir_undo_ch;
+                           tape_undo = dir_undo = NULL;
+                           cmd = stralloc(l);  /* save for the error report */
+                       }
+                       continue;       /* throw the rest of the lines away */
+                   }
+                   l=reply_line();
+                   if (!server_happy()) {
+                       puts(l);
+                       continue;
+                   }
+#define sc "201-"
+                   if(strncmp(l, sc, sizeof(sc)-1) != 0) {
+                       err = "bad reply: not 201-";
+                       continue;
+                   }
+                   s = l + sizeof(sc)-1;
+                   ch = *s++;
+#undef sc
+                   skip_whitespace(s, ch);
+                   if(ch == '\0') {
+                       err = "bad reply: missing date field";
+                       continue;
+                   }
+                   date = s - 1;
+                   skip_non_whitespace(s, ch);
+                   *(s - 1) = '\0';
+
+                   skip_whitespace(s, ch);
+                   if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+                       err = "bad reply: cannot parse level field";
+                       continue;
+                   }
+                   skip_integer(s, ch);
+
+                   skip_whitespace(s, ch);
+                   if(ch == '\0') {
+                       err = "bad reply: missing tape field";
+                       continue;
+                   }
+                   tape = s - 1;
+                   skip_non_whitespace(s, ch);
+                   tape_undo = s - 1;
+                   tape_undo_ch = *tape_undo;
+                   *tape_undo = '\0';
+
+                   if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_ORLD)) {
+                       skip_whitespace(s, ch);
+                       if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&fileno) != 1) {
+                           err = "bad reply: cannot parse fileno field";
+                           continue;
+                       }
+                       skip_integer(s, ch);
+                   }
+
+                   skip_whitespace(s, ch);
+                   if(ch == '\0') {
+                       err = "bad reply: missing directory field";
+                       continue;
+                   }
+                   skip_non_whitespace(s, ch);
+                   dir_undo = s - 1;
+                   dir_undo_ch = *dir_undo;
+                   *dir_undo = '\0';
+
+                    lditem.date = newstralloc(lditem.date, date);
+                   lditem.level=level;
+                    lditem.tape = newstralloc(lditem.tape, tape);
+                   switch(delete_extract_item(&lditem)) {
+                   case -1:
+                       printf("System error\n");
+                       dbprintf(("delete_file: (Failed) System error\n"));
+                       break;
+                   case  0:
+                       printf("Deleted dir %s at date %s\n", ditem_path, date);
+                       dbprintf(("delete_file: (Successful) Deleted dir %s at date %s\n",
+                                 ditem_path, date));
+                       deleted=1;
+                       break;
+                   case  1:
+                       break;
+                   }
+               }
+               if(!server_happy()) {
+                   puts(reply_line());
+               } else if(err) {
+                   if (*err)
+                       puts(err);
+                   if (cmd)
+                       puts(cmd);
+               } else if(deleted == 0) {
+                   printf("Warning - dir '%s' not on tape list\n",
+                          ditem_path);
+                   dbprintf(("delete_file: dir '%s' not on tape list\n",
+                             ditem_path));
+               }
+           }
+           else
+           {
+               switch(delete_extract_item(ditem)) {
+               case -1:
+                   printf("System error\n");
+                   dbprintf(("delete_file: (Failed) System error\n"));
+                   break;
+               case  0:
+                   printf("Deleted %s\n", ditem->path);
+                   dbprintf(("delete_file: (Successful) Deleted %s\n",
+                             ditem->path));
+                   break;
+               case  1:
+                   printf("Warning - file '%s' not on tape list\n",
+                          ditem->path);
+                   dbprintf(("delete_file: file '%s' not on tape list\n",
+                             ditem->path));
+                   break;
+               }
+           }
+       }
+    }
+    amfree(cmd);
+    amfree(ditem_path);
+    amfree(path_on_disk);
+    amfree(path_on_disk_slash);
+
+    if(! found_one) {
+       printf("File %s doesn't exist in directory\n", path);
+       dbprintf(("delete_file: (Failed) File %s doesn't exist in directory\n",
+                 path));
+    }
+}
+
+
+/* print extract list into file. If NULL ptr passed print to screen */
+void
+display_extract_list(
+    char *     file)
+{
+    EXTRACT_LIST *this;
+    EXTRACT_LIST_ITEM *that;
+    FILE *fp;
+    char *pager;
+    char *pager_command;
+    char *uqfile;
+
+    if (file == NULL)
+    {
+       if ((pager = getenv("PAGER")) == NULL)
+       {
+           pager = "more";
+       }
+       /*
+        * Set up the pager command so if the pager is terminated, we do
+        * not get a SIGPIPE back.
+        */
+       pager_command = stralloc2(pager, " ; /bin/cat > /dev/null");
+       if ((fp = popen(pager_command, "w")) == NULL)
+       {
+           printf("Warning - can't pipe through %s\n", pager);
+           fp = stdout;
+       }
+       amfree(pager_command);
+    }
+    else
+    {
+       uqfile = unquote_string(file);
+       if ((fp = fopen(uqfile, "w")) == NULL)
+       {
+           printf("Can't open file %s to print extract list into\n", file);
+           amfree(uqfile);
+           return;
+       }
+       amfree(uqfile);
+    }
+
+    for (this = extract_list; this != NULL; this = this->next)
+    {
+       fprintf(fp, "TAPE %s LEVEL %d DATE %s\n",
+               this->tape, this->level, this->date);
+       for (that = this->files; that != NULL; that = that->next)
+           fprintf(fp, "\t%s\n", that->path);
+    }
+
+    if (file == NULL) {
+       apclose(fp);
+    } else {
+       printf("Extract list written to file %s\n", file);
+       afclose(fp);
+    }
+}
+
+
+/* returns 0 if extract list empty and 1 if it isn't */
+int
+is_extract_list_nonempty(void)
+{
+    return (extract_list != NULL);
+}
+
+
+/* prints continue prompt and waits for response,
+   returns 0 if don't, non-0 if do */
+static int
+okay_to_continue(
+    int                allow_tape,
+    int                allow_skip,
+    int                allow_retry)
+{
+    int ch;
+    int ret = -1;
+    char *line = NULL;
+    char *s;
+    char *prompt;
+    int get_tape;
+
+    get_tape = 0;
+    while (ret < 0) {
+       if (get_tape) {
+           prompt = "New tape device [?]: ";
+       } else if (allow_tape && allow_skip) {
+           prompt = "Continue [?/Y/n/s/t]? ";
+       } else if (allow_tape && !allow_skip) {
+           prompt = "Continue [?/Y/n/t]? ";
+       } else if (allow_retry) {
+           prompt = "Continue [?/Y/n/r]? ";
+       } else {
+           prompt = "Continue [?/Y/n]? ";
+       }
+       fputs(prompt, stdout);
+       fflush(stdout); fflush(stderr);
+       amfree(line);
+       if ((line = agets(stdin)) == NULL) {
+           putchar('\n');
+           clearerr(stdin);
+           if (get_tape) {
+               get_tape = 0;
+               continue;
+           }
+           ret = 0;
+           break;
+       }
+       s = line;
+       while ((ch = *s++) != '\0' && isspace(ch)) {
+           (void)ch;  /* Quiet empty loop body warning */
+       }
+       if (ch == '?') {
+           if (get_tape) {
+               printf("Enter a new device ([host:]device) or \"default\"\n");
+           } else {
+               printf("Enter \"y\"es to continue, \"n\"o to stop");
+               if(allow_skip) {
+                   printf(", \"s\"kip this tape");
+               }
+               if(allow_retry) {
+                   printf(" or \"r\"etry this tape");
+               }
+               if (allow_tape) {
+                   printf(" or \"t\"ape to change tape drives");
+               }
+               putchar('\n');
+           }
+       } else if (get_tape) {
+           set_tape(s - 1);
+           get_tape = 0;
+       } else if (ch == '\0' || ch == 'Y' || ch == 'y') {
+           ret = 1;
+       } else if (allow_tape && (ch == 'T' || ch == 't')) {
+           get_tape = 1;
+       } else if (ch == 'N' || ch == 'n') {
+           ret = 0;
+       } else if (allow_retry && (ch == 'R' || ch == 'r')) {
+           ret = RETRY_TAPE;
+       } else if (allow_skip && (ch == 'S' || ch == 's')) {
+           ret = SKIP_TAPE;
+       }
+    }
+    /*@ignore@*/
+    amfree(line);
+    /*@end@*/
+    return ret;
+}
+
+static void
+send_to_tape_server(
+    int                tss,
+    char *     cmd)
+{
+    char *msg = stralloc2(cmd, "\r\n");
+
+    if (fullwrite(tss, msg, strlen(msg)) < 0)
+    {
+       error("Error writing to tape server");
+       /*NOTREACHED*/
+    }
+    amfree(msg);
+}
+
+
+/* start up connection to tape server and set commands to initiate
+   transfer of dump image.
+   Return tape server socket on success, -1 on error. */
+static int
+extract_files_setup(
+    char *     label,
+    off_t      fsf)
+{
+    struct servent *sp;
+    in_port_t my_port, my_data_port;
+    char *disk_regex = NULL;
+    char *host_regex = NULL;
+    char *service_name = NULL;
+    char *line = NULL;
+    char *clean_datestamp, *ch, *ch1;
+    char *our_feature_string = NULL;
+    char *tt = NULL;
+
+    service_name = stralloc2("amidxtape", SERVICE_SUFFIX);
+
+    /* get tape server details */
+    if ((sp = getservbyname(service_name, "tcp")) == NULL)
+    {
+       printf("%s/tcp unknown protocol - config error?\n", service_name);
+       amfree(service_name);
+       return -1;
+    }
+    amfree(service_name);
+    seteuid(0);                                        /* it either works ... */
+    setegid(0);
+    tape_control_sock = stream_client_privileged(tape_server_name,
+                                                 (in_port_t)ntohs((in_port_t)sp->s_port),
+                                                 0,
+                                                 STREAM_BUFSIZE,
+                                                 &my_port,
+                                                 0);
+    if (tape_control_sock < 0)
+    {
+       printf("cannot connect to %s: %s\n", tape_server_name, strerror(errno));
+       return -1;
+    }
+    if (my_port >= IPPORT_RESERVED) {
+       aclose(tape_control_sock);
+       printf("did not get a reserved port: %u\n", (unsigned)my_port);
+       return -1;
+    }
+    setegid(getgid());
+    seteuid(getuid());                         /* put it back */
+
+    /* do the security thing */
+    line = get_security();
+    send_to_tape_server(tape_control_sock, line);
+    memset(line, '\0', strlen(line));
+    amfree(line);
+
+    disk_regex = alloc(strlen(disk_name) * 2 + 3);
+
+    ch = disk_name;
+    ch1 = disk_regex;
+
+    /* we want to force amrestore to only match disk_name exactly */
+    *(ch1++) = '^';
+
+    /* We need to escape some characters first... NT compatibilty crap */
+    for (; *ch != 0; ch++, ch1++) {
+       switch (*ch) {     /* done this way in case there are more */
+       case '$':
+           *(ch1++) = '\\';
+           /* no break; we do want to fall through... */
+       default:
+           *ch1 = *ch;
+       }
+    }
+
+    /* we want to force amrestore to only match disk_name exactly */
+    *(ch1++) = '$';
+
+    *ch1 = '\0';
+
+    host_regex = alloc(strlen(dump_hostname) * 2 + 3);
+
+    ch = dump_hostname;
+    ch1 = host_regex;
+
+    /* we want to force amrestore to only match dump_hostname exactly */
+    *(ch1++) = '^';
+
+    /* We need to escape some characters first... NT compatibilty crap */
+    for (; *ch != 0; ch++, ch1++) {
+       switch (*ch) {     /* done this way in case there are more */
+       case '$':
+           *(ch1++) = '\\';
+           /* no break; we do want to fall through... */
+       default:
+           *ch1 = *ch;
+       }
+    }
+
+    /* we want to force amrestore to only match dump_hostname exactly */
+    *(ch1++) = '$';
+
+    *ch1 = '\0';
+
+    clean_datestamp = stralloc(dump_datestamp);
+    for(ch=ch1=clean_datestamp;*ch1 != '\0';ch1++) {
+       if(*ch1 != '-') {
+           *ch = *ch1;
+           ch++;
+       }
+    }
+    *ch = '\0';
+
+    /* push our feature list off to the tape server */
+    /* XXX assumes that index server and tape server are equivalent, ew */
+    if(am_has_feature(indexsrv_features, fe_amidxtaped_exchange_features)){
+       char buffer[32768] = "\0";
+
+       our_feature_string = am_feature_to_string(our_features);
+       tt = newstralloc2(tt, "FEATURES=", our_feature_string);
+       send_to_tape_server(tape_control_sock, tt);
+       if (read(tape_control_sock, buffer, sizeof(buffer)) <= 0) {
+           error("Could not read features from control socket\n");
+           /*NOTREACHED*/
+       }
+       tapesrv_features = am_string_to_feature(buffer);
+       amfree(our_feature_string);
+    }
+
+
+    if(am_has_feature(indexsrv_features, fe_amidxtaped_header) &&
+       am_has_feature(indexsrv_features, fe_amidxtaped_device) &&
+       am_has_feature(indexsrv_features, fe_amidxtaped_host) &&
+       am_has_feature(indexsrv_features, fe_amidxtaped_disk) &&
+       am_has_feature(indexsrv_features, fe_amidxtaped_datestamp)) {
+
+       if(am_has_feature(indexsrv_features, fe_amidxtaped_config)) {
+           tt = newstralloc2(tt, "CONFIG=", config);
+           send_to_tape_server(tape_control_sock, tt);
+       }
+       if(am_has_feature(indexsrv_features, fe_amidxtaped_label) &&
+          label && label[0] != '/') {
+           tt = newstralloc2(tt,"LABEL=",label);
+           send_to_tape_server(tape_control_sock, tt);
+       }
+       if(am_has_feature(indexsrv_features, fe_amidxtaped_fsf)) {
+           char v_fsf[100];
+           snprintf(v_fsf, 99, OFF_T_FMT, (OFF_T_FMT_TYPE)fsf);
+           tt = newstralloc2(tt, "FSF=",v_fsf);
+           send_to_tape_server(tape_control_sock, tt);
+       }
+       send_to_tape_server(tape_control_sock, "HEADER");
+       tt = newstralloc2(tt, "DEVICE=", dump_device_name);
+       send_to_tape_server(tape_control_sock, tt);
+       tt = newstralloc2(tt, "HOST=", host_regex);
+       send_to_tape_server(tape_control_sock, tt);
+       tt = newstralloc2(tt, "DISK=", disk_regex);
+       send_to_tape_server(tape_control_sock, tt);
+       tt = newstralloc2(tt, "DATESTAMP=", clean_datestamp);
+       send_to_tape_server(tape_control_sock, tt);
+       send_to_tape_server(tape_control_sock, "END");
+       amfree(tt);
+    }
+    else if(am_has_feature(indexsrv_features, fe_amidxtaped_nargs)) {
+       /* send to the tape server what tape file we want */
+       /* 6 args:
+        *   "-h"
+        *   "-p"
+        *   "tape device"
+        *   "hostname"
+        *   "diskname"
+        *   "datestamp"
+        */
+       send_to_tape_server(tape_control_sock, "6");
+       send_to_tape_server(tape_control_sock, "-h");
+       send_to_tape_server(tape_control_sock, "-p");
+       send_to_tape_server(tape_control_sock, dump_device_name);
+       send_to_tape_server(tape_control_sock, host_regex);
+       send_to_tape_server(tape_control_sock, disk_regex);
+       send_to_tape_server(tape_control_sock, clean_datestamp);
+
+       dbprintf(("Started amidxtaped with arguments \"6 -h -p %s %s %s %s\"\n",
+                 dump_device_name, host_regex, disk_regex, clean_datestamp));
+    }
+
+    /*
+     * split-restoring amidxtaped versions will expect to set up a data
+     * connection for dumpfile data, distinct from the socket we're already
+     * using for control data
+     */
+
+    if(am_has_feature(tapesrv_features, fe_recover_splits)){
+       char buffer[32768];
+       in_port_t data_port = (in_port_t)-1;
+        ssize_t nread;
+
+        nread = read(tape_control_sock, buffer, sizeof(buffer));
+
+       if (nread <= 0) {
+           error("Could not read from control socket: %s\n", 
+                  strerror(errno));
+           /*NOTREACHED*/
+        }
+
+       buffer[nread] = '\0';
+        if (sscanf(buffer, "CONNECT %hu\n",
+               (unsigned short *)&data_port) != 1) {
+           error("Recieved invalid port number message from control socket: %s\n",
+                  buffer);
+           /*NOTREACHED*/
+        }      
+
+       tape_data_sock = stream_client_privileged(server_name,
+                                                 data_port,
+                                                 0,
+                                                 STREAM_BUFSIZE,
+                                                 &my_data_port,
+                                                 0);
+       if(tape_data_sock == -1){
+           error("Unable to make data connection to server: %s\n",
+                     strerror(errno));
+           /*NOTREACHED*/
+       }
+
+       amfree(our_feature_string);
+    
+       line = get_security();
+
+       send_to_tape_server(tape_data_sock, line);
+       memset(line, '\0', strlen(line));
+       amfree(line);
+    }
+
+    amfree(disk_regex);
+    amfree(host_regex);
+    amfree(clean_datestamp);
+
+    return tape_control_sock;
+}
+
+
+/*
+ * Reads the first block of a tape file.
+ */
+
+void
+read_file_header(
+    char *     buffer,
+    dumpfile_t *file,
+    size_t     buflen,
+    int                tapedev)
+{
+    ssize_t bytes_read;
+
+    bytes_read = read_buffer(tapedev, buffer, buflen, READ_TIMEOUT);
+    if(bytes_read < 0) {
+       error("error reading header (%s), check amidxtaped.*.debug on server",
+             strerror(errno));
+       /*NOTREACHED*/
+    }
+
+    if((size_t)bytes_read < buflen) {
+       fprintf(stderr, "%s: short block %d byte%s\n",
+               get_pname(), (int)bytes_read, (bytes_read == 1) ? "" : "s");
+       print_header(stdout, file);
+       error("Can't read file header");
+       /*NOTREACHED*/
+    }
+
+    /* bytes_read == buflen */
+    parse_file_header(buffer, file, (size_t)bytes_read);
+}
+
+enum dumptypes {
+       IS_UNKNOWN,
+       IS_DUMP,
+       IS_GNUTAR,
+       IS_TAR,
+       IS_SAMBA,
+       IS_SAMBA_TAR
+};
+
+static void
+extract_files_child(
+    int                        in_fd,
+    EXTRACT_LIST *     elist)
+{
+    int save_errno;
+    int extra_params = 0;
+    int i,j=0;
+    char **restore_args = NULL;
+    int files_off_tape;
+    EXTRACT_LIST_ITEM *fn;
+    enum dumptypes dumptype = IS_UNKNOWN;
+    char buffer[DISK_BLOCK_BYTES];
+    dumpfile_t file;
+    size_t len_program;
+    char *cmd = NULL;
+    int passwd_field = -1;
+#ifdef SAMBA_CLIENT
+    char *domain = NULL, *smbpass = NULL;
+#endif
+
+    /* code executed by child to do extraction */
+    /* never returns */
+
+    /* make in_fd be our stdin */
+    if (dup2(in_fd, STDIN_FILENO) == -1)
+    {
+       error("dup2 failed in extract_files_child: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+
+    /* read the file header */
+    fh_init(&file);
+    read_file_header(buffer, &file, sizeof(buffer), STDIN_FILENO);
+
+    if(file.type != F_DUMPFILE) {
+       print_header(stdout, &file);
+       error("bad header");
+       /*NOTREACHED*/
+    }
+
+    if (file.program != NULL) {
+#ifdef GNUTAR
+       if (strcmp(file.program, GNUTAR) == 0)
+           dumptype = IS_GNUTAR;
+#endif
+
+       if (dumptype == IS_UNKNOWN) {
+           len_program = strlen(file.program);
+           if(len_program >= 3 &&
+              strcmp(&file.program[len_program-3],"tar") == 0)
+               dumptype = IS_TAR;
+       }
+
+#ifdef SAMBA_CLIENT
+       if (dumptype == IS_UNKNOWN && strcmp(file.program, SAMBA_CLIENT) ==0) {
+           if (samba_extract_method == SAMBA_TAR)
+             dumptype = IS_SAMBA_TAR;
+           else
+             dumptype = IS_SAMBA;
+       }
+#endif
+    }
+
+    /* form the arguments to restore */
+    files_off_tape = length_of_tape_list(elist);
+    switch (dumptype) {
+    case IS_SAMBA:
+#ifdef SAMBA_CLIENT
+       extra_params = 10;
+       break;
+#endif
+    case IS_TAR:
+    case IS_GNUTAR:
+        extra_params = 4;
+        break;
+    case IS_SAMBA_TAR:
+        extra_params = 3;
+        break;
+    case IS_UNKNOWN:
+    case IS_DUMP:
+#ifdef AIX_BACKUP
+        extra_params = 2;
+#else
+#if defined(XFSDUMP)
+       if (strcmp(file.program, XFSDUMP) == 0) {
+            extra_params = 4 + files_off_tape;
+       } else
+#endif
+       {
+        extra_params = 4;
+       }
+#endif
+       break;
+    }
+
+    restore_args = (char **)alloc((size_t)((extra_params + files_off_tape + 1)
+                                 * sizeof(char *)));
+    switch(dumptype) {
+    case IS_SAMBA:
+#ifdef SAMBA_CLIENT
+       restore_args[j++] = stralloc("smbclient");
+       smbpass = findpass(file.disk, &domain);
+       if (smbpass) {
+            restore_args[j++] = stralloc(file.disk);
+           passwd_field=j;
+           restore_args[j++] = stralloc("-U");
+           restore_args[j++] = smbpass;
+           if (domain) {
+               restore_args[j++] = stralloc("-W");
+               restore_args[j++] = stralloc(domain);
+           } else
+               extra_params -= 2;
+       } else
+           extra_params -= 6;
+       restore_args[j++] = stralloc("-d0");
+       restore_args[j++] = stralloc("-Tx");
+       restore_args[j++] = stralloc("-");      /* data on stdin */
+       break;
+#endif
+    case IS_TAR:
+    case IS_GNUTAR:
+       restore_args[j++] = stralloc("tar");
+       restore_args[j++] = stralloc("--numeric-owner");
+       restore_args[j++] = stralloc("-xpGvf");
+       restore_args[j++] = stralloc("-");      /* data on stdin */
+       break;
+    case IS_SAMBA_TAR:
+       restore_args[j++] = stralloc("tar");
+       restore_args[j++] = stralloc("-xpvf");
+       restore_args[j++] = stralloc("-");      /* data on stdin */
+       break;
+    case IS_UNKNOWN:
+    case IS_DUMP:
+        restore_args[j++] = stralloc("restore");
+#ifdef AIX_BACKUP
+        restore_args[j++] = stralloc("-xB");
+#else
+#if defined(XFSDUMP)
+       if (strcmp(file.program, XFSDUMP) == 0) {
+            restore_args[j++] = stralloc("-v");
+            restore_args[j++] = stralloc("silent");
+       } else
+#endif
+#if defined(VDUMP)
+       if (strcmp(file.program, VDUMP) == 0) {
+            restore_args[j++] = stralloc("xf");
+            restore_args[j++] = stralloc("-"); /* data on stdin */
+       } else
+#endif
+       {
+        restore_args[j++] = stralloc("xbf");
+        restore_args[j++] = stralloc("2");     /* read in units of 1K */
+        restore_args[j++] = stralloc("-");     /* data on stdin */
+       }
+#endif
+    }
+  
+    for (i = 0, fn = elist->files; i < files_off_tape; i++, fn = fn->next)
+    {
+       switch (dumptype) {
+       case IS_TAR:
+       case IS_GNUTAR:
+       case IS_SAMBA_TAR:
+       case IS_SAMBA:
+           if (strcmp(fn->path, "/") == 0)
+               restore_args[j++] = stralloc(".");
+           else
+               restore_args[j++] = stralloc2(".", fn->path);
+           break;
+       case IS_UNKNOWN:
+       case IS_DUMP:
+#if defined(XFSDUMP)
+           if (strcmp(file.program, XFSDUMP) == 0) {
+               /*
+                * xfsrestore needs a -s option before each file to be
+                * restored, and also wants them to be relative paths.
+                */
+               restore_args[j++] = stralloc("-s");
+               restore_args[j++] = stralloc(fn->path + 1);
+           } else
+#endif
+           {
+           restore_args[j++] = stralloc(fn->path);
+           }
+       }
+    }
+#if defined(XFSDUMP)
+    if (strcmp(file.program, XFSDUMP) == 0) {
+       restore_args[j++] = stralloc("-");
+       restore_args[j++] = stralloc(".");
+    }
+#endif
+    restore_args[j] = NULL;
+
+    switch (dumptype) {
+    case IS_SAMBA:
+#ifdef SAMBA_CLIENT
+       cmd = stralloc(SAMBA_CLIENT);
+       break;
+#else
+       /* fall through to ... */
+#endif
+    case IS_TAR:
+    case IS_GNUTAR:
+    case IS_SAMBA_TAR:
+#ifndef GNUTAR
+       fprintf(stderr, "warning: GNUTAR program not available.\n");
+       cmd = stralloc("tar");
+#else
+       cmd = stralloc(GNUTAR);
+#endif
+       break;
+    case IS_UNKNOWN:
+    case IS_DUMP:
+       cmd = NULL;
+#if defined(DUMP)
+       if (strcmp(file.program, DUMP) == 0) {
+           cmd = stralloc(RESTORE);
+       }
+#endif
+#if defined(VDUMP)
+       if (strcmp(file.program, VDUMP) == 0) {
+           cmd = stralloc(VRESTORE);
+       }
+#endif
+#if defined(VXDUMP)
+       if (strcmp(file.program, VXDUMP) == 0) {
+           cmd = stralloc(VXRESTORE);
+       }
+#endif
+#if defined(XFSDUMP)
+       if (strcmp(file.program, XFSDUMP) == 0) {
+           cmd = stralloc(XFSRESTORE);
+       }
+#endif
+       if (cmd == NULL) {
+           fprintf(stderr, "warning: restore program for %s not available.\n",
+                   file.program);
+           cmd = stralloc("restore");
+       }
+    }
+    if (cmd) {
+        dbprintf(("Exec'ing %s with arguments:\n", cmd));
+       for (i = 0; i < j; i++) {
+           if( i == passwd_field)
+               dbprintf(("\tXXXXX\n"));
+           else
+               dbprintf(("\t%s\n", restore_args[i]));
+       }
+        (void)execv(cmd, restore_args);
+       /* only get here if exec failed */
+       save_errno = errno;
+       for (i = 0; i < j; i++) {
+           amfree(restore_args[i]);
+       }
+       amfree(restore_args);
+       errno = save_errno;
+        perror("amrecover couldn't exec");
+        fprintf(stderr, " problem executing %s\n", cmd);
+       amfree(cmd);
+    }
+    exit(1);
+    /*NOT REACHED */
+}
+
+/*
+ * Interpose something between the process writing out the dump (writing it to
+ * some extraction program, really) and the socket from which we're reading, so
+ * that we can do things like prompt for human interaction for multiple tapes.
+ */
+void
+writer_intermediary(
+    int                        ctl_fd,
+    int                        data_fd,
+    EXTRACT_LIST *     elist)
+{
+    int child_pipe[2];
+    pid_t pid;
+    char buffer[DISK_BLOCK_BYTES];
+    ssize_t bytes_read;
+    amwait_t extractor_status;
+    int max_fd, nfound;
+    SELECT_ARG_TYPE readset, selectset;
+    struct timeval timeout;
+
+    /*
+     * If there's no distinct data channel (such as if we're talking to an
+     * older server), don't bother doing anything complicated.  Just run the
+     * extraction.
+     */
+    if(data_fd == -1){
+       extract_files_child(ctl_fd, elist);
+       /*NOTREACHED*/
+    }
+
+    if(pipe(child_pipe) == -1) {
+       error("extract_list - error setting up pipe to extractor: %s\n",
+           strerror(errno));
+       /*NOTREACHED*/
+    }
+
+    /* okay, ready to extract. fork a child to do the actual work */
+    if ((pid = fork()) == 0) {
+       /* this is the child process */
+       /* never gets out of this clause */
+       aclose(child_pipe[1]);
+        extract_files_child(child_pipe[0], elist);
+       /*NOTREACHED*/
+    }
+
+    /* This is the parent */
+    if (pid == -1) {
+       error("writer_intermediary - error forking child");
+       /*NOTREACHED*/
+    }
+
+    aclose(child_pipe[0]);
+
+    if(data_fd > ctl_fd) max_fd = data_fd+1;
+                    else max_fd = ctl_fd+1;
+    FD_ZERO(&readset);
+    FD_SET(data_fd, &readset);
+    FD_SET(ctl_fd, &readset);
+
+    do {
+       timeout.tv_sec = READ_TIMEOUT;
+       timeout.tv_usec = 0;
+       FD_COPY(&readset, &selectset);
+        
+       nfound = select(max_fd, &selectset, NULL, NULL,
+                       &timeout);
+       if(nfound < 0) {
+           fprintf(stderr,"select error: %s\n", strerror(errno));
+           break;
+       }
+        
+       if (nfound == 0) { /* timeout */
+           fprintf(stderr, "timeout waiting %d seconds for restore\n",
+                   READ_TIMEOUT);
+           fprintf(stderr, "increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n");
+           break;
+       }
+        
+       if(FD_ISSET(ctl_fd, &selectset)) {
+           bytes_read = read(ctl_fd, buffer, sizeof(buffer)-1);
+           switch(bytes_read) {
+            case -1:
+                if ((errno != EINTR) && (errno != EAGAIN)) {
+                    if (errno != EPIPE) {
+                        fprintf(stderr,"writer ctl fd read error: %s",
+                                strerror(errno));
+                    }
+                    FD_CLR(ctl_fd, &readset);
+                }
+                break;
+                
+            case  0:
+                FD_CLR(ctl_fd, &readset);
+                break;
+                
+            default: {
+                char desired_tape[MAX_TAPE_LABEL_BUF];
+                
+                buffer[bytes_read] = '\0';
+                /* if prompted for a tape, relay said prompt to the user */
+                if(sscanf(buffer, "FEEDME %132s\n", desired_tape) == 1) {
+                    int done = 0;
+                    while (!done) {
+                        char *input = NULL;
+                        printf("Please insert tape %s. Continue? [Y|n]: ",
+                               desired_tape);
+                        fflush(stdout);
+                        
+                        input = agets(stdin); /* strips \n */
+                        if (strcasecmp("", input) == 0|| 
+                            strcasecmp("y", input) == 0|| 
+                            strcasecmp("yes", input) == 0) {
+                            send_to_tape_server(tape_control_sock, "OK");
+                            done = 1;
+                        } else if (strcasecmp("n", input) == 0|| 
+                                   strcasecmp("no", input) == 0) {
+                            send_to_tape_server(tape_control_sock, "ERROR");
+                            /* Abort!
+                               We are the middle process, so just die. */
+                            exit(EXIT_FAILURE);
+                        }
+                        amfree(input);
+                    }
+                } else {
+                    fprintf(stderr, "Strange message from tape server: %s", buffer);
+                   break;
+                }    
+             }
+            }
+        }
+
+        /* now read some dump data */
+        if(FD_ISSET(data_fd, &selectset)) {
+            bytes_read = read(data_fd, buffer, sizeof(buffer)-1);
+            switch(bytes_read) {
+            case -1:
+                if ((errno != EINTR) && (errno != EAGAIN)) {
+                    if (errno != EPIPE) {
+                        fprintf(stderr,"writer data fd read error: %s",
+                                strerror(errno));
+                    }
+                    FD_CLR(data_fd, &readset);
+                }
+                break;
+                
+            case  0:
+                FD_CLR(data_fd, &readset);
+                break;
+                
+            default:
+                /*
+                 * spit what we got from the server to the child
+                 *  process handling actual dumpfile extraction
+                 */
+                if(fullwrite(child_pipe[1], buffer, (size_t)bytes_read) < 0) {
+                    if(errno == EPIPE) {
+                        error("%s: pipe data reader has quit: %s\n",
+                              get_pname(), strerror(errno));
+                        /* NOTREACHED */
+                    }
+                    error("Write error to extract child: %s\n",
+                          strerror(errno));
+                    /* NOTREACHED */
+                }
+                break;
+           }
+       }
+    } while(FD_ISSET(ctl_fd, &readset) || FD_ISSET(data_fd, &readset));
+
+    aclose(child_pipe[1]);
+
+    waitpid(pid, &extractor_status, 0);
+    if(WEXITSTATUS(extractor_status) != 0){
+       int ret = WEXITSTATUS(extractor_status);
+        if(ret == 255) ret = -1;
+       error("Extractor child exited with status %d\n", ret);
+       /*NOTREACHED*/
+    }
+
+    exit(0);
+}
+
+/* exec restore to do the actual restoration */
+
+/* does the actual extraction of files */
+/*
+ * The original design had the dump image being returned exactly as it
+ * appears on the tape, and this routine getting from the index server
+ * whether or not it is compressed, on the assumption that the tape
+ * server may not know how to uncompress it. But
+ * - Amrestore can't do that. It returns either compressed or uncompressed
+ * (always). Amrestore assumes it can uncompress files. It is thus a good
+ * idea to run the tape server on a machine with gzip.
+ * - The information about compression in the disklist is really only
+ * for future dumps. It is possible to change compression on a drive
+ * so the information in the disklist may not necessarily relate to
+ * the dump image on the tape.
+ *   Consequently the design was changed to assuming that amrestore can
+ * uncompress any dump image and have it return an uncompressed file
+ * always.
+ */
+void
+extract_files(void)
+{
+    EXTRACT_LIST *elist;
+    pid_t pid;
+    amwait_t child_stat;
+    char buf[STR_SIZE];
+    char *l;
+    int first;
+    int otc;
+    tapelist_t *tlist = NULL;
+
+    if (!is_extract_list_nonempty())
+    {
+       printf("Extract list empty - No files to extract!\n");
+       return;
+    }
+
+    clean_extract_list();
+
+    /* get tape device name from index server if none specified */
+    if (tape_server_name == NULL) {
+       tape_server_name = newstralloc(tape_server_name, server_name);
+    }
+    if (tape_device_name == NULL) {
+       if (send_command("TAPE") == -1)
+           exit(1);
+       if (get_reply_line() == -1)
+           exit(1);
+       l = reply_line();
+       if (!server_happy())
+       {
+           printf("%s\n", l);
+           exit(1);
+       }
+       /* skip reply number */
+       tape_device_name = newstralloc(tape_device_name, l+4);
+    }
+
+    if (strcmp(tape_device_name, "/dev/null") == 0)
+    {
+       printf("amrecover: warning: using %s as the tape device will not work\n",
+              tape_device_name);
+    }
+
+    first=1;
+    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))
+       if(elist->tape[0]!='/') {
+           if(first) {
+               printf("\nExtracting files using tape drive %s on host %s.\n",
+                       tape_device_name, tape_server_name);
+               printf("The following tapes are needed:");
+               first=0;
+           }
+           else
+               printf("                               ");
+           tlist = unmarshal_tapelist_str(elist->tape); 
+           for( ; tlist != NULL; tlist = tlist->next)
+               printf(" %s", tlist->label);
+           printf("\n");
+           amfree(tlist);
+       }
+    first=1;
+    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))
+    {
+       if(elist->tape[0]=='/') {
+           if(first) {
+               printf("\nExtracting files from holding disk on host %s.\n",
+                       tape_server_name);
+               printf("The following files are needed:");
+               first=0;
+           }
+           else
+               printf("                               ");
+           tlist = unmarshal_tapelist_str(elist->tape); 
+           for( ; tlist != NULL; tlist = tlist->next)
+               printf(" %s", tlist->label);
+           printf("\n");
+           amfree(tlist);
+       }
+    }
+    printf("\n");
+
+    if (getcwd(buf, sizeof(buf)) == NULL) {
+       perror("extract_list: Current working directory unavailable");
+       exit(1);
+    }
+
+    printf("Restoring files into directory %s\n", buf);
+#ifdef SAMBA_CLIENT
+    if (samba_extract_method == SAMBA_SMBCLIENT)
+      printf("(unless it is a Samba backup, that will go through to the SMB server)\n");
+#endif
+    if (!okay_to_continue(0,0,0))
+       return;
+    printf("\n");
+
+    while ((elist = first_tape_list()) != NULL)
+    {
+       if(elist->tape[0]=='/') {
+           dump_device_name = newstralloc(dump_device_name, elist->tape);
+           printf("Extracting from file ");
+           tlist = unmarshal_tapelist_str(dump_device_name); 
+           for( ; tlist != NULL; tlist = tlist->next)
+               printf(" %s", tlist->label);
+           printf("\n");
+           amfree(tlist);
+       }
+       else {
+           printf("Extracting files using tape drive %s on host %s.\n",
+                  tape_device_name, tape_server_name);
+           tlist = unmarshal_tapelist_str(elist->tape); 
+           printf("Load tape %s now\n", tlist->label);
+           amfree(tlist);
+           otc = okay_to_continue(1,1,0);
+           if (otc == 0)
+               return;
+           else if (otc == SKIP_TAPE) {
+               delete_tape_list(elist); /* skip this tape */
+               continue;
+           }
+           dump_device_name = newstralloc(dump_device_name, tape_device_name);
+       }
+       dump_datestamp = newstralloc(dump_datestamp, elist->date);
+
+       /* connect to the tape handler daemon on the tape drive server */
+       if ((tape_control_sock = extract_files_setup(elist->tape, elist->fileno)) == -1)
+       {
+           fprintf(stderr, "amrecover - can't talk to tape server\n");
+           return;
+       }
+
+       /* okay, ready to extract. fork a child to do the actual work */
+       if ((pid = fork()) == 0)
+       {
+           /* this is the child process */
+           /* never gets out of this clause */
+           writer_intermediary(tape_control_sock, tape_data_sock, elist);
+           /*NOT REACHED*/
+       }
+       /* this is the parent */
+       if (pid == -1)
+       {
+           perror("extract_list - error forking child");
+           aclose(tape_control_sock);
+           exit(1);
+       }
+
+       /* store the child pid globally so that it can be killed on intr */
+       extract_restore_child_pid = pid;
+
+       /* wait for the child process to finish */
+       if ((pid = waitpid(-1, &child_stat, 0)) == (pid_t)-1)
+       {
+           perror("extract_list - error waiting for child");
+           exit(1);
+       }
+
+       if(tape_data_sock != -1) {
+           aclose(tape_data_sock);
+       }
+
+       if (pid == extract_restore_child_pid)
+       {
+           extract_restore_child_pid = -1;
+       }
+       else
+       {
+           fprintf(stderr, "extract list - unknown child terminated?\n");
+           exit(1);
+       }
+       if ((WIFEXITED(child_stat) != 0) && (WEXITSTATUS(child_stat) != 0))
+       {
+           fprintf(stderr,
+                   "extract_list - child returned non-zero status: %d\n",
+                   WEXITSTATUS(child_stat));
+           otc = okay_to_continue(0,0,1);
+           if(otc == 0)
+               return;
+
+           if(otc == 1) {
+               delete_tape_list(elist); /* tape failed so delete from list */
+           }
+       }
+       else {
+           delete_tape_list(elist);    /* tape done so delete from list */
+       }
+    }
+}
diff --git a/oldrecover-src/help.c b/oldrecover-src/help.c
new file mode 100644 (file)
index 0000000..7bccd5e
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: help.c,v 1.2 2006/05/25 01:47:13 johnfranks Exp $
+ *
+ * implements the "help" command in amrecover
+ */
+
+#include "amanda.h"
+#include "amrecover.h"
+
+/* print a list of valid commands */
+void
+help_list(void)
+{
+    printf("valid commands are:\n\n");
+
+    printf("add path1 ...     - add to extraction list (shell wildcards)\n");
+    printf("addx path1 ...    - add to extraction list (regular expressions)\n");
+    printf("cd directory      - change cwd on virtual file system (shell wildcards)\n");
+    printf("cdx directory     - change cwd on virtual file system (regular expressions)\n");
+    printf("clear             - clear extraction list\n");
+    printf("delete path1 ...  - delete from extraction list (shell wildcards)\n");
+    printf("deletex path1 ... - delete from extraction list (regular expressions)\n");
+    printf("extract           - extract selected files from tapes\n");
+    printf("exit\n");
+    printf("help\n");
+    printf("history           - show dump history of disk\n");
+    printf("list [filename]   - show extraction list, optionally writing to file\n");
+    printf("lcd directory     - change cwd on local file system\n");
+    printf("ls                - list directory on virtual file system\n");
+    printf("lpwd              - show cwd on local file system\n");
+    printf("mode              - show the method used to extract SMB shares\n");
+    printf("pwd               - show cwd on virtual file system\n");
+    printf("quit\n");
+    printf("listhost          - list hosts\n");
+    printf("listdisk [diskdevice]              - list disks\n");
+    printf("setdate {YYYY-MM-DD|--MM-DD|---DD} - set date of look\n");
+    printf("        {YYYY-MM-DD-HH-MM-SS}      - set date of look\n");
+    printf("setdisk diskname [mountpoint]      - select disk on dump host\n");
+    printf("sethost host                       - select dump host\n");
+    printf("settape [host:][device|default]    - select tape server and/or device\n");
+    printf("setmode smb|tar                 - select the method used to extract SMB shares\n");
+    printf("\n");
+}
diff --git a/oldrecover-src/set_commands.c b/oldrecover-src/set_commands.c
new file mode 100644 (file)
index 0000000..48e655d
--- /dev/null
@@ -0,0 +1,608 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: set_commands.c,v 1.3 2006/07/05 13:14:58 martinea Exp $
+ *
+ * implements the "set" commands in amrecover
+ */
+
+#include "amanda.h"
+#include "amrecover.h"
+
+#ifdef SAMBA_CLIENT
+extern unsigned short samba_extract_method;
+#endif /* SAMBA_CLIENT */
+
+/* sets a date, mapping given date into standard form if needed */
+int
+set_date(
+    char *     date)
+{
+    char *cmd = NULL;
+
+    clear_dir_list();
+
+    cmd = stralloc2("DATE ", date);
+    if (converse(cmd) == -1)
+       exit(1);
+
+    /* if a host/disk/directory is set, then check if that directory
+       is still valid at the new date, and if not set directory to
+       mount_point */
+    if (disk_path != NULL) {
+       cmd = newstralloc2(cmd, "OISD ", disk_path);
+       if (exchange(cmd) == -1)
+           exit(1);
+       if (server_happy())
+       {
+           suck_dir_list_from_server();
+       }
+       else
+       {
+           printf("No index records for cwd on new date\n");
+           printf("Setting cwd to mount point\n");
+           disk_path = newstralloc(disk_path, "/");    /* fake it */
+           clear_dir_list();
+       }
+    }
+    amfree(cmd);
+    return 0;
+}
+
+
+void
+set_host(
+    const char *       host)
+{
+    char *cmd = NULL;
+    struct hostent *hp;
+    char **hostp;
+    int found_host = 0;
+
+    if (is_extract_list_nonempty())
+    {
+       printf("Must clear extract list before changing host\n");
+       return;
+    }
+
+    cmd = stralloc2("HOST ", host);
+    if (converse(cmd) == -1)
+       exit(1);
+    if (server_happy())
+    {
+       found_host = 1;
+    }
+    else
+    {
+       /*
+        * Try converting the given host to a fully qualified name
+        * and then try each of the aliases.
+        */
+       if ((hp = gethostbyname(host)) != NULL) {
+           host = hp->h_name;
+           printf("Trying host %s ...\n", host);
+           cmd = newstralloc2(cmd, "HOST ", host);
+           if (converse(cmd) == -1)
+               exit(1);
+           if(server_happy())
+           {
+               found_host = 1;
+           }
+           else
+           {
+               for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
+               {
+                   printf("Trying host %s ...\n", host);
+                   cmd = newstralloc2(cmd, "HOST ", host);
+                   if (converse(cmd) == -1)
+                       exit(1);
+                   if(server_happy())
+                   {
+                       found_host = 1;
+                       break;
+                   }
+               }
+           }
+       }
+    }
+    if(found_host)
+    {
+       dump_hostname = newstralloc(dump_hostname, host);
+       amfree(disk_name);
+       amfree(mount_point);
+       amfree(disk_path);
+       clear_dir_list();
+    }
+    amfree(cmd);
+}
+
+
+void
+list_host(void)
+{
+    char *cmd = NULL;
+
+    cmd = stralloc("LISTHOST");
+    if (converse(cmd) == -1)
+        exit(1);
+    amfree(cmd);
+}
+
+void
+set_disk(
+    char *     dsk,
+    char *     mtpt)
+{
+    char *cmd = NULL;
+
+    if (is_extract_list_nonempty())
+    {
+       printf("Must clear extract list before changing disk\n");
+       return;
+    }
+
+    /* if mount point specified, check it is valid */
+    if ((mtpt != NULL) && (*mtpt != '/'))
+    {
+       printf("Mount point \"%s\" invalid - must start with /\n", mtpt);
+       return;
+    }
+
+    clear_dir_list();
+    cmd = stralloc2("DISK ", dsk);
+    if (converse(cmd) == -1)
+       exit(1);
+    amfree(cmd);
+
+    if (!server_happy())
+       return;
+
+    disk_name = newstralloc(disk_name, dsk);
+    if (mtpt == NULL)
+    {
+       /* mount point not specified */
+       if (*dsk == '/')
+       {
+           /* disk specified by mount point, hence use it */
+           mount_point = newstralloc(mount_point, dsk);
+       }
+       else
+       {
+           /* device name given, use '/' because nothing better */
+           mount_point = newstralloc(mount_point, "/");
+       }
+    }
+    else
+    {
+       /* mount point specified */
+       mount_point = newstralloc(mount_point, mtpt);
+    }
+
+    /* set the working directory to the mount point */
+    /* there is the possibility that there are no index records for the
+       disk for the given date, hence setting the directory to the
+       mount point will fail. Preempt this by checking first so we can write
+       a more informative message. */
+    if (exchange("OISD /") == -1)
+       exit(1);
+    if (server_happy())
+    {
+       disk_path = newstralloc(disk_path, "/");
+       suck_dir_list_from_server();    /* get list of directory contents */
+    }
+    else
+    {
+       printf("No index records for disk for specified date\n");
+       printf("If date correct, notify system administrator\n");
+       disk_path = newstralloc(disk_path, "/");        /* fake it */
+       clear_dir_list();
+    }
+}
+
+void
+list_disk(
+    char *     amdevice)
+{
+    char *cmd = NULL;
+
+    if(amdevice) {
+       cmd = stralloc2("LISTDISK ", amdevice);
+       if (converse(cmd) == -1)
+           exit(1);
+       amfree(cmd);
+    }
+    else {
+       cmd = stralloc("LISTDISK");
+       if (converse(cmd) == -1)
+           exit(1);
+       amfree(cmd);
+    }
+}
+
+void
+cd_glob(
+    char *     glob)
+{
+    char *regex;
+    char *regex_path;
+    char *s;
+
+    char *path_on_disk = NULL;
+
+    if (disk_name == NULL) {
+       printf("Must select disk before changing directory\n");
+       return;
+    }
+
+    regex = glob_to_regex(glob);
+    dbprintf(("cd_glob (%s) -> %s\n", glob, regex));
+    if ((s = validate_regexp(regex)) != NULL) {
+        printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+        puts(s);
+       amfree(regex);
+        return;
+    }
+    /*
+     * glob_to_regex() anchors the beginning of the pattern with ^,
+     * but we will be tacking it onto the end of the current directory
+     * in add_file, so strip that off.  Also, it anchors the end with
+     * $, but we need to match a trailing /, add it if it is not there
+     */
+    regex_path = stralloc(regex + 1);
+    amfree(regex);
+    if(regex_path[strlen(regex_path) - 2] != '/' ) {
+       regex_path[strlen(regex_path) - 1] = '\0';
+       strappend(regex_path, "/$");
+    }
+
+    /* convert path (assumed in cwd) to one on disk */
+    if (strcmp(disk_path, "/") == 0)
+        path_on_disk = stralloc2("/", regex_path);
+    else {
+        char *clean_disk_path = clean_regex(disk_path);
+        path_on_disk = vstralloc(clean_disk_path, "/", regex_path, NULL);
+        amfree(clean_disk_path);
+    }
+
+    cd_dir(path_on_disk, glob);
+
+    amfree(regex_path);
+    amfree(path_on_disk);
+}
+
+void
+cd_regex(
+    char *     regex)
+{
+    char *s;
+
+    char *path_on_disk = NULL;
+
+    if (disk_name == NULL) {
+       printf("Must select disk before changing directory\n");
+       return;
+    }
+
+    if ((s = validate_regexp(regex)) != NULL) {
+       printf("\"%s\" is not a valid regular expression: ", regex);
+       puts(s);
+       return;
+    }
+
+    /* convert path (assumed in cwd) to one on disk */
+    if (strcmp(disk_path, "/") == 0)
+        path_on_disk = stralloc2("/", regex);
+    else {
+        char *clean_disk_path = clean_regex(disk_path);
+        path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
+        amfree(clean_disk_path);
+    }
+
+    cd_dir(path_on_disk, regex);
+
+    amfree(path_on_disk);
+}
+
+void
+cd_dir(
+    char *     path_on_disk,
+    char *     default_dir)
+{
+    char *path_on_disk_slash = NULL;
+    char *dir = NULL;
+
+    int nb_found;
+    size_t i;
+
+    DIR_ITEM *ditem;
+
+    path_on_disk_slash = stralloc2(path_on_disk, "/");
+
+    nb_found = 0;
+
+    for (ditem=get_dir_list(); ditem!=NULL && nb_found <= 1; 
+                              ditem=get_next_dir_item(ditem))
+    {
+       if (match(path_on_disk, ditem->path)
+           || match(path_on_disk_slash, ditem->path))
+       {
+           i = strlen(ditem->path);
+           if((i > 0 && ditem->path[i-1] == '/')
+               || (i > 1 && ditem->path[i-2] == '/' && ditem->path[i-1] == '.'))
+            {   /* It is a directory */
+               char *dir1, *dir2;
+               nb_found++;
+               dir = newstralloc(dir,ditem->path);
+               if(dir[strlen(dir)-1] == '/')
+                   dir[strlen(dir)-1] = '\0'; /* remove last / */
+               /* remove everything before the last / */
+               dir1 = rindex(dir,'/');
+               if (dir1) {
+                   dir1++;
+                   dir2 = stralloc(dir1);
+                   amfree(dir);
+                   dir = dir2;
+               }
+           }
+       }
+    }
+    amfree(path_on_disk_slash);
+
+    if(nb_found==0) {
+       set_directory(default_dir);
+    }
+    else if(nb_found==1) {
+       set_directory(dir);
+    }
+    else {
+       printf("Too many directory\n");
+    }
+    amfree(dir);
+}
+
+void
+set_directory(
+    char *     dir)
+{
+    char *cmd = NULL;
+    char *new_dir = NULL;
+    char *dp, *de;
+    char *ldir = NULL;
+
+    /* do nothing if "." */
+    if(strcmp(dir,".")==0) {
+       show_directory();               /* say where we are */
+       return;
+       /*NOTREACHED*/
+    }
+
+    if (disk_name == NULL) {
+       printf("Must select disk before setting directory\n");
+       return;
+       /*NOTREACHED*/
+    }
+
+    ldir = stralloc(dir);
+    clean_pathname(ldir);
+
+    /* convert directory into absolute path relative to disk mount point */
+    if (ldir[0] == '/')
+    {
+       /* absolute path specified, must start with mount point */
+       if (strcmp(mount_point, "/") == 0)
+       {
+           new_dir = stralloc(ldir);
+       }
+       else
+       {
+           if (strncmp(mount_point, ldir, strlen(mount_point)) != 0)
+           {
+               printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
+                      mount_point);
+               amfree(ldir);
+               return;
+               /*NOTREACHED*/
+           }
+           new_dir = stralloc(ldir+strlen(mount_point));
+           if (strlen(new_dir) == 0) {
+               new_dir = newstralloc(new_dir, "/");
+                                       /* i.e. ldir == mount_point */
+           }
+       }
+    }
+    else
+    {
+       new_dir = stralloc(disk_path);
+       dp = ldir;
+       /* strip any leading ..s */
+       while (strncmp(dp, "../", 3) == 0)
+       {
+           de = strrchr(new_dir, '/'); /* always at least 1 */
+           if (de == new_dir)
+           {
+               /* at top of disk */
+               *(de + 1) = '\0';
+               dp = dp + 3;
+           }
+           else
+           {
+               *de = '\0';
+               dp = dp + 3;
+           }
+       }
+       if (strcmp(dp, "..") == 0) {
+           if (strcmp(new_dir, "/") == 0) {
+               /* at top of disk */
+               printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
+                      mount_point);
+               /*@ignore@*/
+               amfree(new_dir);
+               /*@end@*/
+               amfree(ldir);
+               return;
+               /*NOTREACHED*/
+           }
+           de = strrchr(new_dir, '/'); /* always at least 1 */
+           if (de == new_dir)
+           {
+               /* at top of disk */
+               *(de+1) = '\0';
+           }
+           else
+           {
+               *de = '\0';
+           }
+       } else {
+           /*@ignore@*/
+           if (strcmp(new_dir, "/") != 0) {
+               strappend(new_dir, "/");
+           }
+           strappend(new_dir, ldir);
+           /*@end@*/
+       }
+    }
+
+    cmd = stralloc2("OISD ", new_dir);
+    if (exchange(cmd) == -1) {
+       exit(1);
+       /*NOTREACHED*/
+    }
+    amfree(cmd);
+
+    if (server_happy())
+    {
+       disk_path = newstralloc(disk_path, new_dir);
+       suck_dir_list_from_server();    /* get list of directory contents */
+       show_directory();               /* say where we moved to */
+    }
+    else
+    {
+       printf("Invalid directory - %s\n", dir);
+    }
+
+    /*@ignore@*/
+    amfree(new_dir);
+    amfree(ldir);
+    /*@end@*/
+}
+
+
+/* prints the current working directory */
+void
+show_directory(void)
+{
+    if (mount_point == NULL || disk_path == NULL)
+        printf("Must select disk first\n");
+    else if (strcmp(mount_point, "/") == 0)
+       printf("%s\n", disk_path);
+    else if (strcmp(disk_path, "/") == 0)
+       printf("%s\n", mount_point);
+    else
+       printf("%s%s\n", mount_point, disk_path);
+}
+
+
+/* set the tape server and device */
+void
+set_tape(
+    char *     tape)
+{
+    char *tapedev = strchr(tape, ':');
+
+    if (tapedev)
+    {
+       if (tapedev != tape) {
+           if((strchr(tapedev+1, ':') == NULL) &&
+              (strncmp(tape, "null:", 5) == 0 ||
+               strncmp(tape, "rait:", 5) == 0 ||
+               strncmp(tape, "file:", 5) == 0 ||
+               strncmp(tape, "tape:", 5) == 0)) {
+               tapedev = tape;
+           }
+           else {
+               *tapedev = '\0';
+               tape_server_name = newstralloc(tape_server_name, tape);
+               ++tapedev;
+           }
+       } else { /* reset server_name if start with : */
+           amfree(tape_server_name);
+           ++tapedev;
+       }
+    } else
+       tapedev = tape;
+    
+    if (tapedev[0])
+    {
+       if (strcmp(tapedev, "default") == 0)
+           amfree(tape_device_name);
+       else
+           tape_device_name = newstralloc(tape_device_name, tapedev);
+    }
+
+    if (tape_device_name)
+       printf ("Using tape \"%s\"", tape_device_name);
+    else
+       printf ("Using default tape");
+
+    if (tape_server_name)
+       printf (" from server %s.\n", tape_server_name);
+    else
+       printf (".\nTape server unspecified, assumed to be %s.\n",
+               server_name);
+}
+
+void
+set_mode(
+    int                mode)
+{
+#ifdef SAMBA_CLIENT
+  if (mode == SAMBA_SMBCLIENT) {
+    printf ("SAMBA dumps will be extracted using smbclient\n");
+    samba_extract_method = SAMBA_SMBCLIENT;
+  } else {
+    if (mode == SAMBA_TAR) {
+      printf ("SAMBA dumps will be extracted as TAR dumps\n");
+      samba_extract_method = SAMBA_TAR;
+    }
+  }
+#else
+  (void)mode;  /* Quiet unused parameter warning */
+#endif /* SAMBA_CLIENT */
+}
+
+void
+show_mode(void) 
+{
+#ifdef SAMBA_CLIENT
+  printf ("SAMBA dumps are extracted ");
+
+  if (samba_extract_method == SAMBA_TAR) {
+    printf (" as TAR dumps\n");
+  } else {
+    printf ("using smbclient\n");
+  }
+#endif /* SAMBA_CLIENT */
+}
diff --git a/oldrecover-src/uparse.c b/oldrecover-src/uparse.c
new file mode 100644 (file)
index 0000000..9e0739f
--- /dev/null
@@ -0,0 +1,1678 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.1"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     LISTHOST = 258,
+     LISTDISK = 259,
+     SETHOST = 260,
+     SETDISK = 261,
+     SETDATE = 262,
+     SETTAPE = 263,
+     SETMODE = 264,
+     CD = 265,
+     CDX = 266,
+     QUIT = 267,
+     DHIST = 268,
+     LS = 269,
+     ADD = 270,
+     ADDX = 271,
+     EXTRACT = 272,
+     LIST = 273,
+     DELETE = 274,
+     DELETEX = 275,
+     PWD = 276,
+     CLEAR = 277,
+     HELP = 278,
+     LCD = 279,
+     LPWD = 280,
+     MODE = 281,
+     SMB = 282,
+     TAR = 283,
+     PATH = 284,
+     DATE = 285
+   };
+#endif
+/* Tokens.  */
+#define LISTHOST 258
+#define LISTDISK 259
+#define SETHOST 260
+#define SETDISK 261
+#define SETDATE 262
+#define SETTAPE 263
+#define SETMODE 264
+#define CD 265
+#define CDX 266
+#define QUIT 267
+#define DHIST 268
+#define LS 269
+#define ADD 270
+#define ADDX 271
+#define EXTRACT 272
+#define LIST 273
+#define DELETE 274
+#define DELETEX 275
+#define PWD 276
+#define CLEAR 277
+#define HELP 278
+#define LCD 279
+#define LPWD 280
+#define MODE 281
+#define SMB 282
+#define TAR 283
+#define PATH 284
+#define DATE 285
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 31 "uparse.y"
+
+#include "amanda.h"
+#include "amrecover.h"
+
+void           yyerror(char *s);
+extern int     yylex(void);
+extern char *  yytext;
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 42 "uparse.y"
+typedef union YYSTYPE {
+       int     intval;
+       double  floatval;
+       char *  strval;
+       int     subtok;
+} YYSTYPE;
+/* Line 196 of yacc.c.  */
+#line 162 "uparse.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 219 of yacc.c.  */
+#line 174 "uparse.c"
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if defined (__STDC__) || defined (__cplusplus)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     define YYINCLUDED_STDLIB_H
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+#  endif
+#  ifdef __cplusplus
+extern "C" {
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+       && (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+       && (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifdef __cplusplus
+}
+#  endif
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+        || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short int yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short int) + sizeof (YYSTYPE))                    \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined (__GNUC__) && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)                                       \
+    do                                                                 \
+      {                                                                        \
+       YYSIZE_T yynewbytes;                                            \
+       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
+       Stack = &yyptr->Stack;                                          \
+       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  55
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   45
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  31
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  16
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  49
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  61
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   285
+
+#define YYTRANSLATE(YYX)                                               \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned char yyprhs[] =
+{
+       0,     0,     3,     5,     7,     9,    11,    13,    15,    17,
+      19,    21,    23,    24,    26,    29,    31,    34,    37,    41,
+      44,    47,    49,    52,    55,    58,    61,    63,    65,    68,
+      70,    72,    74,    76,    78,    81,    84,    86,    89,    92,
+      94,    97,   100,   102,   105,   108,   110,   112,   115,   117
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      32,     0,    -1,    33,    -1,    34,    -1,    35,    -1,    36,
+      -1,    38,    -1,    40,    -1,    42,    -1,    44,    -1,    45,
+      -1,    46,    -1,    -1,     3,    -1,     4,    29,    -1,     4,
+      -1,     7,    30,    -1,     5,    29,    -1,     6,    29,    29,
+      -1,     6,    29,    -1,     8,    29,    -1,     8,    -1,    10,
+      29,    -1,    11,    29,    -1,     9,    27,    -1,     9,    28,
+      -1,    13,    -1,    14,    -1,    18,    29,    -1,    18,    -1,
+      21,    -1,    22,    -1,    26,    -1,    12,    -1,    15,    37,
+      -1,    37,    29,    -1,    29,    -1,    16,    39,    -1,    39,
+      29,    -1,    29,    -1,    19,    41,    -1,    41,    29,    -1,
+      29,    -1,    20,    43,    -1,    43,    29,    -1,    29,    -1,
+      25,    -1,    24,    29,    -1,    23,    -1,    17,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned char yyrline[] =
+{
+       0,    65,    65,    66,    67,    68,    69,    70,    71,    72,
+      73,    74,    75,    84,    85,    86,    87,    88,    89,    90,
+      91,    92,    93,    94,    95,   100,   108,   109,   110,   111,
+     112,   113,   114,   118,   122,   126,   127,   131,   135,   136,
+     140,   144,   145,   149,   153,   154,   158,   159,   168,   172
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "LISTHOST", "LISTDISK", "SETHOST",
+  "SETDISK", "SETDATE", "SETTAPE", "SETMODE", "CD", "CDX", "QUIT", "DHIST",
+  "LS", "ADD", "ADDX", "EXTRACT", "LIST", "DELETE", "DELETEX", "PWD",
+  "CLEAR", "HELP", "LCD", "LPWD", "MODE", "SMB", "TAR", "PATH", "DATE",
+  "$accept", "ucommand", "set_command", "display_command", "quit_command",
+  "add_command", "add_path", "addx_command", "addx_path", "delete_command",
+  "delete_path", "deletex_command", "deletex_path", "local_command",
+  "help_command", "extract_command", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short int yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    31,    32,    32,    32,    32,    32,    32,    32,    32,
+      32,    32,    32,    33,    33,    33,    33,    33,    33,    33,
+      33,    33,    33,    33,    33,    33,    34,    34,    34,    34,
+      34,    34,    34,    35,    36,    37,    37,    38,    39,    39,
+      40,    41,    41,    42,    43,    43,    44,    44,    45,    46
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     0,     1,     2,     1,     2,     2,     3,     2,
+       2,     1,     2,     2,     2,     2,     1,     1,     2,     1,
+       1,     1,     1,     1,     2,     2,     1,     2,     2,     1,
+       2,     2,     1,     2,     2,     1,     1,     2,     1,     1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+      12,    13,    15,     0,     0,     0,    21,     0,     0,     0,
+      33,    26,    27,     0,     0,    49,    29,     0,     0,    30,
+      31,    48,     0,    46,    32,     0,     2,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    14,    17,    19,    16,
+      20,    24,    25,    22,    23,    36,    34,    39,    37,    28,
+      42,    40,    45,    43,    47,     1,    18,    35,    38,    41,
+      44
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+      -1,    25,    26,    27,    28,    29,    46,    30,    48,    31,
+      51,    32,    53,    33,    34,    35
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -6
+static const yysigned_char yypact[] =
+{
+      -3,    -6,    -5,    -1,     0,     1,     3,    -2,     4,     5,
+      -6,    -6,    -6,     6,     7,    -6,     8,     9,    10,    -6,
+      -6,    -6,    11,    -6,    -6,    27,    -6,    -6,    -6,    -6,
+      -6,    -6,    -6,    -6,    -6,    -6,    -6,    -6,    12,    -6,
+      -6,    -6,    -6,    -6,    -6,    -6,    13,    -6,    14,    -6,
+      -6,    15,    -6,    16,    -6,    -6,    -6,    -6,    -6,    -6,
+      -6
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yysigned_char yypgoto[] =
+{
+      -6,    -6,    -6,    -6,    -6,    -6,    -6,    -6,    -6,    -6,
+      -6,    -6,    -6,    -6,    -6,    -6
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+       1,     2,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    36,    41,    42,    55,    37,    38,
+       0,    39,    40,    43,    44,    45,    47,    49,    50,    52,
+      54,    56,    57,    58,    59,    60
+};
+
+static const yysigned_char yycheck[] =
+{
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    29,    27,    28,     0,    29,    29,
+      -1,    30,    29,    29,    29,    29,    29,    29,    29,    29,
+      29,    29,    29,    29,    29,    29
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    23,    24,    25,    26,    32,    33,    34,    35,    36,
+      38,    40,    42,    44,    45,    46,    29,    29,    29,    30,
+      29,    27,    28,    29,    29,    29,    37,    29,    39,    29,
+      29,    41,    29,    43,    29,     0,    29,    29,    29,    29,
+      29
+};
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                (-2)
+#define YYEOF          0
+
+#define YYACCEPT       goto yyacceptlab
+#define YYABORT                goto yyabortlab
+#define YYERROR                goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL         goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                 \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK;                                              \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;                                                 \
+    }                                                          \
+while (0)
+
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (N)                                                           \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+              (Loc).first_line, (Loc).first_column,    \
+              (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                       \
+do {                                           \
+  if (yydebug)                                 \
+    YYFPRINTF Args;                            \
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)         \
+do {                                                           \
+  if (yydebug)                                                 \
+    {                                                          \
+      YYFPRINTF (stderr, "%s ", Title);                                \
+      yysymprint (stderr,                                      \
+                  Type, Value);        \
+      YYFPRINTF (stderr, "\n");                                        \
+    }                                                          \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    short int *bottom;
+    short int *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                           \
+do {                                                           \
+  if (yydebug)                                                 \
+    yy_stack_print ((Bottom), (Top));                          \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
+#endif
+{
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
+             yyrule - 1, yylno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule)         \
+do {                                   \
+  if (yydebug)                         \
+    yy_reduce_print (Rule);            \
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef        YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      size_t yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+       switch (*++yyp)
+         {
+         case '\'':
+         case ',':
+           goto do_not_strip_quotes;
+
+         case '\\':
+           if (*++yyp != '\\')
+             goto do_not_strip_quotes;
+           /* Fall through.  */
+         default:
+           if (yyres)
+             yyres[yyn] = *yyp;
+           yyn++;
+           break;
+
+         case '"':
+           if (yyres)
+             yyres[yyn] = '\0';
+           return yyn;
+         }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
+
+\f
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+        break;
+    }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  short int *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;            /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+       /* Give user a chance to reallocate the stack. Use copies of
+          these so that the &'s don't force the real ones into
+          memory.  */
+       YYSTYPE *yyvs1 = yyvs;
+       short int *yyss1 = yyss;
+
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  This used to be a
+          conditional around just the two extra args, but that might
+          be undefined if yyoverflow is a macro.  */
+       yyoverflow (YY_("memory exhausted"),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+
+                   &yystacksize);
+
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+       goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+       yystacksize = YYMAXDEPTH;
+
+      {
+       short int *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyexhaustedlab;
+       YYSTACK_RELOCATE (yyss);
+       YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+       YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a look-ahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 12:
+#line 75 "uparse.y"
+    {
+           char * errstr = vstralloc("Invalid command: ", yytext, NULL);
+           yyerror(errstr);
+           amfree(errstr);
+           YYERROR;
+       }
+    break;
+
+  case 13:
+#line 84 "uparse.y"
+    { list_host(); }
+    break;
+
+  case 14:
+#line 85 "uparse.y"
+    { list_disk((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 15:
+#line 86 "uparse.y"
+    { list_disk(NULL); }
+    break;
+
+  case 16:
+#line 87 "uparse.y"
+    { set_date((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 17:
+#line 88 "uparse.y"
+    { set_host((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 18:
+#line 89 "uparse.y"
+    { set_disk((yyvsp[-1].strval), (yyvsp[0].strval)); amfree((yyvsp[-1].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 19:
+#line 90 "uparse.y"
+    { set_disk((yyvsp[0].strval), NULL); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 20:
+#line 91 "uparse.y"
+    { set_tape((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 21:
+#line 92 "uparse.y"
+    { set_tape(""); }
+    break;
+
+  case 22:
+#line 93 "uparse.y"
+    { cd_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 23:
+#line 94 "uparse.y"
+    { cd_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 24:
+#line 95 "uparse.y"
+    {
+#ifdef SAMBA_CLIENT
+                        set_mode(SAMBA_SMBCLIENT);
+#endif /* SAMBA_CLIENT */
+                    }
+    break;
+
+  case 25:
+#line 100 "uparse.y"
+    {
+#ifdef SAMBA_CLIENT
+                        set_mode(SAMBA_TAR);
+#endif /* SAMBA_CLIENT */
+                    }
+    break;
+
+  case 26:
+#line 108 "uparse.y"
+    { list_disk_history(); }
+    break;
+
+  case 27:
+#line 109 "uparse.y"
+    { list_directory(); }
+    break;
+
+  case 28:
+#line 110 "uparse.y"
+    { display_extract_list((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 29:
+#line 111 "uparse.y"
+    { display_extract_list(NULL); }
+    break;
+
+  case 30:
+#line 112 "uparse.y"
+    { show_directory(); }
+    break;
+
+  case 31:
+#line 113 "uparse.y"
+    { clear_extract_list(); }
+    break;
+
+  case 32:
+#line 114 "uparse.y"
+    { show_mode (); }
+    break;
+
+  case 33:
+#line 118 "uparse.y"
+    { quit(); }
+    break;
+
+  case 35:
+#line 126 "uparse.y"
+    { add_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 36:
+#line 127 "uparse.y"
+    { add_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 38:
+#line 135 "uparse.y"
+    { add_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 39:
+#line 136 "uparse.y"
+    { add_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 41:
+#line 144 "uparse.y"
+    { delete_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 42:
+#line 145 "uparse.y"
+    { delete_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 44:
+#line 153 "uparse.y"
+    { delete_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 45:
+#line 154 "uparse.y"
+    { delete_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 46:
+#line 158 "uparse.y"
+    { char buf[STR_SIZE]; puts(getcwd(buf, sizeof(buf))); }
+    break;
+
+  case 47:
+#line 159 "uparse.y"
+    {
+               if (chdir((yyvsp[0].strval)) == -1) {
+                       perror((yyvsp[0].strval));
+               }
+               amfree((yyvsp[0].strval));
+       }
+    break;
+
+  case 48:
+#line 168 "uparse.y"
+    { help_list(); }
+    break;
+
+  case 49:
+#line 172 "uparse.y"
+    { extract_files(); }
+    break;
+
+
+      default: break;
+    }
+
+/* Line 1126 of yacc.c.  */
+#line 1402 "uparse.c"
+\f
+  yyvsp -= yylen;
+  yyssp -= yylen;
+
+
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+       {
+         int yytype = YYTRANSLATE (yychar);
+         YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+         YYSIZE_T yysize = yysize0;
+         YYSIZE_T yysize1;
+         int yysize_overflow = 0;
+         char *yymsg = 0;
+#        define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+         char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+         int yyx;
+
+#if 0
+         /* This is so xgettext sees the translatable formats that are
+            constructed on the fly.  */
+         YY_("syntax error, unexpected %s");
+         YY_("syntax error, unexpected %s, expecting %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+         char *yyfmt;
+         char const *yyf;
+         static char const yyunexpected[] = "syntax error, unexpected %s";
+         static char const yyexpecting[] = ", expecting %s";
+         static char const yyor[] = " or %s";
+         char yyformat[sizeof yyunexpected
+                       + sizeof yyexpecting - 1
+                       + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                          * (sizeof yyor - 1))];
+         char const *yyprefix = yyexpecting;
+
+         /* Start YYX at -YYN if negative to avoid negative indexes in
+            YYCHECK.  */
+         int yyxbegin = yyn < 0 ? -yyn : 0;
+
+         /* Stay within bounds of both yycheck and yytname.  */
+         int yychecklim = YYLAST - yyn;
+         int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+         int yycount = 1;
+
+         yyarg[0] = yytname[yytype];
+         yyfmt = yystpcpy (yyformat, yyunexpected);
+
+         for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+           if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+             {
+               if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                 {
+                   yycount = 1;
+                   yysize = yysize0;
+                   yyformat[sizeof yyunexpected - 1] = '\0';
+                   break;
+                 }
+               yyarg[yycount++] = yytname[yyx];
+               yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+               yysize_overflow |= yysize1 < yysize;
+               yysize = yysize1;
+               yyfmt = yystpcpy (yyfmt, yyprefix);
+               yyprefix = yyor;
+             }
+
+         yyf = YY_(yyformat);
+         yysize1 = yysize + yystrlen (yyf);
+         yysize_overflow |= yysize1 < yysize;
+         yysize = yysize1;
+
+         if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+           yymsg = (char *) YYSTACK_ALLOC (yysize);
+         if (yymsg)
+           {
+             /* Avoid sprintf, as that infringes on the user's name space.
+                Don't have undefined behavior even if the translation
+                produced a string with the wrong number of "%s"s.  */
+             char *yyp = yymsg;
+             int yyi = 0;
+             while ((*yyp = *yyf))
+               {
+                 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+                   {
+                     yyp += yytnamerr (yyp, yyarg[yyi++]);
+                     yyf += 2;
+                   }
+                 else
+                   {
+                     yyp++;
+                     yyf++;
+                   }
+               }
+             yyerror (yymsg);
+             YYSTACK_FREE (yymsg);
+           }
+         else
+           {
+             yyerror (YY_("syntax error"));
+             goto yyexhaustedlab;
+           }
+       }
+      else
+#endif /* YYERROR_VERBOSE */
+       yyerror (YY_("syntax error"));
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+        error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+         /* Return failure if at end of input.  */
+         if (yychar == YYEOF)
+           YYABORT;
+        }
+      else
+       {
+         yydestruct ("Error: discarding", yytoken, &yylval);
+         yychar = YYEMPTY;
+       }
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (0)
+     goto yyerrorlab;
+
+yyvsp -= yylen;
+  yyssp -= yylen;
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+       {
+         yyn += YYTERROR;
+         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+           {
+             yyn = yytable[yyn];
+             if (0 < yyn)
+               break;
+           }
+       }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+       YYABORT;
+
+
+      yydestruct ("Error: popping", yystos[yystate], yyvsp);
+      YYPOPSTACK;
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                 yystos[*yyssp], yyvsp);
+      YYPOPSTACK;
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+#line 176 "uparse.y"
+
+
+void
+yyerror(
+    char *     s)
+{
+  printf("%s\n", s);
+}
+
diff --git a/oldrecover-src/uparse.h b/oldrecover-src/uparse.h
new file mode 100644 (file)
index 0000000..30d97fa
--- /dev/null
@@ -0,0 +1,113 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     LISTHOST = 258,
+     LISTDISK = 259,
+     SETHOST = 260,
+     SETDISK = 261,
+     SETDATE = 262,
+     SETTAPE = 263,
+     SETMODE = 264,
+     CD = 265,
+     CDX = 266,
+     QUIT = 267,
+     DHIST = 268,
+     LS = 269,
+     ADD = 270,
+     ADDX = 271,
+     EXTRACT = 272,
+     LIST = 273,
+     DELETE = 274,
+     DELETEX = 275,
+     PWD = 276,
+     CLEAR = 277,
+     HELP = 278,
+     LCD = 279,
+     LPWD = 280,
+     MODE = 281,
+     SMB = 282,
+     TAR = 283,
+     PATH = 284,
+     DATE = 285
+   };
+#endif
+/* Tokens.  */
+#define LISTHOST 258
+#define LISTDISK 259
+#define SETHOST 260
+#define SETDISK 261
+#define SETDATE 262
+#define SETTAPE 263
+#define SETMODE 264
+#define CD 265
+#define CDX 266
+#define QUIT 267
+#define DHIST 268
+#define LS 269
+#define ADD 270
+#define ADDX 271
+#define EXTRACT 272
+#define LIST 273
+#define DELETE 274
+#define DELETEX 275
+#define PWD 276
+#define CLEAR 277
+#define HELP 278
+#define LCD 279
+#define LPWD 280
+#define MODE 281
+#define SMB 282
+#define TAR 283
+#define PATH 284
+#define DATE 285
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 42 "uparse.y"
+typedef union YYSTYPE {
+       int     intval;
+       double  floatval;
+       char *  strval;
+       int     subtok;
+} YYSTYPE;
+/* Line 1447 of yacc.c.  */
+#line 105 "uparse.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
+
+
diff --git a/oldrecover-src/uparse.y b/oldrecover-src/uparse.y
new file mode 100644 (file)
index 0000000..117e6d9
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: uparse.y,v 1.2 2006/05/25 01:47:13 johnfranks Exp $
+ *
+ * parser for amrecover interactive language
+ */
+%{
+#include "amanda.h"
+#include "amrecover.h"
+
+void           yyerror(char *s);
+extern int     yylex(void);
+extern char *  yytext;
+
+%}
+
+/* DECLARATIONS */
+%union {
+       int     intval;
+       double  floatval;
+       char *  strval;
+       int     subtok;
+}
+
+       /* literal keyword tokens */
+
+%token LISTHOST LISTDISK SETHOST SETDISK SETDATE SETTAPE SETMODE
+%token CD CDX QUIT DHIST LS ADD ADDX EXTRACT
+%token LIST DELETE DELETEX PWD CLEAR HELP LCD LPWD MODE SMB TAR
+
+        /* typed tokens */
+
+%token <strval> PATH
+%token <strval> DATE
+
+
+/* GRAMMAR */
+%%
+
+ucommand:
+       set_command
+  |     display_command
+  |     quit_command
+  |     add_command
+  |     addx_command
+  |     delete_command
+  |     deletex_command
+  |     local_command
+  |    help_command
+  |     extract_command
+  |     {
+           char * errstr = vstralloc("Invalid command: ", yytext, NULL);
+           yyerror(errstr);
+           amfree(errstr);
+           YYERROR;
+       } /* Quiets compiler warnings about unused label */
+  ;
+
+set_command:
+        LISTHOST { list_host(); }
+  |     LISTDISK PATH { list_disk($2); amfree($2); }
+  |    LISTDISK { list_disk(NULL); }
+  |    SETDATE DATE { set_date($2); amfree($2); }
+  |     SETHOST PATH { set_host($2); amfree($2); }
+  |     SETDISK PATH PATH { set_disk($2, $3); amfree($2); amfree($3); }
+  |     SETDISK PATH { set_disk($2, NULL); amfree($2); }
+  |     SETTAPE PATH { set_tape($2); amfree($2); }
+  |     SETTAPE { set_tape(""); }
+  |     CD PATH { cd_glob($2); amfree($2); }
+  |     CDX PATH { cd_regex($2); amfree($2); }
+  |     SETMODE SMB {
+#ifdef SAMBA_CLIENT
+                        set_mode(SAMBA_SMBCLIENT);
+#endif /* SAMBA_CLIENT */
+                    }
+  |     SETMODE TAR {
+#ifdef SAMBA_CLIENT
+                        set_mode(SAMBA_TAR);
+#endif /* SAMBA_CLIENT */
+                    }
+  ;
+
+display_command:
+       DHIST { list_disk_history(); }
+  |     LS { list_directory(); }
+  |     LIST PATH { display_extract_list($2); amfree($2); }
+  |     LIST { display_extract_list(NULL); }
+  |     PWD { show_directory(); }
+  |     CLEAR { clear_extract_list(); }    
+  |     MODE { show_mode (); }
+  ;
+
+quit_command:
+       QUIT { quit(); }
+  ;
+
+add_command:
+       ADD add_path
+  ;
+
+add_path:
+       add_path PATH { add_glob($2); amfree($2); }
+  |     PATH { add_glob($1); amfree($1); }
+  ;
+
+addx_command:
+       ADDX addx_path
+  ;
+
+addx_path:
+       addx_path PATH { add_regex($2); amfree($2); }
+  |     PATH { add_regex($1); amfree($1); }
+  ;
+
+delete_command:
+       DELETE delete_path
+  ;
+
+delete_path:
+       delete_path PATH { delete_glob($2); amfree($2); }
+  |     PATH { delete_glob($1); amfree($1); }
+  ;
+
+deletex_command:
+       DELETEX deletex_path
+  ;
+
+deletex_path:
+       deletex_path PATH { delete_regex($2); amfree($2); }
+  |     PATH { delete_regex($1); amfree($1); }
+  ;
+
+local_command:
+       LPWD { char buf[STR_SIZE]; puts(getcwd(buf, sizeof(buf))); }
+  |     LCD PATH {
+               if (chdir($2) == -1) {
+                       perror($2);
+               }
+               amfree($2);
+       }
+  ;
+
+help_command:
+       HELP { help_list(); }
+  ;
+
+extract_command:
+       EXTRACT { extract_files(); }
+  ;
+
+/* ADDITIONAL C CODE */
+%%
+
+void
+yyerror(
+    char *     s)
+{
+  printf("%s\n", s);
+}
diff --git a/oldrecover-src/uscan.c b/oldrecover-src/uscan.c
new file mode 100644 (file)
index 0000000..0535822
--- /dev/null
@@ -0,0 +1,1976 @@
+/* A lexical scanner generated by flex*/
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else  /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ *     if ( condition_holds )
+ *             yyless( 5 );
+ *     else
+ *             do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+               *yy_cp = yy_hold_char; \
+               YY_RESTORE_YY_MORE_OFFSET \
+               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+               } \
+       while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* Some routines like yy_flex_realloc() are emitted as static but are
+   not called by all lexers. This generates warnings in some compilers,
+   notably GCC. Arrange to suppress these. */
+#ifdef __GNUC__
+#define YY_MAY_BE_UNUSED __attribute__((unused))
+#else
+#define YY_MAY_BE_UNUSED
+#endif
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+       {
+       FILE *yy_input_file;
+
+       char *yy_ch_buf;                /* input buffer */
+       char *yy_buf_pos;               /* current position in input buffer */
+
+       /* Size of input buffer in bytes, not including room for EOB
+        * characters.
+        */
+       yy_size_t yy_buf_size;
+
+       /* Number of characters read into yy_ch_buf, not including EOB
+        * characters.
+        */
+       int yy_n_chars;
+
+       /* Whether we "own" the buffer - i.e., we know we created it,
+        * and can realloc() it to grow it, and should free() it to
+        * delete it.
+        */
+       int yy_is_our_buffer;
+
+       /* Whether this is an "interactive" input source; if so, and
+        * if we're using stdio for input, then we want to use getc()
+        * instead of fread(), to make sure we stop fetching input after
+        * each newline.
+        */
+       int yy_is_interactive;
+
+       /* Whether we're considered to be at the beginning of a line.
+        * If so, '^' rules will be active on the next match, otherwise
+        * not.
+        */
+       int yy_at_bol;
+
+       /* Whether to try to fill the input buffer when we reach the
+        * end of it.
+        */
+       int yy_fill_buffer;
+
+       int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+       /* When an EOF's been seen but there's still some text to process
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+        * shouldn't try reading from the input source any more.  We might
+        * still have a bunch of tokens to match, though, because of
+        * possible backing-up.
+        *
+        * When we actually see the EOF, we change the status to "new"
+        * (via yyrestart()), so that the user can continue scanning by
+        * just pointing yyin at a new input file.
+        */
+#define YY_BUFFER_EOF_PENDING 2
+       };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;                /* whether we need to initialize */
+static int yy_start = 0;       /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )) YY_MAY_BE_UNUSED;
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+       { \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_is_interactive = is_interactive; \
+       }
+
+#define yy_set_bol(at_bol) \
+       { \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_at_bol = at_bol; \
+       }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+       yytext_ptr = yy_bp; \
+       yyleng = (int) (yy_cp - yy_bp); \
+       yy_hold_char = *yy_cp; \
+       *yy_cp = '\0'; \
+       yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 40
+#define YY_END_OF_BUFFER 41
+static yyconst short int yy_accept[131] =
+    {   0,
+        0,    0,    0,    0,   41,   40,   39,   38,   34,   38,
+       38,   22,   38,   38,   38,   38,   38,   38,   38,   38,
+       38,   38,   38,   35,   37,   40,   39,   38,   38,   38,
+       38,   38,    8,   38,   38,   38,   38,   38,   38,   38,
+       38,   13,   38,   38,   38,   38,   38,   38,   35,   36,
+       38,   38,   38,   14,    9,   38,   38,   38,   38,   38,
+       38,   23,   38,   38,   38,   19,   38,   38,   26,   27,
+       29,   38,   38,   15,   38,   38,   11,   38,   21,   38,
+       16,   24,   28,   10,   38,   38,   38,   38,   30,   31,
+       20,   38,   38,   38,   38,   38,   38,   38,   38,   38,
+
+       38,   38,   17,   38,   38,   38,   38,   38,   38,   38,
+       38,   38,   38,   18,   25,   12,   38,   38,    5,    4,
+        3,    6,    7,   38,    2,    1,   33,   38,   32,    0
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    5,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    6,    4,    4,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    4,    4,    4,
+        4,    4,    8,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    9,    4,    4,    4,    4,   10,   11,   12,   13,
+
+       14,    4,    4,   15,   16,    4,   17,   18,   19,    4,
+       20,   21,   22,   23,   24,   25,   26,    4,   27,   28,
+       29,    4,    4,    4,    4,    4,    1,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4
+    } ;
+
+static yyconst int yy_meta[30] =
+    {   0,
+        1,    1,    2,    3,    4,    3,    3,    3,    5,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3
+    } ;
+
+static yyconst short int yy_base[135] =
+    {   0,
+        0,    0,   25,   26,  161,  162,   30,    0,  162,  154,
+       30,    0,  146,   25,  144,  129,   25,   28,  136,  128,
+      128,   28,  143,    0,  162,    0,   43,    0,   44,  145,
+       47,  138,  122,  135,  130,   32,  129,  122,  132,  120,
+      116,    0,  129,  128,  124,  114,  127,  114,    0,  162,
+      129,   49,   52,  107,    0,  124,  119,  107,  108,  109,
+      104,    0,  103,  114,  112,    0,  100,   47,    0,    0,
+      117,  116,  115,    0,   98,   95,    0,  109,    0,   98,
+       48,    0,    0,    0,   54,   97,   96,  105,  107,   61,
+        0,   99,  100,   88,   94,   89,   83,   83,   82,   92,
+
+       83,   96,   74,   76,   71,   75,   74,   83,   79,   70,
+       80,   79,   67,    0,    0,    0,   72,   58,    0,    0,
+        0,    0,    0,   64,    0,    0,   69,   62,   58,  162,
+       76,   79,   84,   87
+    } ;
+
+static yyconst short int yy_def[135] =
+    {   0,
+      130,    1,  131,  131,  130,  130,  130,  132,  130,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  133,  130,  134,  130,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  133,  130,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,    0,
+      130,  130,  130,  130
+    } ;
+
+static yyconst short int yy_nxt[192] =
+    {   0,
+        6,    7,    7,    8,    9,   10,   11,   12,    8,   13,
+        8,   14,   15,   16,   17,    8,    8,   18,   19,    8,
+       20,   21,    8,   22,   23,    8,    8,    8,    8,   25,
+       25,   27,   27,   26,   26,   30,   31,   33,   37,   39,
+       38,   46,   34,   40,   27,   27,   47,   58,   41,   51,
+       52,   42,   30,   31,   72,   52,   59,   73,   53,   85,
+       95,   86,   96,   97,  129,   87,  102,   90,  129,   98,
+      127,   88,  124,  113,  128,  127,   24,   24,   24,   24,
+       24,   28,  126,   28,   49,   49,   49,   50,  125,   50,
+       50,   50,  123,  122,  121,  120,  119,  118,  117,  116,
+
+      115,  114,  113,  112,  111,  110,  109,  108,  107,  106,
+      105,  104,  103,   89,  101,  100,   99,   94,   93,   92,
+       91,   90,   89,   71,   84,   83,   82,   81,   80,   79,
+       78,   77,   76,   75,   74,   71,   70,   69,   68,   67,
+       66,   65,   64,   63,   62,   61,   60,   57,   56,   55,
+       54,   53,   48,   45,   44,   43,   36,   35,   32,   29,
+      130,    5,  130,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130
+
+    } ;
+
+static yyconst short int yy_chk[192] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    3,
+        4,    7,    7,    3,    4,   11,   11,   14,   17,   18,
+       17,   22,   14,   18,   27,   27,   22,   36,   18,   29,
+       29,   18,   31,   31,   52,   52,   36,   53,   53,   68,
+       81,   68,   81,   85,  129,   68,   90,   90,  128,   85,
+      124,   68,  113,  113,  127,  127,  131,  131,  131,  131,
+      131,  132,  118,  132,  133,  133,  133,  134,  117,  134,
+      134,  134,  112,  111,  110,  109,  108,  107,  106,  105,
+
+      104,  103,  102,  101,  100,   99,   98,   97,   96,   95,
+       94,   93,   92,   89,   88,   87,   86,   80,   78,   76,
+       75,   73,   72,   71,   67,   65,   64,   63,   61,   60,
+       59,   58,   57,   56,   54,   51,   48,   47,   46,   45,
+       44,   43,   41,   40,   39,   38,   37,   35,   34,   33,
+       32,   30,   23,   21,   20,   19,   16,   15,   13,   10,
+        5,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130
+
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "uscan.l"
+#define INITIAL 0
+/*
+ * amanda, the advanced maryland automatic network disk archiver
+ * Copyright (c) 1991-2000 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: uscan.l,v 1.3 2006/07/05 11:15:56 martinea Exp $
+ *
+ * lexer for amrecover interactive language
+ */
+#line 32 "uscan.l"
+#include "amanda.h"
+#include "uparse.h"
+
+/*
+ * We redefine this here to prevent compiler warning about ignoring fwrite
+ * return value...
+ */
+#undef ECHO
+#define ECHO do {                                              \
+               if (fwrite(yytext, (size_t)yyleng, 1, yyout) <= 0) {    \
+                   yyerror("ECHO failure");                    \
+               }                                               \
+       } while (0)
+
+#define YY_NO_UNPUT
+
+#define        DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD-HH-MM-SS")   /* includes null */
+
+#define YY_DECL        int yylex()
+extern int yylex(void);
+
+extern void    yyerror(char *s);
+extern int     yyparse(void);
+static int     ll_parse_date(int type, char *text);
+int            process_line(char *line);
+#define quotedpath 1
+
+#line 62 "uscan.l"
+static char *string_buf = NULL;
+#line 517 "uscan.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+       if ( yy_current_buffer->yy_is_interactive ) \
+               { \
+               int c = '*', n; \
+               for ( n = 0; n < max_size && \
+                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+                       buf[n] = (char) c; \
+               if ( c == '\n' ) \
+                       buf[n++] = (char) c; \
+               if ( c == EOF && ferror( yyin ) ) \
+                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
+               result = n; \
+               } \
+       else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+                 && ferror( yyin ) ) \
+               YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+       YY_USER_ACTION
+
+YY_DECL
+       {
+       register yy_state_type yy_current_state;
+       register char *yy_cp = NULL, *yy_bp = NULL;
+       register int yy_act;
+
+#line 65 "uscan.l"
+
+
+
+    /* literal keyword tokens */
+
+
+#line 675 "uscan.c"
+
+       if ( yy_init )
+               {
+               yy_init = 0;
+
+#ifdef YY_USER_INIT
+               YY_USER_INIT;
+#endif
+
+               if ( ! yy_start )
+                       yy_start = 1;   /* first start state */
+
+               if ( ! yyin )
+                       yyin = stdin;
+
+               if ( ! yyout )
+                       yyout = stdout;
+
+               if ( ! yy_current_buffer )
+                       yy_current_buffer =
+                               yy_create_buffer( yyin, YY_BUF_SIZE );
+
+               yy_load_buffer_state();
+               }
+
+       while ( 1 )             /* loops until end-of-file is reached */
+               {
+               yy_cp = yy_c_buf_p;
+
+               /* Support of yytext. */
+               *yy_cp = yy_hold_char;
+
+               /* yy_bp points to the position in yy_ch_buf of the start of
+                * the current run.
+                */
+               yy_bp = yy_cp;
+
+               yy_current_state = yy_start;
+yy_match:
+               do
+                       {
+                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+                       if ( yy_accept[yy_current_state] )
+                               {
+                               yy_last_accepting_state = yy_current_state;
+                               yy_last_accepting_cpos = yy_cp;
+                               }
+                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                               {
+                               yy_current_state = (int) yy_def[yy_current_state];
+                               if ( yy_current_state >= 131 )
+                                       yy_c = yy_meta[(unsigned int) yy_c];
+                               }
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                       ++yy_cp;
+                       }
+               while ( yy_base[yy_current_state] != 162 );
+
+yy_find_action:
+               yy_act = yy_accept[yy_current_state];
+               if ( yy_act == 0 )
+                       { /* have to back up */
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
+                       yy_act = yy_accept[yy_current_state];
+                       }
+
+               YY_DO_BEFORE_ACTION;
+
+
+do_action:     /* This label is used only to access EOF actions. */
+
+
+               switch ( yy_act )
+       { /* beginning of action switch */
+                       case 0: /* must back up */
+                       /* undo the effects of YY_DO_BEFORE_ACTION */
+                       *yy_cp = yy_hold_char;
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
+                       goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 71 "uscan.l"
+{ return LISTHOST; }
+       YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 72 "uscan.l"
+{ return LISTDISK; }
+       YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 73 "uscan.l"
+{ return SETHOST; }
+       YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 74 "uscan.l"
+{ return SETDISK; }
+       YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 75 "uscan.l"
+{ return SETDATE; }
+       YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 76 "uscan.l"
+{ return SETMODE; }
+       YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 77 "uscan.l"
+{ return SETTAPE; }
+       YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 78 "uscan.l"
+{ return CD; }
+       YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 79 "uscan.l"
+{ return CDX; }
+       YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 80 "uscan.l"
+{ return QUIT; }
+       YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 81 "uscan.l"
+{ return QUIT; }
+       YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 82 "uscan.l"
+{ return DHIST; }
+       YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 83 "uscan.l"
+{ return LS; }
+       YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 84 "uscan.l"
+{ return ADD; }
+       YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 85 "uscan.l"
+{ return ADDX; }
+       YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 86 "uscan.l"
+{ return LIST; }
+       YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 87 "uscan.l"
+{ return DELETE; }
+       YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 88 "uscan.l"
+{ return DELETEX; }
+       YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 89 "uscan.l"
+{ return PWD; }
+       YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 90 "uscan.l"
+{ return CLEAR; }
+       YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 91 "uscan.l"
+{ return HELP; }
+       YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 92 "uscan.l"
+{ return HELP; }
+       YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 93 "uscan.l"
+{ return LCD; }
+       YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 94 "uscan.l"
+{ return LPWD; }
+       YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 95 "uscan.l"
+{ return EXTRACT; }
+       YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 96 "uscan.l"
+{ return SMB; }
+       YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 97 "uscan.l"
+{ return TAR; }
+       YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 98 "uscan.l"
+{ return MODE; }
+       YY_BREAK
+
+    /* dates */
+
+case 29:
+YY_RULE_SETUP
+#line 104 "uscan.l"
+{ return ll_parse_date(1, yytext); }
+       YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 105 "uscan.l"
+{ return ll_parse_date(2, yytext); }
+       YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 106 "uscan.l"
+{ return ll_parse_date(3, yytext); }
+       YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 107 "uscan.l"
+{ return ll_parse_date(4, yytext); }
+       YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 108 "uscan.l"
+{ return ll_parse_date(5, yytext); }
+       YY_BREAK
+
+    /* quoted file names */
+
+case 34:
+YY_RULE_SETUP
+#line 114 "uscan.l"
+{
+    if(string_buf != NULL) {
+       printf("ERROR:string_buf != NULL: %s\n",string_buf);
+    }
+    BEGIN(quotedpath);
+    strappend(string_buf, yytext);
+}
+       YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 122 "uscan.l"
+{
+    strappend(string_buf, yytext);
+}
+       YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 126 "uscan.l"
+{
+    /* escaped character (including quote) */
+    strappend(string_buf, yytext);
+}
+       YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 131 "uscan.l"
+{ /* saw closing quote - all done */
+    strappend(string_buf, yytext);
+    yylval.strval = string_buf;
+    string_buf = NULL;
+    BEGIN(INITIAL);
+    return PATH;
+}
+       YY_BREAK
+
+    /* file names */
+
+case 38:
+YY_RULE_SETUP
+#line 143 "uscan.l"
+{
+    yylval.strval = stralloc(yytext);
+    return PATH;
+}
+       YY_BREAK
+
+    /* whitespace */
+
+case 39:
+YY_RULE_SETUP
+#line 152 "uscan.l"
+;     /* whitespace */
+       YY_BREAK
+
+    /* anything else */
+    /* everything should have been handled by now, so this rule is disabled */
+
+
+#if 0
+.      { yyerror("invalid character"); }
+#endif
+
+case 40:
+YY_RULE_SETUP
+#line 165 "uscan.l"
+ECHO;
+       YY_BREAK
+#line 999 "uscan.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(quotedpath):
+       yyterminate();
+
+       case YY_END_OF_BUFFER:
+               {
+               /* Amount of text matched not including the EOB char. */
+               int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = yy_hold_char;
+               YY_RESTORE_YY_MORE_OFFSET
+
+               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+                       /* We're scanning a new file or input source.  It's
+                        * possible that this happened because the user
+                        * just pointed yyin at a new source and called
+                        * yylex().  If so, then we have to assure
+                        * consistency between yy_current_buffer and our
+                        * globals.  Here is the right place to do so, because
+                        * this is the first action (other than possibly a
+                        * back-up) that will match for the new input source.
+                        */
+                       yy_n_chars = yy_current_buffer->yy_n_chars;
+                       yy_current_buffer->yy_input_file = yyin;
+                       yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+                       }
+
+               /* Note that here we test for yy_c_buf_p "<=" to the position
+                * of the first EOB in the buffer, since yy_c_buf_p will
+                * already have been incremented past the NUL character
+                * (since all states make transitions on EOB to the
+                * end-of-buffer state).  Contrast this with the test
+                * in input().
+                */
+               if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+                       { /* This was really a NUL. */
+                       yy_state_type yy_next_state;
+
+                       yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+                       yy_current_state = yy_get_previous_state();
+
+                       /* Okay, we're now positioned to make the NUL
+                        * transition.  We couldn't have
+                        * yy_get_previous_state() go ahead and do it
+                        * for us because it doesn't know how to deal
+                        * with the possibility of jamming (and we don't
+                        * want to build jamming into it because then it
+                        * will run more slowly).
+                        */
+
+                       yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+                       yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+                       if ( yy_next_state )
+                               {
+                               /* Consume the NUL. */
+                               yy_cp = ++yy_c_buf_p;
+                               yy_current_state = yy_next_state;
+                               goto yy_match;
+                               }
+
+                       else
+                               {
+                               yy_cp = yy_c_buf_p;
+                               goto yy_find_action;
+                               }
+                       }
+
+               else switch ( yy_get_next_buffer() )
+                       {
+                       case EOB_ACT_END_OF_FILE:
+                               {
+                               yy_did_buffer_switch_on_eof = 0;
+
+                               if ( yywrap() )
+                                       {
+                                       /* Note: because we've taken care in
+                                        * yy_get_next_buffer() to have set up
+                                        * yytext, we can now set up
+                                        * yy_c_buf_p so that if some total
+                                        * hoser (like flex itself) wants to
+                                        * call the scanner after we return the
+                                        * YY_NULL, it'll still work - another
+                                        * YY_NULL will get returned.
+                                        */
+                                       yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+                                       yy_act = YY_STATE_EOF(YY_START);
+                                       goto do_action;
+                                       }
+
+                               else
+                                       {
+                                       if ( ! yy_did_buffer_switch_on_eof )
+                                               YY_NEW_FILE;
+                                       }
+                               break;
+                               }
+
+                       case EOB_ACT_CONTINUE_SCAN:
+                               yy_c_buf_p =
+                                       yytext_ptr + yy_amount_of_matched_text;
+
+                               yy_current_state = yy_get_previous_state();
+
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
+                               goto yy_match;
+
+                       case EOB_ACT_LAST_MATCH:
+                               yy_c_buf_p =
+                               &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+                               yy_current_state = yy_get_previous_state();
+
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
+                               goto yy_find_action;
+                       }
+               break;
+               }
+
+       default:
+               YY_FATAL_ERROR(
+                       "fatal flex scanner internal error--no action found" );
+       } /* end of action switch */
+               } /* end of scanning one token */
+       } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *     EOB_ACT_LAST_MATCH -
+ *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *     EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+       {
+       register char *dest = yy_current_buffer->yy_ch_buf;
+       register char *source = yytext_ptr;
+       register int number_to_move, i;
+       int ret_val;
+
+       if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+               YY_FATAL_ERROR(
+               "fatal flex scanner internal error--end of buffer missed" );
+
+       if ( yy_current_buffer->yy_fill_buffer == 0 )
+               { /* Don't try to fill the buffer, so this is an EOF. */
+               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+                       {
+                       /* We matched a single character, the EOB, so
+                        * treat this as a final EOF.
+                        */
+                       return EOB_ACT_END_OF_FILE;
+                       }
+
+               else
+                       {
+                       /* We matched some text prior to the EOB, first
+                        * process it.
+                        */
+                       return EOB_ACT_LAST_MATCH;
+                       }
+               }
+
+       /* Try to read more data. */
+
+       /* First move last chars to start of buffer. */
+       number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+       for ( i = 0; i < number_to_move; ++i )
+               *(dest++) = *(source++);
+
+       if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+               /* don't do the read, it's not guaranteed to return an EOF,
+                * just force an EOF
+                */
+               yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+       else
+               {
+               int num_to_read =
+                       yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+               while ( num_to_read <= 0 )
+                       { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+                       YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+                       /* just a shorter name for the current buffer */
+                       YY_BUFFER_STATE b = yy_current_buffer;
+
+                       int yy_c_buf_p_offset =
+                               (int) (yy_c_buf_p - b->yy_ch_buf);
+
+                       if ( b->yy_is_our_buffer )
+                               {
+                               int new_size = b->yy_buf_size * 2;
+
+                               if ( new_size <= 0 )
+                                       b->yy_buf_size += b->yy_buf_size / 8;
+                               else
+                                       b->yy_buf_size *= 2;
+
+                               b->yy_ch_buf = (char *)
+                                       /* Include room in for 2 EOB chars. */
+                                       yy_flex_realloc( (void *) b->yy_ch_buf,
+                                                        b->yy_buf_size + 2 );
+                               }
+                       else
+                               /* Can't grow it, we don't own it. */
+                               b->yy_ch_buf = 0;
+
+                       if ( ! b->yy_ch_buf )
+                               YY_FATAL_ERROR(
+                               "fatal error - scanner input buffer overflow" );
+
+                       yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+                       num_to_read = yy_current_buffer->yy_buf_size -
+                                               number_to_move - 1;
+#endif
+                       }
+
+               if ( num_to_read > YY_READ_BUF_SIZE )
+                       num_to_read = YY_READ_BUF_SIZE;
+
+               /* Read in more data. */
+               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+                       yy_n_chars, num_to_read );
+
+               yy_current_buffer->yy_n_chars = yy_n_chars;
+               }
+
+       if ( yy_n_chars == 0 )
+               {
+               if ( number_to_move == YY_MORE_ADJ )
+                       {
+                       ret_val = EOB_ACT_END_OF_FILE;
+                       yyrestart( yyin );
+                       }
+
+               else
+                       {
+                       ret_val = EOB_ACT_LAST_MATCH;
+                       yy_current_buffer->yy_buffer_status =
+                               YY_BUFFER_EOF_PENDING;
+                       }
+               }
+
+       else
+               ret_val = EOB_ACT_CONTINUE_SCAN;
+
+       yy_n_chars += number_to_move;
+       yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+       yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+       yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+       return ret_val;
+       }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+       {
+       register yy_state_type yy_current_state;
+       register char *yy_cp;
+
+       yy_current_state = yy_start;
+
+       for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+               {
+               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+               if ( yy_accept[yy_current_state] )
+                       {
+                       yy_last_accepting_state = yy_current_state;
+                       yy_last_accepting_cpos = yy_cp;
+                       }
+               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                       {
+                       yy_current_state = (int) yy_def[yy_current_state];
+                       if ( yy_current_state >= 131 )
+                               yy_c = yy_meta[(unsigned int) yy_c];
+                       }
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+               }
+
+       return yy_current_state;
+       }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *     next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+       {
+       register int yy_is_jam;
+       register char *yy_cp = yy_c_buf_p;
+
+       register YY_CHAR yy_c = 1;
+       if ( yy_accept[yy_current_state] )
+               {
+               yy_last_accepting_state = yy_current_state;
+               yy_last_accepting_cpos = yy_cp;
+               }
+       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+               {
+               yy_current_state = (int) yy_def[yy_current_state];
+               if ( yy_current_state >= 131 )
+                       yy_c = yy_meta[(unsigned int) yy_c];
+               }
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+       yy_is_jam = (yy_current_state == 130);
+
+       return yy_is_jam ? 0 : yy_current_state;
+       }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+       {
+       register char *yy_cp = yy_c_buf_p;
+
+       /* undo effects of setting up yytext */
+       *yy_cp = yy_hold_char;
+
+       if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+               { /* need to shift things up to make room */
+               /* +2 for EOB chars. */
+               register int number_to_move = yy_n_chars + 2;
+               register char *dest = &yy_current_buffer->yy_ch_buf[
+                                       yy_current_buffer->yy_buf_size + 2];
+               register char *source =
+                               &yy_current_buffer->yy_ch_buf[number_to_move];
+
+               while ( source > yy_current_buffer->yy_ch_buf )
+                       *--dest = *--source;
+
+               yy_cp += (int) (dest - source);
+               yy_bp += (int) (dest - source);
+               yy_current_buffer->yy_n_chars =
+                       yy_n_chars = yy_current_buffer->yy_buf_size;
+
+               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
+               }
+
+       *--yy_cp = (char) c;
+
+
+       yytext_ptr = yy_bp;
+       yy_hold_char = *yy_cp;
+       yy_c_buf_p = yy_cp;
+       }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+       {
+       int c;
+
+       *yy_c_buf_p = yy_hold_char;
+
+       if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+               {
+               /* yy_c_buf_p now points to the character we want to return.
+                * If this occurs *before* the EOB characters, then it's a
+                * valid NUL; if not, then we've hit the end of the buffer.
+                */
+               if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+                       /* This was really a NUL. */
+                       *yy_c_buf_p = '\0';
+
+               else
+                       { /* need more input */
+                       int offset = yy_c_buf_p - yytext_ptr;
+                       ++yy_c_buf_p;
+
+                       switch ( yy_get_next_buffer() )
+                               {
+                               case EOB_ACT_LAST_MATCH:
+                                       /* This happens because yy_g_n_b()
+                                        * sees that we've accumulated a
+                                        * token and flags that we need to
+                                        * try matching the token before
+                                        * proceeding.  But for input(),
+                                        * there's no matching to consider.
+                                        * So convert the EOB_ACT_LAST_MATCH
+                                        * to EOB_ACT_END_OF_FILE.
+                                        */
+
+                                       /* Reset buffer status. */
+                                       yyrestart( yyin );
+
+                                       /* fall through */
+
+                               case EOB_ACT_END_OF_FILE:
+                                       {
+                                       if ( yywrap() )
+                                               return EOF;
+
+                                       if ( ! yy_did_buffer_switch_on_eof )
+                                               YY_NEW_FILE;
+#ifdef __cplusplus
+                                       return yyinput();
+#else
+                                       return input();
+#endif
+                                       }
+
+                               case EOB_ACT_CONTINUE_SCAN:
+                                       yy_c_buf_p = yytext_ptr + offset;
+                                       break;
+                               }
+                       }
+               }
+
+       c = *(unsigned char *) yy_c_buf_p;      /* cast for 8-bit char's */
+       *yy_c_buf_p = '\0';     /* preserve yytext */
+       yy_hold_char = *++yy_c_buf_p;
+
+
+       return c;
+       }
+#endif /* YY_NO_INPUT */
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+       {
+       if ( ! yy_current_buffer )
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+       yy_init_buffer( yy_current_buffer, input_file );
+       yy_load_buffer_state();
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+       {
+       if ( yy_current_buffer == new_buffer )
+               return;
+
+       if ( yy_current_buffer )
+               {
+               /* Flush out information for old buffer. */
+               *yy_c_buf_p = yy_hold_char;
+               yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+               yy_current_buffer->yy_n_chars = yy_n_chars;
+               }
+
+       yy_current_buffer = new_buffer;
+       yy_load_buffer_state();
+
+       /* We don't actually know whether we did this switch during
+        * EOF (yywrap()) processing, but the only time this flag
+        * is looked at is after yywrap() is called, so it's safe
+        * to go ahead and always set it.
+        */
+       yy_did_buffer_switch_on_eof = 1;
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+       {
+       yy_n_chars = yy_current_buffer->yy_n_chars;
+       yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+       yyin = yy_current_buffer->yy_input_file;
+       yy_hold_char = *yy_c_buf_p;
+       }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+       {
+       YY_BUFFER_STATE b;
+
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_buf_size = size;
+
+       /* yy_ch_buf has to be 2 characters longer than the size given because
+        * we need to put in 2 end-of-buffer characters.
+        */
+       b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+       if ( ! b->yy_ch_buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_is_our_buffer = 1;
+
+       yy_init_buffer( b, file );
+
+       return b;
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+       {
+       if ( ! b )
+               return;
+
+       if ( b == yy_current_buffer )
+               yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+       if ( b->yy_is_our_buffer )
+               yy_flex_free( (void *) b->yy_ch_buf );
+
+       yy_flex_free( (void *) b );
+       }
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+       {
+       yy_flush_buffer( b );
+
+       b->yy_input_file = file;
+       b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+       b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+       b->yy_is_interactive = 0;
+#else
+       b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+       }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+       {
+       if ( ! b )
+               return;
+
+       b->yy_n_chars = 0;
+
+       /* We always need two end-of-buffer characters.  The first causes
+        * a transition to the end-of-buffer state.  The second causes
+        * a jam in that state.
+        */
+       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+       b->yy_buf_pos = &b->yy_ch_buf[0];
+
+       b->yy_at_bol = 1;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       if ( b == yy_current_buffer )
+               yy_load_buffer_state();
+       }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+       {
+       YY_BUFFER_STATE b;
+
+       if ( size < 2 ||
+            base[size-2] != YY_END_OF_BUFFER_CHAR ||
+            base[size-1] != YY_END_OF_BUFFER_CHAR )
+               /* They forgot to leave room for the EOB's. */
+               return 0;
+
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
+       b->yy_buf_pos = b->yy_ch_buf = base;
+       b->yy_is_our_buffer = 0;
+       b->yy_input_file = 0;
+       b->yy_n_chars = b->yy_buf_size;
+       b->yy_is_interactive = 0;
+       b->yy_at_bol = 1;
+       b->yy_fill_buffer = 0;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       yy_switch_to_buffer( b );
+
+       return b;
+       }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+       {
+       int len;
+       for ( len = 0; yy_str[len]; ++len )
+               ;
+
+       return yy_scan_bytes( yy_str, len );
+       }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+       {
+       YY_BUFFER_STATE b;
+       char *buf;
+       yy_size_t n;
+       int i;
+
+       /* Get memory for full buffer, including space for trailing EOB's. */
+       n = len + 2;
+       buf = (char *) yy_flex_alloc( n );
+       if ( ! buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+       for ( i = 0; i < len; ++i )
+               buf[i] = bytes[i];
+
+       buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+       b = yy_scan_buffer( buf, n );
+       if ( ! b )
+               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+       /* It's okay to grow etc. this buffer, and we should throw it
+        * away when we're done.
+        */
+       b->yy_is_our_buffer = 1;
+
+       return b;
+       }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+       {
+       if ( yy_start_stack_ptr >= yy_start_stack_depth )
+               {
+               yy_size_t new_size;
+
+               yy_start_stack_depth += YY_START_STACK_INCR;
+               new_size = yy_start_stack_depth * sizeof( int );
+
+               if ( ! yy_start_stack )
+                       yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+               else
+                       yy_start_stack = (int *) yy_flex_realloc(
+                                       (void *) yy_start_stack, new_size );
+
+               if ( ! yy_start_stack )
+                       YY_FATAL_ERROR(
+                       "out of memory expanding start-condition stack" );
+               }
+
+       yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+       BEGIN(new_state);
+       }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+       {
+       if ( --yy_start_stack_ptr < 0 )
+               YY_FATAL_ERROR( "start-condition stack underflow" );
+
+       BEGIN(yy_start_stack[yy_start_stack_ptr]);
+       }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+       {
+       return yy_start_stack[yy_start_stack_ptr - 1];
+       }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+       {
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+       }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+               yytext[yyleng] = yy_hold_char; \
+               yy_c_buf_p = yytext + n; \
+               yy_hold_char = *yy_c_buf_p; \
+               *yy_c_buf_p = '\0'; \
+               yyleng = n; \
+               } \
+       while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+       {
+       register int i;
+       for ( i = 0; i < n; ++i )
+               s1[i] = s2[i];
+       }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+       {
+       register int n;
+       for ( n = 0; s[n]; ++n )
+               ;
+
+       return n;
+       }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+       {
+       return (void *) malloc( size );
+       }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+       {
+       /* The cast to (char *) in the following accommodates both
+        * implementations that use char* generic pointers, and those
+        * that use void* generic pointers.  It works with the latter
+        * because both ANSI C and C++ allow castless assignment from
+        * any pointer type to void*, and deal with argument conversions
+        * as though doing an assignment.
+        */
+       return (void *) realloc( (char *) ptr, size );
+       }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+       {
+       free( ptr );
+       }
+
+#if YY_MAIN
+int main()
+       {
+       yylex();
+       return 0;
+       }
+#endif
+#line 165 "uscan.l"
+
+
+int
+process_line(
+    char *     line)
+{
+    YY_BUFFER_STATE b;
+    int result;
+
+    b = yy_scan_string(line);          /* tell lex to scan lineread */
+    result = yyparse();                        /* parse lineread and act */
+    yy_delete_buffer(b);
+    return result;
+}
+
+static int
+ll_parse_date(
+    int                type,
+    char *     text)
+{
+    time_t now;
+    struct tm *t;
+    int y=2000, m=0, d=1, h=0, mi=0, s=0;
+    int ret;
+
+    now = time((time_t *)NULL);
+    t = localtime(&now);
+    if (t) {
+       y = 1900+t->tm_year;
+       m = t->tm_mon+1;
+       d = t->tm_mday;
+    }
+    switch(type) {
+    case 1:
+       if (sscanf(text, "---%d", &d) != 1) {
+           yyerror("invalid date");
+        }
+        break;
+    case 2:
+       if (sscanf(text, "--%d-%d", &m, &d) != 2) {
+           yyerror("invalid date");
+        }
+        break;
+    case 3:
+       if (sscanf(text, "%d-%d-%d", &y, &m, &d) != 3) {
+           yyerror("invalid date");        
+        }
+        break;
+    case 4:
+       if (sscanf(text, "%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi, &s) != 6) {
+           yyerror("invalid date");
+       }
+        break;
+    case 5:
+       if (sscanf(text, "%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi) != 5) {
+           yyerror("invalid date");
+       }
+        break;
+    }
+
+    ret = PATH;                                /* cause a parse error */
+    if(y < 70) {
+       y += 2000;
+    } else if(y < 100) {
+       y += 1900;
+    }
+    if(y < 1000 || y > 9999) {
+       yyerror("invalid year");
+    } else if(m < 1 || m > 12) {
+       yyerror("invalid month");
+    } else if(d < 1 || d > 31) {
+       yyerror("invalid day");
+    } else if(h < 0 || h > 24) {
+       yyerror("invalid hour");
+    } else if(mi < 0 || mi > 59) {
+       yyerror("invalid minute");
+    } else if(s < 0 || s > 59) {
+       yyerror("invalid second");
+    } else if(type < 4) {
+       yylval.strval = alloc(DATE_ALLOC_SIZE);
+       snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
+       ret = DATE;
+    } else {
+       yylval.strval = alloc(DATE_ALLOC_SIZE);
+       snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d-%02d-%02d-%02d", y, m, d, h, mi, s);
+       ret = DATE;
+    }
+    return ret;
+}
+
+int
+yywrap(void)
+{
+  return 1;
+}
diff --git a/oldrecover-src/uscan.l b/oldrecover-src/uscan.l
new file mode 100644 (file)
index 0000000..69674ce
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * amanda, the advanced maryland automatic network disk archiver
+ * Copyright (c) 1991-2000 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.
+ *
+ * Authors: the Amanda Development Team.  Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: uscan.l,v 1.3 2006/07/05 11:15:56 martinea Exp $
+ *
+ * lexer for amrecover interactive language
+ */
+%{
+#include "amanda.h"
+#include "uparse.h"
+
+/*
+ * We redefine this here to prevent compiler warning about ignoring fwrite
+ * return value...
+ */
+#undef ECHO
+#define ECHO do {                                              \
+               if (fwrite(yytext, (size_t)yyleng, 1, yyout) <= 0) {    \
+                   yyerror("ECHO failure");                    \
+               }                                               \
+       } while (0)
+
+#define YY_NO_UNPUT
+
+#define        DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD-HH-MM-SS")   /* includes null */
+
+#define YY_DECL        int yylex()
+extern int yylex(void);
+
+extern void    yyerror(char *s);
+extern int     yyparse(void);
+static int     ll_parse_date(int type, char *text);
+int            process_line(char *line);
+%}
+
+%x quotedpath
+
+%{
+static char *string_buf = NULL;
+%}
+
+%%
+
+%{
+    /* literal keyword tokens */
+%}
+
+listhost       { return LISTHOST; }
+listdisk       { return LISTDISK; }
+sethost        { return SETHOST; }
+setdisk        { return SETDISK; }
+setdate { return SETDATE; }
+setmode        { return SETMODE; }
+settape { return SETTAPE; }
+cd     { return CD; }
+cdx    { return CDX; }
+quit    { return QUIT; }
+exit    { return QUIT; }
+history { return DHIST; }
+ls      { return LS; }
+add     { return ADD; }
+addx    { return ADDX; }
+list    { return LIST; }
+delete  { return DELETE; }
+deletex { return DELETEX; }
+pwd     { return PWD; }
+clear   { return CLEAR; }
+help    { return HELP; }
+\?      { return HELP; }
+lcd     { return LCD; }
+lpwd    { return LPWD; }
+extract { return EXTRACT; }
+smb     { return SMB; }
+tar     { return TAR; }
+mode    { return MODE; }
+
+%{
+    /* dates */
+%}
+
+---[0-9]+              { return ll_parse_date(1, yytext); }
+--[0-9]+-[0-9]+                { return ll_parse_date(2, yytext); }
+[0-9]+-[0-9]+-[0-9]+   { return ll_parse_date(3, yytext); }
+[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+      { return ll_parse_date(4, yytext); }
+[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+     { return ll_parse_date(5, yytext); }
+
+%{
+    /* quoted file names */
+%}
+
+\"                     {
+    if(string_buf != NULL) {
+       printf("ERROR:string_buf != NULL: %s\n",string_buf);
+    }
+    BEGIN(quotedpath);
+    strappend(string_buf, yytext);
+}
+
+<quotedpath>[^\\\"]+   {
+    strappend(string_buf, yytext);
+}
+
+<quotedpath>\\.        {
+    /* escaped character (including quote) */
+    strappend(string_buf, yytext);
+}
+
+<quotedpath>\" { /* saw closing quote - all done */
+    strappend(string_buf, yytext);
+    yylval.strval = string_buf;
+    string_buf = NULL;
+    BEGIN(INITIAL);
+    return PATH;
+}
+
+%{
+    /* file names */
+%}
+
+[^[:space:][:cntrl:]"]+                {
+    yylval.strval = stralloc(yytext);
+    return PATH;
+}
+
+%{
+    /* whitespace */
+%}
+
+[[:space:]]+   ;     /* whitespace */
+
+%{
+    /* anything else */
+    /* everything should have been handled by now, so this rule is disabled */
+%}
+
+%{
+#if 0
+.      { yyerror("invalid character"); }
+#endif
+%}
+
+%%
+
+int
+process_line(
+    char *     line)
+{
+    YY_BUFFER_STATE b;
+    int result;
+
+    b = yy_scan_string(line);          /* tell lex to scan lineread */
+    result = yyparse();                        /* parse lineread and act */
+    yy_delete_buffer(b);
+    return result;
+}
+
+static int
+ll_parse_date(
+    int                type,
+    char *     text)
+{
+    time_t now;
+    struct tm *t;
+    int y=2000, m=0, d=1, h=0, mi=0, s=0;
+    int ret;
+
+    now = time((time_t *)NULL);
+    t = localtime(&now);
+    if (t) {
+       y = 1900+t->tm_year;
+       m = t->tm_mon+1;
+       d = t->tm_mday;
+    }
+    switch(type) {
+    case 1:
+       if (sscanf(text, "---%d", &d) != 1) {
+           yyerror("invalid date");
+        }
+        break;
+    case 2:
+       if (sscanf(text, "--%d-%d", &m, &d) != 2) {
+           yyerror("invalid date");
+        }
+        break;
+    case 3:
+       if (sscanf(text, "%d-%d-%d", &y, &m, &d) != 3) {
+           yyerror("invalid date");        
+        }
+        break;
+    case 4:
+       if (sscanf(text, "%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi, &s) != 6) {
+           yyerror("invalid date");
+       }
+        break;
+    case 5:
+       if (sscanf(text, "%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi) != 5) {
+           yyerror("invalid date");
+       }
+        break;
+    }
+
+    ret = PATH;                                /* cause a parse error */
+    if(y < 70) {
+       y += 2000;
+    } else if(y < 100) {
+       y += 1900;
+    }
+    if(y < 1000 || y > 9999) {
+       yyerror("invalid year");
+    } else if(m < 1 || m > 12) {
+       yyerror("invalid month");
+    } else if(d < 1 || d > 31) {
+       yyerror("invalid day");
+    } else if(h < 0 || h > 24) {
+       yyerror("invalid hour");
+    } else if(mi < 0 || mi > 59) {
+       yyerror("invalid minute");
+    } else if(s < 0 || s > 59) {
+       yyerror("invalid second");
+    } else if(type < 4) {
+       yylval.strval = alloc(DATE_ALLOC_SIZE);
+       snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
+       ret = DATE;
+    } else {
+       yylval.strval = alloc(DATE_ALLOC_SIZE);
+       snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d-%02d-%02d-%02d", y, m, d, h, mi, s);
+       ret = DATE;
+    }
+    return ret;
+}
+
+int
+yywrap(void)
+{
+  return 1;
+}
index 364f6dedbc6b784b8e52cab24657060f6fff4f35..2dfe457161560535b710dfed0b226f3b8fef33f2 100644 (file)
@@ -2,8 +2,10 @@
 
 INCLUDES =     -I$(top_builddir)/common-src \
                -I$(top_srcdir)/common-src   \
-               -I$(top_srcdir)/client-src   \
-               -I$(top_srcdir)/tape-src
+               -I$(top_srcdir)/client-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
 
 LIB_EXTENSION = la
 
@@ -22,22 +24,31 @@ endif
 
 LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
        @LEXLIB@ \
-       ../client-src/libamclient.$(LIB_EXTENSION)
-if WANT_SERVER
-LDADD += ../tape-src/libamtape.$(LIB_EXTENSION)
-endif
-LDADD += ../common-src/libamanda.$(LIB_EXTENSION) \
+       ../client-src/libamclient.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION) \
        $(READLINE_LIBS)
 
-amrecover_SOURCES =    amrecover.c                                     \
+amrecover_CSRC =       amrecover.c                                     \
                        display_commands.c              extract_list.c  \
-                       help.c                          set_commands.c  \
-                       uparse.y                        uscan.l
+                       help.c                          set_commands.c
+
+amrecover_SOURCES =    $(amrecover_CSRC)       uparse.y        uscan.l
 
 noinst_HEADERS =       amrecover.h uparse.h
 
 AM_YFLAGS =            -d
 
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+
+uscan.$(OBJEXT): $(srcdir)/uscan.c
+       $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+uparse.$(OBJEXT): $(srcdir)/uparse.c
+       $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+
 install-exec-hook:
        @list="$(sbin_PROGRAMS)"; \
        for p in $$list; do \
@@ -50,6 +61,17 @@ install-exec-hook:
                chmod o-rwx $$pa; \
        done
 
-# so that uscan.c is never generated before uparse.h
-# otherwise we might have makedepend problems
-uscan.c: uparse.h
+
+lint:
+       @f="$(amrecover_CSRC)";                                                 \
+       (cd ../common-src; make listlibsrc);                                    \
+       f="$$f "`cat ../common-src/listlibsrc.output`;                          \
+       (cd ../server-src; make listlibsrc);                                    \
+       f="$$f "`cat ../server-src/listlibsrc.output`;                          \
+       echo $(LINT) $$f;                                                       \
+       $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $$f;\
+       if [ $$? -ne 0 ]; then                                                  \
+           exit 1;                                                             \
+       fi;                                                                     \
+        exit 0
+
index 3475161df1ce3395a4dce33e2642de31eadeb49c..c253cd0d99949d994e79d433df0f2a75c19f8eaa 100644 (file)
@@ -41,7 +41,6 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 sbin_PROGRAMS = amrecover$(EXEEXT)
-@WANT_SERVER_TRUE@am__append_1 = ../tape-src/libamtape.$(LIB_EXTENSION)
 subdir = recover-src
 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
        $(srcdir)/Makefile.in uparse.c uparse.h uscan.c
@@ -56,18 +55,16 @@ CONFIG_CLEAN_FILES =
 am__installdirs = "$(DESTDIR)$(sbindir)"
 sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(sbin_PROGRAMS)
-am_amrecover_OBJECTS = amrecover.$(OBJEXT) display_commands.$(OBJEXT) \
-       extract_list.$(OBJEXT) help.$(OBJEXT) set_commands.$(OBJEXT) \
-       uparse.$(OBJEXT) uscan.$(OBJEXT)
+am__objects_1 = amrecover.$(OBJEXT) display_commands.$(OBJEXT) \
+       extract_list.$(OBJEXT) help.$(OBJEXT) set_commands.$(OBJEXT)
+am_amrecover_OBJECTS = $(am__objects_1) uparse.$(OBJEXT) \
+       uscan.$(OBJEXT)
 amrecover_OBJECTS = $(am_amrecover_OBJECTS)
 amrecover_LDADD = $(LDADD)
-@WANT_SERVER_TRUE@am__DEPENDENCIES_1 =  \
-@WANT_SERVER_TRUE@     ../tape-src/libamtape.$(LIB_EXTENSION)
-am__DEPENDENCIES_2 =
+am__DEPENDENCIES_1 =
 amrecover_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../client-src/libamclient.$(LIB_EXTENSION) \
-       $(am__DEPENDENCIES_1) ../common-src/libamanda.$(LIB_EXTENSION) \
-       $(am__DEPENDENCIES_2)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
 am__depfiles_maybe = depfiles
@@ -97,11 +94,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -109,6 +109,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -291,9 +293,10 @@ target_os = @target_os@
 target_vendor = @target_vendor@
 INCLUDES = -I$(top_builddir)/common-src \
                -I$(top_srcdir)/common-src   \
-               -I$(top_srcdir)/client-src   \
-               -I$(top_srcdir)/tape-src
+               -I$(top_srcdir)/client-src
 
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
 LIB_EXTENSION = la
 @WANT_RUNTIME_PSEUDO_RELOC_TRUE@AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
 
@@ -303,14 +306,17 @@ LIB_EXTENSION = la
 # need to list libamanda twice here, first to override the system library
 # routines, and second to pick up any references in the other libraries.
 ###
-LDADD = ../common-src/libamanda.$(LIB_EXTENSION) @LEXLIB@ \
-       ../client-src/libamclient.$(LIB_EXTENSION) $(am__append_1) \
-       ../common-src/libamanda.$(LIB_EXTENSION) $(READLINE_LIBS)
-amrecover_SOURCES = amrecover.c                                        \
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+       @LEXLIB@ \
+       ../client-src/libamclient.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION) \
+       $(READLINE_LIBS)
+
+amrecover_CSRC = amrecover.c                                   \
                        display_commands.c              extract_list.c  \
-                       help.c                          set_commands.c  \
-                       uparse.y                        uscan.l
+                       help.c                          set_commands.c
 
+amrecover_SOURCES = $(amrecover_CSRC)  uparse.y        uscan.l
 noinst_HEADERS = amrecover.h uparse.h
 AM_YFLAGS = -d
 all: all-am
@@ -630,6 +636,16 @@ uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
        uninstall-sbinPROGRAMS
 
 
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+
+uscan.$(OBJEXT): $(srcdir)/uscan.c
+       $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+uparse.$(OBJEXT): $(srcdir)/uparse.c
+       $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
 install-exec-hook:
        @list="$(sbin_PROGRAMS)"; \
        for p in $$list; do \
@@ -642,9 +658,18 @@ install-exec-hook:
                chmod o-rwx $$pa; \
        done
 
-# so that uscan.c is never generated before uparse.h
-# otherwise we might have makedepend problems
-uscan.c: uparse.h
+lint:
+       @f="$(amrecover_CSRC)";                                                 \
+       (cd ../common-src; make listlibsrc);                                    \
+       f="$$f "`cat ../common-src/listlibsrc.output`;                          \
+       (cd ../server-src; make listlibsrc);                                    \
+       f="$$f "`cat ../server-src/listlibsrc.output`;                          \
+       echo $(LINT) $$f;                                                       \
+       $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $$f;\
+       if [ $$? -ne 0 ]; then                                                  \
+           exit 1;                                                             \
+       fi;                                                                     \
+        exit 0
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
index a4fe069f59a5a5eddca41749ce97f164481dd65b..cf21c0312ce6553b6ef790a4eac6b6820ead003e 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amrecover.c,v 1.52 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amrecover.c,v 1.73 2006/07/25 18:27:57 martinea Exp $
  *
  * an interactive program for recovering backed-up files
  */
 
 #include "amanda.h"
 #include "version.h"
-#ifdef HAVE_NETINET_IN_SYSTM_H
-#include <netinet/in_systm.h>
-#endif
-#include <netinet/in.h>
-#ifdef HAVE_NETINET_IP_H
-#include <netinet/ip.h>
-#endif
 #include "stream.h"
 #include "amfeatures.h"
 #include "amrecover.h"
 #include "getfsent.h"
 #include "dgram.h"
 #include "util.h"
+#include "clientconf.h"
+#include "protocol.h"
+#include "event.h"
+#include "security.h"
 
-#ifdef HAVE_LIBREADLINE
-#  ifdef HAVE_READLINE_READLINE_H
-#    include <readline/readline.h>
-#    ifdef HAVE_READLINE_HISTORY_H
-#      include <readline/history.h>
-#    endif
-#  else
-#    ifdef HAVE_READLINE_H
-#      include <readline.h>
-#      ifdef HAVE_HISTORY_H
-#        include <history.h>
-#      endif
-#    else
-#      undef HAVE_LIBREADLINE
-#    endif
-#  endif
-#endif
-
-extern int process_line P((char *line));
-int guess_disk P((char *cwd, size_t cwd_len, char **dn_guess, char **mpt_guess));
+extern int process_line(char *line);
+int get_line(void);
+int grab_reply(int show);
+void sigint_handler(int signum);
+int main(int argc, char **argv);
 
-#define USAGE "Usage: amrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>]\n"
+#define USAGE "Usage: amrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>] [-o <clientconfigoption>]*\n"
 
 char *config = NULL;
 char *server_name = NULL;
@@ -83,80 +65,64 @@ char *tape_server_name = NULL;
 int tape_server_socket;
 char *tape_device_name = NULL;
 am_feature_t *our_features = NULL;
+char *our_features_string = NULL;
 am_feature_t *indexsrv_features = NULL;
 am_feature_t *tapesrv_features = NULL;
-
-
-#ifndef HAVE_LIBREADLINE
-/*
- * simple readline() replacements
- */
-
-char *
-readline(prompt)
-char *prompt;
-{
-    printf("%s",prompt);
-    fflush(stdout); fflush(stderr);
-    return agets(stdin);
-}
-
-#define add_history(x)                /* add_history((x)) */
-
-#endif
-
+static char *errstr = NULL;
+char *authopt;
+int amindexd_alive = 0;
+
+static struct {
+    const char *name;
+    security_stream_t *fd;
+} streams[] = {
+#define MESGFD  0
+    { "MESG", NULL },
+};
+#define NSTREAMS        (int)(sizeof(streams) / sizeof(streams[0]))
+
+static void amindexd_response(void *, pkt_t *, security_handle_t *);
+void stop_amindexd(void);
+char *amindexd_client_get_security_conf(char *, void *);
+
+static char* mesg_buffer = NULL;
 /* gets a "line" from server and put in server_line */
 /* server_line is terminated with \0, \r\n is striped */
 /* returns -1 if error */
 
-int get_line ()
+int
+get_line(void)
 {
-    char *line = NULL;
-    char *part = NULL;
-    size_t len;
-
-    while(1) {
-       if((part = areads(server_socket)) == NULL) {
-           int save_errno = errno;
-
-           if(server_line) {
-               fputs(server_line, stderr);     /* show the last line read */
-               fputc('\n', stderr);
-           }
-           if(save_errno != 0) {
-               fprintf(stderr, "%s: Error reading line from server: %s\n",
-                               get_pname(),
-                               strerror(save_errno));
-           } else {
-               fprintf(stderr, "%s: Unexpected end of file, check amindexd*debug on server %s\n",
-                       get_pname(),
-                       server_name);
-           }
-           amfree(line);
-           amfree(server_line);
-           errno = save_errno;
+    ssize_t size;
+    char *newbuf, *s;
+    void *buf;
+
+    if (!mesg_buffer)
+       mesg_buffer = stralloc("");
+    while (!strstr(mesg_buffer,"\r\n")) {
+       size = security_stream_read_sync(streams[MESGFD].fd, &buf);
+       if(size < 0) {
            return -1;
        }
-       if(line) {
-           strappend(line, part);
-           amfree(part);
-       } else {
-           line = part;
-           part = NULL;
-       }
-       if((len = strlen(line)) > 0 && line[len-1] == '\r') {
-           line[len-1] = '\0';
-           server_line = newstralloc(server_line, line);
-           amfree(line);
-           return 0;
+       else if(size == 0) {
+           return -1;
        }
-       /*
-        * Hmmm.  We got a "line" from areads(), which means it saw
-        * a '\n' (or EOF, etc), but there was not a '\r' before it.
-        * Put a '\n' back in the buffer and loop for more.
-        */
-       strappend(line, "\n");
+       newbuf = alloc(strlen(mesg_buffer)+size+1);
+       strncpy(newbuf, mesg_buffer, (size_t)(strlen(mesg_buffer) + size));
+       memcpy(newbuf+strlen(mesg_buffer), buf, (size_t)size);
+       newbuf[strlen(mesg_buffer)+size] = '\0';
+       amfree(mesg_buffer);
+       mesg_buffer = newbuf;
     }
+
+    s = strstr(mesg_buffer,"\r\n");
+    *s = '\0';
+    newbuf = stralloc(s+2);
+    server_line = newstralloc(server_line, mesg_buffer);
+    amfree(mesg_buffer);
+    mesg_buffer = newbuf;
+    return 0;
 }
 
 
@@ -165,8 +131,9 @@ int get_line ()
 /* return -1 if error */
 /* return code returned by server always occupies first 3 bytes of global
    variable server_line */
-int grab_reply (show)
-int show;
+int
+grab_reply(
+    int show)
 {
     do {
        if (get_line() == -1) {
@@ -182,7 +149,8 @@ int show;
 
 /* get 1 line of reply */
 /* returns -1 if error, 0 if last (or only) line, 1 if more to follow */
-int get_reply_line ()
+int
+get_reply_line(void)
 {
     if (get_line() == -1)
        return -1;
@@ -191,7 +159,8 @@ int get_reply_line ()
 
 
 /* returns pointer to returned line */
-char *reply_line ()
+char *
+reply_line(void)
 {
     return server_line;
 }
@@ -200,14 +169,16 @@ char *reply_line ()
 
 /* returns 0 if server returned an error code (ie code starting with 5)
    and non-zero otherwise */
-int server_happy ()
+int
+server_happy(void)
 {
     return server_line[0] != '5';
 }
 
 
-int send_command(cmd)
-char *cmd;
+int
+send_command(
+    char *     cmd)
 {
     /*
      * NOTE: this routine is called from sigint_handler, so we must be
@@ -215,25 +186,26 @@ char *cmd;
      * our state at the time the interrupt happened.  For instance,
      * do not use any stdio or malloc routines here.
      */
-    struct iovec msg[2];
-    ssize_t bytes;
+    char *buffer;
 
-    msg[0].iov_base = cmd;
-    msg[0].iov_len = strlen(msg[0].iov_base);
-    msg[1].iov_base = "\r\n";
-    msg[1].iov_len = strlen(msg[1].iov_base);
-    bytes = msg[0].iov_len + msg[1].iov_len;
+    buffer = alloc(strlen(cmd)+3);
+    strncpy(buffer, cmd, strlen(cmd));
+    buffer[strlen(cmd)] = '\r';
+    buffer[strlen(cmd)+1] = '\n';
+    buffer[strlen(cmd)+2] = '\0';
 
-    if (writev(server_socket, msg, 2) < bytes) {
+    if(security_stream_write(streams[MESGFD].fd, buffer, strlen(buffer)) < 0) {
        return -1;
     }
+    amfree(buffer);
     return (0);
 }
 
 
 /* send a command to the server, get reply and print to screen */
-int converse(cmd)
-char *cmd;
+int
+converse(
+    char *     cmd)
 {
     if (send_command(cmd) == -1) return -1;
     if (grab_reply(1) == -1) return -1;
@@ -242,8 +214,9 @@ char *cmd;
 
 
 /* same as converse() but reply not echoed to stdout */
-int exchange(cmd)
-char *cmd;
+int
+exchange(
+    char *     cmd)
 {
     if (send_command(cmd) == -1) return -1;
     if (grab_reply(0) == -1) return -1;
@@ -253,8 +226,9 @@ char *cmd;
 
 /* basic interrupt handler for when user presses ^C */
 /* Bale out, letting server know before doing so */
-void sigint_handler(signum)
-int signum;
+void
+sigint_handler(
+    int        signum)
 {
     /*
      * NOTE: we must be **very** careful about what we do here since there
@@ -263,17 +237,22 @@ int signum;
      * routines.  Also, use _exit() instead of exit() to make sure stdio
      * buffer flushing is not attempted.
      */
+    (void)signum;      /* Quiet unused parameter warning */
+
     if (extract_restore_child_pid != -1)
        (void)kill(extract_restore_child_pid, SIGKILL);
     extract_restore_child_pid = -1;
 
-    (void)send_command("QUIT");
+    if(amindexd_alive) 
+       (void)send_command("QUIT");
+
     _exit(1);
 }
 
 
-void clean_pathname(s)
-char *s;
+void
+clean_pathname(
+    char *     s)
 {
     size_t length;
     length = strlen(s);
@@ -292,132 +271,41 @@ char *s;
 }
 
 
-/* try and guess the disk the user is currently on.
-   Return -1 if error, 0 if disk not local, 1 if disk local,
-   2 if disk local but can't guess name */
-/* do this by looking for the longest mount point which matches the
-   current directory */
-int guess_disk (cwd, cwd_len, dn_guess, mpt_guess)
-     char *cwd, **dn_guess, **mpt_guess;
-     size_t cwd_len;
-{
-    size_t longest_match = 0;
-    size_t current_length;
-    size_t cwd_length;
-    int local_disk = 0;
-    generic_fsent_t fsent;
-    char *fsname = NULL;
-    char *disk_try = NULL;
-
-    *dn_guess = *mpt_guess = NULL;
-
-    if (getcwd(cwd, cwd_len) == NULL)
-       return -1;
-    cwd_length = strlen(cwd);
-    dbprintf(("guess_disk: %d: \"%s\"\n", cwd_length, cwd));
-
-    if (open_fstab() == 0)
-       return -1;
-
-    while (get_fstab_nextentry(&fsent))
-    {
-       current_length = fsent.mntdir ? strlen(fsent.mntdir) : (size_t)0;
-       dbprintf(("guess_disk: %d: %d: \"%s\": \"%s\"\n",
-                 longest_match,
-                 current_length,
-                 fsent.mntdir ? fsent.mntdir : "(mntdir null)",
-                 fsent.fsname ? fsent.fsname : "(fsname null)"));
-       if ((current_length > longest_match)
-           && (current_length <= cwd_length)
-           && (strncmp(fsent.mntdir, cwd, current_length) == 0))
-       {
-           longest_match = current_length;
-           amfree(*mpt_guess);
-           *mpt_guess = stralloc(fsent.mntdir);
-           if(strncmp(fsent.fsname,DEV_PREFIX,(strlen(DEV_PREFIX))))
-           {
-               fsname = newstralloc(fsname, fsent.fsname);
-            }
-           else
-           {
-               fsname = newstralloc(fsname,fsent.fsname+strlen(DEV_PREFIX));
-           }
-           local_disk = is_local_fstype(&fsent);
-           dbprintf(("guess_disk: local_disk = %d, fsname = \"%s\"\n",
-                     local_disk,
-                     fsname));
-       }
-    }
-    close_fstab();
-
-    if (longest_match == 0) {
-       amfree(*mpt_guess);
-       amfree(fsname);
-       return -1;                      /* ? at least / should match */
-    }
-
-    if (!local_disk) {
-       amfree(*mpt_guess);
-       amfree(fsname);
-       return 0;
-    }
-
-    /* have mount point now */
-    /* disk name may be specified by mount point (logical name) or
-       device name, have to determine */
-    printf("Trying disk %s ...\n", *mpt_guess);
-    disk_try = stralloc2("DISK ", *mpt_guess);         /* try logical name */
-    if (exchange(disk_try) == -1)
-       exit(1);
-    amfree(disk_try);
-    if (server_happy())
-    {
-       *dn_guess = stralloc(*mpt_guess);               /* logical is okay */
-       amfree(fsname);
-       return 1;
-    }
-    printf("Trying disk %s ...\n", fsname);
-    disk_try = stralloc2("DISK ", fsname);             /* try device name */
-    if (exchange(disk_try) == -1)
-       exit(1);
-    amfree(disk_try);
-    if (server_happy())
-    {
-       *dn_guess = stralloc(fsname);                   /* dev name is okay */
-       amfree(fsname);
-       return 1;
-    }
-
-    /* neither is okay */
-    amfree(*mpt_guess);
-    amfree(fsname);
-    return 2;
-}
-
-
-void quit ()
+void
+quit(void)
 {
     quit_prog = 1;
     (void)converse("QUIT");
+    stop_amindexd();
 }
 
 char *localhost = NULL;
 
-int main(argc, argv)
-int argc;
-char **argv;
+#ifdef DEFAULT_TAPE_SERVER
+# define DEFAULT_TAPE_SERVER_FAILOVER (DEFAULT_TAPE_SERVER)
+#else
+# define DEFAULT_TAPE_SERVER_FAILOVER (NULL)
+#endif
+
+int
+main(
+    int                argc,
+    char **    argv)
 {
-    int my_port;
-    struct servent *sp;
     int i;
     time_t timer;
     char *lineread = NULL;
     struct sigaction act, oact;
     extern char *optarg;
     extern int optind;
-    char cwd[STR_SIZE], *dn_guess = NULL, *mpt_guess = NULL;
-    char *service_name;
     char *line = NULL;
+    char *conffile;
+    const security_driver_t *secdrv;
+    char *req = NULL;
+    int response_error;
+    int new_argc;
+    char **new_argv;
+    struct tm *tm;
 
     safe_fd(-1, 0);
 
@@ -426,66 +314,64 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-    dbopen();
+    dbopen(DBG_SUBDIR_CLIENT);
 
 #ifndef IGNORE_UID_CHECK
     if (geteuid() != 0) {
        erroutput_type |= ERR_SYSLOG;
        error("amrecover must be run by root");
+       /*NOTREACHED*/
     }
 #endif
 
     localhost = alloc(MAX_HOSTNAME_LENGTH+1);
     if (gethostname(localhost, MAX_HOSTNAME_LENGTH) != 0) {
        error("cannot determine local host name\n");
+       /*NOTREACHED*/
     }
     localhost[MAX_HOSTNAME_LENGTH] = '\0';
 
-    config = newstralloc(config, DEFAULT_CONFIG);
-    server_name = newstralloc(server_name, DEFAULT_SERVER);
-#ifdef DEFAULT_TAPE_SERVER
-    tape_server_name = newstralloc(tape_server_name, DEFAULT_TAPE_SERVER);
-#else
-    amfree(tape_server_name);
-#endif
-    if (argc > 1 && argv[1][0] != '-')
-    {
+    parse_client_conf(argc, argv, &new_argc, &new_argv);
+
+    if (new_argc > 1 && new_argv[1][0] != '-') {
        /*
         * If the first argument is not an option flag, then we assume
         * it is a configuration name to match the syntax of the other
         * Amanda utilities.
         */
-       char **new_argv;
+       char **new_argv1;
 
-       new_argv = (char **) alloc ((argc + 1 + 1) * sizeof (*new_argv));
-       new_argv[0] = argv[0];
-       new_argv[1] = "-C";
-       for (i = 1; i < argc; i++)
-       {
-           new_argv[i + 1] = argv[i];
+       new_argv1 = (char **) alloc((size_t)((new_argc + 1 + 1) * sizeof(*new_argv1)));
+       new_argv1[0] = new_argv[0];
+       new_argv1[1] = "-C";
+       for (i = 1; i < new_argc; i++) {
+           new_argv1[i + 1] = new_argv[i];
        }
-       new_argv[i + 1] = NULL;
-       argc++;
-       argv = new_argv;
+       new_argv1[i + 1] = NULL;
+       new_argc++;
+       amfree(new_argv);
+       new_argv = new_argv1;
     }
-    while ((i = getopt(argc, argv, "C:s:t:d:U")) != EOF)
-    {
-       switch (i)
-       {
+    while ((i = getopt(new_argc, new_argv, "C:s:t:d:U")) != EOF) {
+       switch (i) {
            case 'C':
-               config = newstralloc(config, optarg);
+               add_client_conf(CLN_CONF, optarg);
+               //config = newstralloc(config, optarg);
                break;
 
            case 's':
-               server_name = newstralloc(server_name, optarg);
+               add_client_conf(CLN_INDEX_SERVER, optarg);
+               //server_name = newstralloc(server_name, optarg);
                break;
 
            case 't':
-               tape_server_name = newstralloc(tape_server_name, optarg);
+               add_client_conf(CLN_TAPE_SERVER, optarg);
+               //tape_server_name = newstralloc(tape_server_name, optarg);
                break;
 
            case 'd':
-               tape_device_name = newstralloc(tape_device_name, optarg);
+               add_client_conf(CLN_TAPEDEV, optarg);
+               //tape_device_name = newstralloc(tape_device_name, optarg);
                break;
 
            case 'U':
@@ -494,12 +380,53 @@ char **argv;
                return 0;
        }
     }
-    if (optind != argc)
-    {
+    if (optind != new_argc) {
        (void)fprintf(stderr, USAGE);
        exit(1);
     }
 
+    our_features = am_init_feature_set();
+    our_features_string = am_feature_to_string(our_features);
+
+    conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+    if (read_clientconf(conffile) > 0) {
+       error("error reading conffile: %s", conffile);
+       /*NOTREACHED*/
+    }
+    amfree(conffile);
+
+    config = stralloc(client_getconf_str(CLN_CONF));
+
+    conffile = vstralloc(CONFIG_DIR, "/", config, "/", "amanda-client.conf",
+                        NULL);
+    if (read_clientconf(conffile) > 0) {
+       error("error reading conffile: %s", conffile);
+       /*NOTREACHED*/
+    }
+    amfree(conffile);
+
+    dbrename(config, DBG_SUBDIR_CLIENT);
+
+    report_bad_client_arg();
+
+    amfree(server_name);
+    server_name = getenv("AMANDA_SERVER");
+    if(!server_name) server_name = client_getconf_str(CLN_INDEX_SERVER);
+    server_name = stralloc(server_name);
+
+    amfree(tape_server_name);
+    tape_server_name = getenv("AMANDA_TAPESERVER");
+    if(!tape_server_name) tape_server_name = client_getconf_str(CLN_TAPE_SERVER);
+    tape_server_name = stralloc(tape_server_name);
+
+    amfree(tape_device_name);
+    tape_device_name = client_getconf_str(CLN_TAPEDEV);
+    if (tape_device_name)
+       tape_device_name = stralloc(tape_device_name);
+
+    authopt = stralloc(client_getconf_str(CLN_AUTH));
+
+
     amfree(disk_name);
     amfree(mount_point);
     amfree(disk_path);
@@ -512,33 +439,40 @@ char **argv;
     act.sa_handler = sigint_handler;
     sigemptyset(&act.sa_mask);
     act.sa_flags = 0;
-    if (sigaction(SIGINT, &act, &oact) != 0)
-    {
+    if (sigaction(SIGINT, &act, &oact) != 0) {
        error("error setting signal handler: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 
-    service_name = stralloc2("amandaidx", SERVICE_SUFFIX);
+    protocol_init();
+
+    /* We assume that amindexd support fe_amindexd_options_features */
+    /*                             and fe_amindexd_options_auth     */
+    /* We should send a noop to really know                         */
+    req = vstralloc("SERVICE amindexd\n",
+                   "OPTIONS ", "features=", our_features_string, ";",
+                               "auth=", authopt, ";",
+                   "\n", NULL);
+
+    secdrv = security_getdriver(authopt);
+    if (secdrv == NULL) {
+       error("no '%s' security driver available for host '%s'",
+           authopt, server_name);
+       /*NOTREACHED*/
+    }
+
+    protocol_sendreq(server_name, secdrv, amindexd_client_get_security_conf,
+                    req, STARTUP_TIMEOUT, amindexd_response, &response_error);
+
+    amfree(req);
+    protocol_run();
 
     printf("AMRECOVER Version %s. Contacting server on %s ...\n",
-          version(), server_name);  
-    if ((sp = getservbyname(service_name, "tcp")) == NULL)
-    {
-       error("%s/tcp unknown protocol", service_name);
-    }
-    amfree(service_name);
-    server_socket = stream_client_privileged(server_name,
-                                            ntohs(sp->s_port),
-                                            -1,
-                                            -1,
-                                            &my_port,
-                                            0);
-    if (server_socket < 0)
-    {
-       error("cannot connect to %s: %s", server_name, strerror(errno));
-    }
-    if (my_port >= IPPORT_RESERVED)
-    {
-       error("did not get a reserved port: %d", my_port);
+          version(), server_name);
+
+    if(response_error != 0) {
+       fprintf(stderr,"%s\n",errstr);
+       exit(1);
     }
 
 #if 0
@@ -552,32 +486,21 @@ char **argv;
 #endif
 
     /* get server's banner */
-    if (grab_reply(1) == -1)
+    if (grab_reply(1) == -1) {
+        aclose(server_socket);
        exit(1);
-    if (!server_happy())
-    {
+    }
+    if (!server_happy()) {
        dbclose();
        aclose(server_socket);
        exit(1);
     }
 
-    /* do the security thing */
-    line = get_security();
-    if (converse(line) == -1)
-       exit(1);
-    if (!server_happy())
-       exit(1);
-    memset(line, '\0', strlen(line));
-    amfree(line);
-
     /* try to get the features from the server */
     {
-       char *our_feature_string = NULL;
        char *their_feature_string = NULL;
 
-       our_features = am_init_feature_set();
-       our_feature_string = am_feature_to_string(our_features);
-       line = stralloc2("FEATURES ", our_feature_string);
+       line = stralloc2("FEATURES ", our_features_string);
        if(exchange(line) == 0) {
            their_feature_string = stralloc(server_line+13);
            indexsrv_features = am_string_to_feature(their_feature_string);
@@ -585,70 +508,46 @@ char **argv;
        else {
            indexsrv_features = am_set_default_feature_set();
         }
-       amfree(our_feature_string);
        amfree(their_feature_string);
        amfree(line);
     }
 
     /* set the date of extraction to be today */
     (void)time(&timer);
-    strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", localtime(&timer));
+    tm = localtime(&timer);
+    if (tm) 
+       strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", tm);
+    else
+       error("BAD DATE");
+
     printf("Setting restore date to today (%s)\n", dump_date);
     line = stralloc2("DATE ", dump_date);
-    if (converse(line) == -1)
+    if (converse(line) == -1) {
+        aclose(server_socket);
        exit(1);
+    }
     amfree(line);
 
     line = stralloc2("SCNF ", config);
-    if (converse(line) == -1)
+    if (converse(line) == -1) {
+        aclose(server_socket);
        exit(1);
+    }
     amfree(line);
 
-    if (server_happy())
-    {
+    if (server_happy()) {
        /* set host we are restoring to this host by default */
        amfree(dump_hostname);
        set_host(localhost);
        if (dump_hostname)
-       {
-            /* get a starting disk and directory based on where
-              we currently are */
-           switch (guess_disk(cwd, sizeof(cwd), &dn_guess, &mpt_guess))
-           {
-               case 1:
-                   /* okay, got a guess. Set disk accordingly */
-                   printf("$CWD '%s' is on disk '%s' mounted at '%s'.\n",
-                          cwd, dn_guess, mpt_guess);
-                   set_disk(dn_guess, mpt_guess);
-                   set_directory(cwd);
-                   if (server_happy() && strcmp(cwd, mpt_guess) != 0)
-                       printf("WARNING: not on root of selected filesystem, check man-page!\n");
-                   amfree(dn_guess);
-                   amfree(mpt_guess);
-                   break;
-
-               case 0:
-                   printf("$CWD '%s' is on a network mounted disk\n",
-                          cwd);
-                   printf("so you must 'sethost' to the server\n");
-                   /* fake an unhappy server */
-                   server_line[0] = '5';
-                   break;
-
-               case 2:
-               case -1:
-               default:
-                   printf("Can't determine disk and mount point from $CWD '%s'\n", cwd);
-                   /* fake an unhappy server */
-                   server_line[0] = '5';
-                   break;
-           }
-       }
+           printf("Use the setdisk command to choose dump disk to recover\n");
+       else
+           printf("Use the sethost command to choose a host to recover\n");
+
     }
 
     quit_prog = 0;
-    do
-    {
+    do {
        if ((lineread = readline("amrecover> ")) == NULL) {
            clearerr(stdin);
            putchar('\n');
@@ -668,12 +567,245 @@ char **argv;
     return 0;
 }
 
+static void
+amindexd_response(
+    void *datap,
+    pkt_t *pkt,
+    security_handle_t *sech)
+{
+    int ports[NSTREAMS], *response_error = datap, i;
+    char *p;
+    char *tok;
+    char *extra = NULL;
+
+    assert(response_error != NULL);
+    assert(sech != NULL);
+
+    if (pkt == NULL) {
+       errstr = newvstralloc(errstr, "[request failed: ",
+                            security_geterror(sech), "]", NULL);
+       *response_error = 1;
+       return;
+    }
+
+    if (pkt->type == P_NAK) {
+#if defined(PACKET_DEBUG)
+       fprintf(stderr, "got nak response:\n----\n%s\n----\n\n", pkt->body);
+#endif
+
+       tok = strtok(pkt->body, " ");
+       if (tok == NULL || strcmp(tok, "ERROR") != 0)
+           goto bad_nak;
+
+       tok = strtok(NULL, "\n");
+       if (tok != NULL) {
+           errstr = newvstralloc(errstr, "NAK: ", tok, NULL);
+           *response_error = 1;
+       } else {
+bad_nak:
+           errstr = newstralloc(errstr, "request NAK");
+           *response_error = 2;
+       }
+       return;
+    }
+
+    if (pkt->type != P_REP) {
+       errstr = newvstralloc(errstr, "received strange packet type ",
+                             pkt_type2str(pkt->type), ": ", pkt->body, NULL);
+       *response_error = 1;
+       return;
+    }
+
+#if defined(PACKET_DEBUG)
+    fprintf(stderr, "got response:\n----\n%s\n----\n\n", pkt->body);
+#endif
+
+    for(i = 0; i < NSTREAMS; i++) {
+        ports[i] = -1;
+        streams[i].fd = NULL;
+    }
+
+    p = pkt->body;
+    while((tok = strtok(p, " \n")) != NULL) {
+       p = NULL;
+
+       /*
+        * Error response packets have "ERROR" followed by the error message
+        * followed by a newline.
+        */
+       if (strcmp(tok, "ERROR") == 0) {
+           tok = strtok(NULL, "\n");
+           if (tok == NULL)
+               tok = "[bogus error packet]";
+           errstr = newstralloc(errstr, tok);
+           *response_error = 2;
+           return;
+       }
+
+
+        /*
+         * Regular packets have CONNECT followed by three streams
+         */
+        if (strcmp(tok, "CONNECT") == 0) {
+
+           /*
+            * Parse the three stream specifiers out of the packet.
+            */
+           for (i = 0; i < NSTREAMS; i++) {
+               tok = strtok(NULL, " ");
+               if (tok == NULL || strcmp(tok, streams[i].name) != 0) {
+                   extra = vstralloc("CONNECT token is \"",
+                                     tok ? tok : "(null)",
+                                     "\": expected \"",
+                                     streams[i].name,
+                                     "\"",
+                                     NULL);
+                   goto parse_error;
+               }
+               tok = strtok(NULL, " \n");
+               if (tok == NULL || sscanf(tok, "%d", &ports[i]) != 1) {
+                   extra = vstralloc("CONNECT ",
+                                     streams[i].name,
+                                     " token is \"",
+                                     tok ? tok : "(null)",
+                                     "\": expected a port number",
+                                     NULL);
+                   goto parse_error;
+               }
+           }
+           continue;
+       }
+
+       /*
+        * OPTIONS [options string] '\n'
+        */
+       if (strcmp(tok, "OPTIONS") == 0) {
+           tok = strtok(NULL, "\n");
+           if (tok == NULL) {
+               extra = stralloc("OPTIONS token is missing");
+               goto parse_error;
+           }
+/*
+           tok_end = tok + strlen(tok);
+           while((p = strchr(tok, ';')) != NULL) {
+               *p++ = '\0';
+#define sc "features="
+               if(strncmp(tok, sc, sizeof(sc)-1) == 0) {
+                   tok += sizeof(sc) - 1;
+#undef sc
+                   am_release_feature_set(their_features);
+                   if((their_features = am_string_to_feature(tok)) == NULL) {
+                       errstr = newvstralloc(errstr,
+                                             "OPTIONS: bad features value: ",
+                                             tok,
+                                             NULL);
+                       goto parse_error;
+                   }
+               }
+               tok = p;
+           }
+*/
+           continue;
+       }
+/*
+       extra = vstralloc("next token is \"",
+                         tok ? tok : "(null)",
+                         "\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\"",
+                         NULL);
+       goto parse_error;
+*/
+    }
+
+    /*
+     * Connect the streams to their remote ports
+     */
+    for (i = 0; i < NSTREAMS; i++) {
+/*@i@*/        if (ports[i] == -1)
+           continue;
+       streams[i].fd = security_stream_client(sech, ports[i]);
+       if (streams[i].fd == NULL) {
+           errstr = newvstralloc(errstr,
+                       "[could not connect ", streams[i].name, " stream: ",
+                       security_geterror(sech), "]", NULL);
+           goto connect_error;
+       }
+    }
+    /*
+     * Authenticate the streams
+     */
+    for (i = 0; i < NSTREAMS; i++) {
+       if (streams[i].fd == NULL)
+           continue;
+       if (security_stream_auth(streams[i].fd) < 0) {
+           errstr = newvstralloc(errstr,
+               "[could not authenticate ", streams[i].name, " stream: ",
+               security_stream_geterror(streams[i].fd), "]", NULL);
+           goto connect_error;
+       }
+    }
+
+    /*
+     * The MESGFD and DATAFD streams are mandatory.  If we didn't get
+     * them, complain.
+     */
+    if (streams[MESGFD].fd == NULL) {
+        errstr = newstralloc(errstr, "[couldn't open MESG streams]");
+        goto connect_error;
+    }
+
+    /* everything worked */
+    *response_error = 0;
+    amindexd_alive = 1;
+    return;
+
+parse_error:
+    errstr = newvstralloc(errstr,
+                         "[parse of reply message failed: ",
+                         extra ? extra : "(no additional information)",
+                         "]",
+                         NULL);
+    amfree(extra);
+    *response_error = 2;
+    return;
+
+connect_error:
+    stop_amindexd();
+    *response_error = 1;
+}
+
+/*
+ * This is called when everything needs to shut down so event_loop()
+ * will exit.
+ */
+void
+stop_amindexd(void)
+{
+    int i;
+
+    amindexd_alive = 0;
+    for (i = 0; i < NSTREAMS; i++) {
+        if (streams[i].fd != NULL) {
+            security_stream_close(streams[i].fd);
+            streams[i].fd = NULL;
+        }
+    }
+}
+
 char *
-get_security()
+amindexd_client_get_security_conf(
+    char *     string,
+    void *     arg)
 {
-    struct passwd *pwptr;
+    (void)arg; /* Quiet unused parameter warning */
+
+    if(!string || !*string)
+       return(NULL);
 
-    if((pwptr = getpwuid(getuid())) == NULL)
-       error("can't get login name for my uid %ld", (long)getuid());
-    return stralloc2("SECURITY USER ", pwptr->pw_name);
+    if(strcmp(string, "auth")==0) {
+       return(client_getconf_str(CLN_AUTH));
+    }
+    else if(strcmp(string, "ssh_keys")==0) {
+       return(client_getconf_str(CLN_SSH_KEYS));
+    }
+    return(NULL);
 }
index 52c964e5e53426e2a0aa68e7f65ba514db0cc0bf..79a9a922b495196d83372d13fe22b9c6e49ef655 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amrecover.h,v 1.17 2005/12/31 00:02:10 paddy_s Exp $
+ * $Id: amrecover.h,v 1.19 2006/05/25 01:47:14 johnfranks Exp $
  *
  * data structures and declarations for amrecover
  */
 #include "amanda.h"
 #include "amfeatures.h"
 
+#define STARTUP_TIMEOUT 60
+
 typedef struct DIR_ITEM
 {
     char *date;
     int  level;
     char *tape;
     char *path;
-    int  fileno;
+    off_t  fileno;
 
     struct DIR_ITEM *next;
 }
@@ -55,59 +57,63 @@ extern char dump_date[STR_SIZE];    /* date on which we are restoring */
 extern int quit_prog;                  /* set when time to exit parser */
 extern char *tape_server_name;
 extern char *tape_device_name;
+extern char *authopt;
 extern am_feature_t *our_features;
+extern char *our_features_string;
 extern am_feature_t *indexsrv_features;
 extern am_feature_t *tapesrv_features;
 extern pid_t extract_restore_child_pid;
 
-extern void free_dir_item P((DIR_ITEM *item));
+extern void free_dir_item(DIR_ITEM *item);
 
-extern int converse P((char *cmd));
-extern int exchange P((char *cmd));
-extern int server_happy P((void));
-extern int send_command P((char *cmd));
-extern int get_reply_line P((void));
-extern char *reply_line P((void));
+extern int converse(char *cmd);
+extern int exchange(char *cmd);
+extern int server_happy(void);
+extern int send_command(char *cmd);
+extern int get_reply_line(void);
+extern char *reply_line(void);
 
-extern void quit P((void));
+extern void quit(void);
 
-extern void help_list P((void));               /* list commands */
+extern void help_list(void);           /* list commands */
 
-extern void set_disk P((char *dsk, char *mtpt));
-extern void list_disk P((char *amdevice));
-extern void set_host P((char *host));
-extern int set_date P((char *date));
-extern void set_directory P((char *dir));
-extern void cd_glob P((char *dir));
-extern void cd_regex P((char *dir));
-extern void cd_dir P((char *dir, char *default_dir));
-extern void set_tape P((char *tape));
-extern void show_directory P((void));
-extern void set_mode P((int mode));
-extern void show_mode P((void));
+extern void set_disk(char *dsk, char *mtpt);
+extern void list_disk(char *amdevice);
+extern void set_host(const char *host);
+extern void list_host(void);
+extern int set_date(char *date);
+extern void set_directory(char *dir);
+extern void cd_glob(char *dir);
+extern void cd_regex(char *dir);
+extern void cd_dir(char *dir, char *default_dir);
+extern void set_tape(char *tape);
+extern void show_directory(void);
+extern void set_mode(int mode);
+extern void show_mode(void);
 
-extern void list_disk_history P((void));
-extern void list_directory P((void));
-extern DIR_ITEM *get_dir_list P((void));
-extern DIR_ITEM *get_next_dir_item P((DIR_ITEM *this));
-extern void suck_dir_list_from_server P((void));
-extern void clear_dir_list P((void));
-extern void clean_pathname P((char *s));
-extern void display_extract_list P((char *file));
-extern void clear_extract_list P((void));
-extern int is_extract_list_nonempty P((void));
-extern void add_glob P((char *glob));
-extern void add_regex P((char *regex));
-extern void add_file P((char *path, char *regex));
-extern void delete_glob P((char *glob));
-extern void delete_regex P((char *regex));
-extern void delete_file P((char *path, char *regex));
+extern void list_disk_history(void);
+extern void list_directory(void);
+extern DIR_ITEM *get_dir_list(void);
+extern DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
+extern void suck_dir_list_from_server(void);
+extern void clear_dir_list(void);
+extern void clean_pathname(char *s);
+extern void display_extract_list(char *file);
+extern void clear_extract_list(void);
+extern int is_extract_list_nonempty(void);
+extern void add_glob(char *glob);
+extern void add_regex(char *regex);
+extern void add_file(char *path, char *regex);
+extern void delete_glob(char *glob);
+extern void delete_regex(char *regex);
+extern void delete_file(char *path, char *regex);
 
-extern void extract_files P((void));
+extern void extract_files(void);
 
 #ifdef SAMBA_CLIENT
 #define SAMBA_SMBCLIENT 0
 #define SAMBA_TAR       1
 #endif
 
-extern char *get_security P((void));
+extern char *get_security(void);
+extern void stop_amindexd(void);
index 88c0cea74846d91006cb2cb67c2e8bf15f72025d..90e181674afc385ea96f3629be90ed1b72b12927 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: display_commands.c,v 1.19 2006/03/09 20:06:11 johnfranks Exp $
+ * $Id: display_commands.c,v 1.22 2006/07/05 19:42:17 martinea Exp $
  *
  * implements the directory-display related commands in amrecover
  */
 
 #include "amanda.h"
 #include "amrecover.h"
+#include "util.h"
+
+DIR_ITEM *get_dir_list(void);
+DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
+
+void clear_dir_list(void);
+void free_dir_item(DIR_ITEM *item);
+static int add_dir_list_item(char *date,
+                               int level,
+                               char *tape,
+                               off_t fileno,
+                               char *path);
+void list_disk_history(void);
+void suck_dir_list_from_server(void);
+void list_directory(void);
 
 static DIR_ITEM *dir_list = NULL;
 
-DIR_ITEM *get_dir_list P((void))
+DIR_ITEM *
+get_dir_list(void)
 {
     return dir_list;
 }
 
-DIR_ITEM *get_next_dir_item(this)
-DIR_ITEM *this;
+DIR_ITEM *
+get_next_dir_item(
+    DIR_ITEM * this)
 {
+    /*@ignore@*/
     return this->next;
+    /*@end@*/
 }
 
 
-void clear_dir_list P((void))
+void
+clear_dir_list(void)
 {
     free_dir_item(dir_list); /* Frees all items from dir_list to end of list */
     dir_list = NULL;
 }
 
-void free_dir_item P((DIR_ITEM *item)) {
+void
+free_dir_item(
+    DIR_ITEM * item)
+{
     DIR_ITEM *next;
 
     while (item != NULL) {
@@ -66,17 +89,19 @@ void free_dir_item P((DIR_ITEM *item)) {
 }
 
 /* add item to list if path not already on list */
-static int add_dir_list_item(date, level, tape, fileno, path)
-char *date;
-int level;
-char *tape;
-int fileno;
-char *path;
+static int
+add_dir_list_item(
+    char *     date,
+    int                level,
+    char *     tape,
+    off_t      fileno,
+    char *     path)
 {
     DIR_ITEM *next;
 
-    dbprintf(("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \"%d\" \"%s\"\n",
-             date, level, tape, fileno, path));
+    dbprintf(("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \""
+             OFF_T_FMT "\" \"%s\"\n",
+             date, level, tape, (OFF_T_FMT_TYPE)fileno, path));
 
     next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
     memset(next, 0, sizeof(DIR_ITEM));
@@ -94,23 +119,26 @@ char *path;
 }
 
 
-void list_disk_history P((void))
+void
+list_disk_history(void)
 {
     if (converse("DHST") == -1)
        exit(1);
 }
 
 
-void suck_dir_list_from_server P((void))
+void
+suck_dir_list_from_server(void)
 {
     char *cmd = NULL;
     char *err = NULL;
     int i;
     char *l = NULL;
-    char *date, *date_undo, date_undo_ch = '\0';
-    int level, fileno;
+    char *date;
+    int level = 0;
+    off_t fileno = (off_t)-1;
     char *tape, *tape_undo, tape_undo_ch = '\0';
-    char *dir;
+    char *dir, *qdir;
     char *disk_path_slash = NULL;
     char *disk_path_slash_dot = NULL;
     char *s;
@@ -149,7 +177,7 @@ void suck_dir_list_from_server P((void))
     disk_path_slash_dot = stralloc2(disk_path_slash, ".");
     amfree(cmd);
     amfree(err);
-    date_undo = tape_undo = NULL;
+    tape_undo = NULL;
     /* skip the last line -- duplicate of the preamble */
     while ((i = get_reply_line()) != 0)
     {
@@ -161,7 +189,7 @@ void suck_dir_list_from_server P((void))
        if(err) {
            if(cmd == NULL) {
                if(tape_undo) *tape_undo = tape_undo_ch;
-               date_undo = tape_undo = NULL;
+               tape_undo = NULL;
                cmd = stralloc(l);      /* save for the error report */
            }
            continue;                   /* throw the rest of the lines away */
@@ -187,9 +215,7 @@ void suck_dir_list_from_server P((void))
        }
        date = s - 1;
        skip_non_whitespace(s, ch);
-       date_undo = s - 1;
-       date_undo_ch = *date_undo;
-       *date_undo = '\0';
+       *(s - 1) = '\0';
 
        skip_whitespace(s, ch);
        if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
@@ -211,14 +237,15 @@ void suck_dir_list_from_server P((void))
 
        if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_OLSD)) {
            skip_whitespace(s, ch);
-           if(ch == '\0' || sscanf(s - 1, "%d", &fileno) != 1) {
+           if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+                                   (OFF_T_FMT_TYPE *)&fileno) != 1) {
                err = "bad reply: cannot parse fileno field";
                continue;
            }
            skip_integer(s, ch);
        }
        else {
-           fileno = -1;
+           fileno = (off_t)-1;
        }
 
        skip_whitespace(s, ch);
@@ -226,13 +253,16 @@ void suck_dir_list_from_server P((void))
            err = "bad reply: missing directory field";
            continue;
        }
-       dir = s - 1;
+       qdir = s - 1;
+       dir = unquote_string(qdir);
 
        /* add a '.' if it a the entry for the current directory */
-       if(strcmp(disk_path,dir)==0 || strcmp(disk_path_slash,dir)==0) {
-           dir = disk_path_slash_dot;
+       if((strcmp(disk_path,dir)==0) || (strcmp(disk_path_slash,dir)==0)) {
+           amfree(dir);
+           dir = stralloc(disk_path_slash_dot);
        }
        add_dir_list_item(date, level, tape, fileno, dir);
+       amfree(dir);
     }
     amfree(disk_path_slash_dot);
     amfree(disk_path_slash);
@@ -242,23 +272,26 @@ void suck_dir_list_from_server P((void))
        if(*err) {
            puts(err);
        }
-       puts(cmd);
+       if (cmd)
+           puts(cmd);
        clear_dir_list();
     }
     amfree(cmd);
 }
 
 
-void list_directory P((void))
+void
+list_directory(void)
 {
     size_t i;
     DIR_ITEM *item;
     FILE *fp;
     char *pager;
     char *pager_command;
+    char *quoted;
 
     if (disk_path == NULL) {
-       printf("Must select a disk before listing files\n");
+       printf("Must select a disk before listing files; use the setdisk command.\n");
        return;
     }
 
@@ -280,7 +313,10 @@ void list_directory P((void))
     i = strlen(disk_path);
     if (i != 1)
        i++;                            /* so disk_path != "/" */
-    for (item = get_dir_list(); item != NULL; item=get_next_dir_item(item))
-       fprintf(fp, "%s %s\n", item->date, item->path+i);
+    for (item = get_dir_list(); item != NULL; item=get_next_dir_item(item)) {
+       quoted = quote_string(item->path + i);
+       fprintf(fp, "%s %s\n", item->date, quoted);
+       amfree(quoted);
+    }
     apclose(fp);
 }
index 72b37c52bc0a86ced1762a1d084ff68b5b1c94e1..67c02d1bd10325a8c5ee358ef6fbeb61952ee95e 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: extract_list.c,v 1.97 2006/03/09 16:51:41 martinea Exp $
+ * $Id: extract_list.c,v 1.117 2006/08/24 01:57:15 paddy_s Exp $
  *
  * implements the "extract" command in amrecover
  */
 #include "findpass.h"
 #endif
 #include "util.h"
+#include "clientconf.h"
+#include "protocol.h"
+#include "event.h"
+#include "security.h"
 
-typedef struct EXTRACT_LIST_ITEM
-{
+typedef struct EXTRACT_LIST_ITEM {
     char *path;
-
     struct EXTRACT_LIST_ITEM *next;
 }
 EXTRACT_LIST_ITEM;
 
-typedef struct EXTRACT_LIST
-{
+typedef struct EXTRACT_LIST {
     char *date;                        /* date tape created */
-    int  level;                                /* level of dump */
+    int  level;                        /* level of dump */
     char *tape;                        /* tape label */
-    int fileno;                                /* fileno on tape */
-    EXTRACT_LIST_ITEM *files;          /* files to get off tape */
+    off_t fileno;              /* fileno on tape */
+    EXTRACT_LIST_ITEM *files;  /* files to get off tape */
 
     struct EXTRACT_LIST *next;
 }
@@ -64,7 +65,24 @@ EXTRACT_LIST;
 #define SKIP_TAPE 2
 #define RETRY_TAPE 3
 
-char *dump_device_name = NULL;
+static struct {
+    const char *name;
+    security_stream_t *fd;
+} amidxtaped_streams[] = {
+#define CTLFD  0
+    { "CTL", NULL },
+#define DATAFD  1
+    { "DATA", NULL },
+};
+#define NSTREAMS  (int)(sizeof(amidxtaped_streams) / sizeof(amidxtaped_streams[0]))
+
+
+static void amidxtaped_response(void *, pkt_t *, security_handle_t *);
+static void stop_amidxtaped(void);
+char *amidxtaped_client_get_security_conf(char *, void *);
+static char *dump_device_name = NULL;
+static char *errstr;
+static char *amidxtaped_line = NULL;
 
 extern char *localhost;
 
@@ -72,8 +90,7 @@ extern char *localhost;
 pid_t extract_restore_child_pid = -1;
 
 static EXTRACT_LIST *extract_list = NULL;
-static int tape_control_sock = -1;
-static int tape_data_sock = -1;
+static const security_driver_t *amidxtaped_secdrv;
 
 #ifdef SAMBA_CLIENT
 unsigned short samba_extract_method = SAMBA_TAR;
@@ -81,9 +98,44 @@ unsigned short samba_extract_method = SAMBA_TAR;
 
 #define READ_TIMEOUT   240*60
 
-static int okay_to_continue P((int, int,  int));
-void writer_intermediary P((int ctl_fd, int data_fd, EXTRACT_LIST *elist));
-
+EXTRACT_LIST *first_tape_list(void);
+EXTRACT_LIST *next_tape_list(EXTRACT_LIST *list);
+static int is_empty_dir(char *fname);
+int is_extract_list_nonempty(void);
+int length_of_tape_list(EXTRACT_LIST *tape_list);
+void add_file(char *path, char *regex);
+void add_glob(char *glob);
+void add_regex(char *regex);
+void clear_extract_list(void);
+void clean_tape_list(EXTRACT_LIST *tape_list);
+void clean_extract_list(void);
+void check_file_overwrite(char *filename);
+void delete_file(char *path, char *regex);
+void delete_glob(char *glob);
+void delete_regex(char *regex);
+void delete_tape_list(EXTRACT_LIST *tape_list);
+void display_extract_list(char *file);
+void extract_files(void);
+void read_file_header(char *buffer,
+                       dumpfile_t *file,
+                       size_t buflen,
+                       int tapedev);
+static int add_extract_item(DIR_ITEM *ditem);
+static int delete_extract_item(DIR_ITEM *ditem);
+static int extract_files_setup(char *label, off_t fsf);
+static int okay_to_continue(int allow_tape,
+                       int allow_skip,
+                       int allow_retry);
+static ssize_t read_buffer(int datafd,
+                       char *buffer,
+                       size_t buflen,
+                       long timeout_s);
+static void clear_tape_list(EXTRACT_LIST *tape_list);
+static void extract_files_child(int in_fd, EXTRACT_LIST *elist);
+static void send_to_tape_server(security_stream_t *stream, char *cmd);
+int writer_intermediary(EXTRACT_LIST *elist);
+int get_amidxtaped_line(void);
+static void read_amidxtaped_data(void *, void *, ssize_t);
 
 /*
  * Function:  ssize_t read_buffer(datafd, buffer, buflen, timeout_s)
@@ -107,25 +159,26 @@ void writer_intermediary P((int ctl_fd, int data_fd, EXTRACT_LIST *elist));
  */
 
 static ssize_t
-read_buffer(datafd, buffer, buflen, timeout_s)
-int datafd;
-char *buffer;
-size_t buflen;
+read_buffer(
+    int                datafd,
+    char *     buffer,
+    size_t     buflen,
+    long       timeout_s)
 {
     ssize_t size = 0;
     fd_set readset;
     struct timeval timeout;
     char *dataptr;
-    size_t spaceleft;
+    ssize_t spaceleft;
     int nfound;
 
-    if(datafd < 0 || datafd >= FD_SETSIZE) {
+    if(datafd < 0 || datafd >= (int)FD_SETSIZE) {
        errno = EMFILE;                                 /* out of range */
        return -1;
     }
 
     dataptr = buffer;
-    spaceleft = buflen;
+    spaceleft = (ssize_t)buflen;
 
     do {
         FD_ZERO(&readset);
@@ -156,7 +209,7 @@ size_t buflen;
            continue;
 
         /* Select says data is available, so read it.  */
-        size = read(datafd, dataptr, spaceleft);
+        size = read(datafd, dataptr, (size_t)spaceleft);
         if (size < 0) {
            if ((errno == EINTR) || (errno == EAGAIN)) {
                continue;
@@ -172,25 +225,28 @@ size_t buflen;
         dataptr += size;
     } while ((size > 0) && (spaceleft > 0));
 
-    return (((buflen-spaceleft) > 0) ? (buflen-spaceleft) : size);
+    return ((((ssize_t)buflen-spaceleft) > 0) ? ((ssize_t)buflen-spaceleft) : size);
 }
 
 
-EXTRACT_LIST *first_tape_list P((void))
+EXTRACT_LIST *
+first_tape_list(void)
 {
     return extract_list;
 }
 
-EXTRACT_LIST *next_tape_list(list)
-EXTRACT_LIST *list;
+EXTRACT_LIST *
+next_tape_list(
+    /*@keep@*/EXTRACT_LIST *list)
 {
     if (list == NULL)
        return NULL;
     return list->next;
 }
 
-static void clear_tape_list(tape_list)
-EXTRACT_LIST *tape_list;
+static void
+clear_tape_list(
+    EXTRACT_LIST *     tape_list)
 {
     EXTRACT_LIST_ITEM *this, *next;
     
@@ -209,8 +265,9 @@ EXTRACT_LIST *tape_list;
 
 /* remove a tape list from the extract list, clearing the tape list
    beforehand if necessary */
-void delete_tape_list(tape_list)
-EXTRACT_LIST *tape_list;
+void
+delete_tape_list(
+    EXTRACT_LIST *tape_list)
 {
     EXTRACT_LIST *this, *prev;
 
@@ -250,8 +307,9 @@ EXTRACT_LIST *tape_list;
 
 
 /* return the number of files on a tape's list */
-int length_of_tape_list(tape_list)
-EXTRACT_LIST *tape_list;
+int
+length_of_tape_list(
+    EXTRACT_LIST *tape_list)
 {
     EXTRACT_LIST_ITEM *fn;
     int n;
@@ -264,18 +322,235 @@ EXTRACT_LIST *tape_list;
 }
 
 
-void clear_extract_list P((void))
+void
+clear_extract_list(void)
 {
     while (extract_list != NULL)
        delete_tape_list(extract_list);
 }
 
 
+void
+clean_tape_list(
+    EXTRACT_LIST *tape_list)
+{
+    EXTRACT_LIST_ITEM *fn1, *pfn1, *ofn1;
+    EXTRACT_LIST_ITEM *fn2, *pfn2, *ofn2;
+    int remove_fn1;
+    int remove_fn2;
+
+    pfn1 = NULL;
+    fn1 = tape_list->files;
+    while (fn1 != NULL) {
+       remove_fn1 = 0;
+
+       pfn2 = fn1;
+       fn2 = fn1->next;
+       while (fn2 != NULL && remove_fn1 == 0) {
+           remove_fn2 = 0;
+           if(strcmp(fn1->path, fn2->path) == 0) {
+               remove_fn2 = 1;
+           } else if (strncmp(fn1->path, fn2->path, strlen(fn1->path)) == 0 &&
+                      ((strlen(fn2->path) > strlen(fn1->path) &&
+                        fn2->path[strlen(fn1->path)] == '/') ||
+                      (fn1->path[strlen(fn1->path)-1] == '/'))) {
+               remove_fn2 = 1;
+           } else if (strncmp(fn2->path, fn1->path, strlen(fn2->path)) == 0 &&
+                      ((strlen(fn1->path) > strlen(fn2->path) &&
+                        fn1->path[strlen(fn2->path)] == '/')  ||
+                      (fn2->path[strlen(fn2->path)-1] == '/'))) {
+               remove_fn1 = 1;
+               break;
+           }
+
+           if (remove_fn2) {
+               dbprintf(("removing path %s, it is included in %s\n",
+                         fn2->path, fn1->path));
+               ofn2 = fn2;
+               fn2 = fn2->next;
+               amfree(ofn2->path);
+               amfree(ofn2);
+               pfn2->next = fn2;
+           } else if (remove_fn1 == 0) {
+               pfn2 = fn2;
+               fn2 = fn2->next;
+           }
+       }
+
+       if(remove_fn1 != 0) {
+           /* fn2->path is always valid */
+           /*@i@*/ dbprintf(("removing path %s, it is included in %s\n",
+           /*@i@*/           fn1->path, fn2->path));
+           ofn1 = fn1;
+           fn1 = fn1->next;
+           amfree(ofn1->path);
+           if(pfn1 == NULL) {
+               amfree(tape_list->files);
+               tape_list->files = fn1;
+           } else {
+               amfree(pfn1->next);
+               pfn1->next = fn1;
+           }
+       } else {
+           pfn1 = fn1;
+           fn1 = fn1->next;
+       }
+    }
+}
+
+
+void
+clean_extract_list(void)
+{
+    EXTRACT_LIST *this;
+
+    for (this = extract_list; this != NULL; this = this->next)
+       clean_tape_list(this);
+}
+
+
+int add_to_unlink_list(char *path);
+int do_unlink_list(void);
+void free_unlink_list(void);
+
+typedef struct s_unlink_list {
+    char *path;
+    struct s_unlink_list *next;
+} t_unlink_list;
+t_unlink_list *unlink_list = NULL;
+
+int
+add_to_unlink_list(
+    char *path)
+{
+    t_unlink_list *ul;
+
+    if (!unlink_list) {
+       unlink_list = alloc(SIZEOF(*unlink_list));
+       unlink_list->path = stralloc(path);
+       unlink_list->next = NULL;
+    } else {
+       for (ul = unlink_list; ul != NULL; ul = ul->next) {
+           if (strcmp(ul->path, path) == 0)
+               return 0;
+       }
+       ul = alloc(SIZEOF(*ul));
+       ul->path = stralloc(path);
+       ul->next = unlink_list;
+       unlink_list = ul;
+    }
+    return 1;
+}
+
+int
+do_unlink_list(void)
+{
+    t_unlink_list *ul;
+    int ret = 1;
+
+    for (ul = unlink_list; ul != NULL; ul = ul->next) {
+       if (unlink(ul->path) < 0) {
+           fprintf(stderr,"Can't unlink %s: %s\n", ul->path, strerror(errno));
+           ret = 0;
+       }
+    }
+    return ret;
+}
+
+
+void
+free_unlink_list(void)
+{
+    t_unlink_list *ul, *ul1;
+
+    for (ul = unlink_list; ul != NULL; ul = ul1) {
+       amfree(ul->path);
+       ul1 = ul->next;
+       amfree(ul);
+    }
+
+    unlink_list = NULL;
+}
+
+
+
+void
+check_file_overwrite(
+    char *dir)
+{
+    EXTRACT_LIST      *this;
+    EXTRACT_LIST_ITEM *fn;
+    struct stat        stat_buf;
+    char              *filename;
+    char              *path, *s;
+
+    for (this = extract_list; this != NULL; this = this->next) {
+       for (fn = this->files; fn != NULL ; fn = fn->next) {
+
+           /* Check path component of fn->path */
+
+           path = stralloc2(dir, fn->path);
+           if (path[strlen(path)-1] == '/') {
+               path[strlen(path)-1] = '\0';
+           }
+
+           s = path + strlen(dir) + 1;
+           while((s = strchr(s, '/'))) {
+               *s = '\0';
+               if (lstat(path, &stat_buf) == 0) {
+                   if(!S_ISDIR(stat_buf.st_mode)) {
+                       if (add_to_unlink_list(path)) {
+                           printf("WARNING: %s is not a directory, "
+                                  "it will be deleted.\n",
+                                  path);
+                       }
+                   }
+               }
+               else if (errno != ENOENT) {
+                   printf("Can't stat %s: %s\n", path, strerror(errno));
+               }
+               *s = '/';
+               s++;
+           }
+           amfree(path);
+
+           /* Check fn->path */
+
+           filename = stralloc2(dir, fn->path);
+           if (filename[strlen(filename)-1] == '/') {
+               filename[strlen(filename)-1] = '\0';
+           }
+
+           if (lstat(filename, &stat_buf) == 0) {
+               if(S_ISDIR(stat_buf.st_mode)) {
+                   if(!is_empty_dir(filename)) {
+                       printf("WARNING: All existing files in %s "
+                              "will be deleted.\n", filename);
+                   }
+               } else if(S_ISREG(stat_buf.st_mode)) {
+                   printf("WARNING: Existing file %s will be overwritten\n",
+                          filename);
+               } else {
+                   if (add_to_unlink_list(filename)) {
+                       printf("WARNING: Existing entry %s will be deleted\n",
+                              filename);
+                   }
+               }
+           } else if (errno != ENOENT) {
+               printf("Can't stat %s: %s\n", filename, strerror(errno));
+           }
+           amfree(filename);
+       }
+    }
+}
+
+
 /* returns -1 if error */
 /* returns  0 on succes */
 /* returns  1 if already added */
-static int add_extract_item(ditem)
-DIR_ITEM *ditem;
+static int
+add_extract_item(
+    DIR_ITEM *ditem)
 {
     EXTRACT_LIST *this, *this1;
     EXTRACT_LIST_ITEM *that, *curr;
@@ -351,8 +626,9 @@ DIR_ITEM *ditem;
 /* returns -1 if error */
 /* returns  0 on deletion */
 /* returns  1 if not there */
-static int delete_extract_item(ditem)
-DIR_ITEM *ditem;
+static int
+delete_extract_item(
+    DIR_ITEM *ditem)
 {
     EXTRACT_LIST *this;
     EXTRACT_LIST_ITEM *that, *prev;
@@ -405,51 +681,58 @@ DIR_ITEM *ditem;
 }
 
 
-void add_glob(glob)
-char *glob;
+void
+add_glob(
+    char *     glob)
 {
     char *regex;
     char *regex_path;
     char *s;
-
-    regex = glob_to_regex(glob);
-    dbprintf(("add_glob (%s) -> %s\n", glob, regex));
+    char *uqglob = unquote_string(glob);
+    regex = glob_to_regex(uqglob);
+    dbprintf(("add_glob (%s) -> %s\n", uqglob, regex));
     if ((s = validate_regexp(regex)) != NULL) {
-       printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+       printf("%s is not a valid shell wildcard pattern: ", glob);
        puts(s);
-       return;
+    } else {
+        /*
+         * glob_to_regex() anchors the beginning of the pattern with ^,
+         * but we will be tacking it onto the end of the current directory
+         * in add_file, so strip that off.  Also, it anchors the end with
+         * $, but we need to match an optional trailing /, so tack that on
+         * the end.
+         */
+        regex_path = stralloc(regex + 1);
+        regex_path[strlen(regex_path) - 1] = '\0';
+        strappend(regex_path, "[/]*$");
+        add_file(uqglob, regex_path);
+        amfree(regex_path);
     }
-    /*
-     * glob_to_regex() anchors the beginning of the pattern with ^,
-     * but we will be tacking it onto the end of the current directory
-     * in add_file, so strip that off.  Also, it anchors the end with
-     * $, but we need to match an optional trailing /, so tack that on
-     * the end.
-     */
-    regex_path = stralloc(regex + 1);
     amfree(regex);
-    regex_path[strlen(regex_path) - 1] = '\0';
-    strappend(regex_path, "[/]*$");
-    add_file(glob, regex_path);
-    amfree(regex_path);
+    amfree(uqglob);
 }
 
-void add_regex(regex)
-char *regex;
+void
+add_regex(
+    char *     regex)
 {
     char *s;
-
-    if ((s = validate_regexp(regex)) != NULL) {
+    char *uqregex = unquote_string(regex);
+    if ((s = validate_regexp(uqregex)) != NULL) {
        printf("\"%s\" is not a valid regular expression: ", regex);
        puts(s);
-       return;
+    } else {
+        add_file(uqregex, regex);
     }
-    add_file(regex, regex);
+    amfree(uqregex);
 }
 
-void add_file(path, regex)
-char *path;
-char *regex;
+void
+add_file(
+    char *     path,
+    char *     regex)
 {
     DIR_ITEM *ditem, lditem;
     char *path_on_disk = NULL;
@@ -457,14 +740,15 @@ char *regex;
     char *cmd = NULL;
     char *err = NULL;
     int i;
-    int j;
+    ssize_t j;
     char *dir, *dir_undo, dir_undo_ch = '\0';
     char *ditem_path = NULL;
     char *l = NULL;
     int  added;
-    char *s, *fp;
+    char *s, *fp, *quoted;
     int ch;
     int found_one;
+    int dir_entries;
 
     if (disk_path == NULL) {
        printf("Must select directory before adding files\n");
@@ -474,20 +758,24 @@ char *regex;
 
     dbprintf(("add_file: Looking for \"%s\"\n", regex));
 
-    /* remove "/" at end of path */
-    j = strlen(regex)-1;
-    while(j >= 0 && regex[j] == '/') regex[j--] = '\0';
+    if(strcmp(regex, "/[/]*$") == 0) { /* "/" behave like "." */
+       regex = "\\.[/]*$";
+    }
+    else if(strcmp(regex, "[^/]*[/]*$") == 0) {                /* "*" */
+       //regex = 
+       regex = "([^/.]|\\.[^/]+|[^/.][^/]*)[/]*$";
+    } else {
+       /* remove "/" at end of path */
+       j = (ssize_t)(strlen(regex) - 1);
+       while(j >= 0 && regex[j] == '/')
+           regex[j--] = '\0';
+    }
 
     /* convert path (assumed in cwd) to one on disk */
     if (strcmp(disk_path, "/") == 0) {
         if (*regex == '/') {
-           if (strcmp(regex, "/[/]*$") == 0) {
-               /* We want '/' to match everything in directory... */
-               path_on_disk = stralloc("/[^/]*[/]*$");
-           } else {
-               /* No mods needed if already starts with '/' */
-               path_on_disk = stralloc(regex);
-           }
+           /* No mods needed if already starts with '/' */
+           path_on_disk = stralloc(regex);
        } else {
            /* Prepend '/' */
            path_on_disk = stralloc2("/", regex);
@@ -504,18 +792,21 @@ char *regex;
              regex, path_on_disk));
 
     found_one = 0;
+    dir_entries = 0;
     for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
     {
-       dbprintf(("add_file: Pondering ditem->path=\"%s\"\n", ditem->path));
+       dir_entries++;
+       quoted = quote_string(ditem->path);
+       dbprintf(("add_file: Pondering ditem->path=%s\n", quoted));
+       amfree(quoted);
        if (match(path_on_disk, ditem->path)
            || match(path_on_disk_slash, ditem->path))
        {
            found_one = 1;
-           j = strlen(ditem->path);
+           j = (ssize_t)strlen(ditem->path);
            if((j > 0 && ditem->path[j-1] == '/')
               || (j > 1 && ditem->path[j-2] == '/' && ditem->path[j-1] == '.'))
            {   /* It is a directory */
-
                ditem_path = newstralloc(ditem_path, ditem->path);
                clean_pathname(ditem_path);
 
@@ -536,8 +827,7 @@ char *regex;
                    amfree(path_on_disk_slash);
                    exit(1);
                }
-               if(i==0)                /* assume something wrong */
-               {
+               if(i==0) {              /* assume something wrong */
                    amfree(ditem_path);
                    amfree(path_on_disk);
                    amfree(path_on_disk_slash);
@@ -549,8 +839,8 @@ char *regex;
                added=0;
                 lditem.path = newstralloc(lditem.path, ditem->path);
                /* skip the last line -- duplicate of the preamble */
-               while ((i = get_reply_line()) != 0)
-               {
+
+               while ((i = get_reply_line()) != 0) {
                    if (i == -1) {
                        amfree(ditem_path);
                        amfree(path_on_disk);
@@ -588,7 +878,7 @@ char *regex;
                     skip_non_whitespace(s, ch);
                     s[-1] = '\0';
                     lditem.date = newstralloc(lditem.date, fp);
-                    s[-1] = ch;
+                    s[-1] = (char)ch;
 
                    skip_whitespace(s, ch);
                    if(ch == '\0' || sscanf(s - 1, "%d", &lditem.level) != 1) {
@@ -606,11 +896,12 @@ char *regex;
                     skip_non_whitespace(s, ch);
                     s[-1] = '\0';
                     lditem.tape = newstralloc(lditem.tape, fp);
-                    s[-1] = ch;
+                    s[-1] = (char)ch;
 
                    if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_ORLD)) {
                        skip_whitespace(s, ch);
-                       if(ch == '\0' || sscanf(s - 1, "%d", &lditem.fileno) != 1) {
+                       if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&lditem.fileno) != 1) {
                            err = "bad reply: cannot parse fileno field";
                            continue;
                        }
@@ -623,7 +914,7 @@ char *regex;
                        continue;
                    }
                    dir = s - 1;
-                   skip_non_whitespace(s, ch);
+                   skip_quoted_string(s, ch);
                    dir_undo = s - 1;
                    dir_undo_ch = *dir_undo;
                    *dir_undo = '\0';
@@ -633,13 +924,17 @@ char *regex;
                        printf("System error\n");
                        dbprintf(("add_file: (Failed) System error\n"));
                        break;
+
                    case  0:
+                       quoted = quote_string(lditem.path);
                        printf("Added dir %s at date %s\n",
-                              ditem_path, lditem.date);
+                              quoted, lditem.date);
                        dbprintf(("add_file: (Successful) Added dir %s at date %s\n",
-                                 ditem_path,lditem.date));
+                                 quoted, lditem.date));
+                       amfree(quoted);
                        added=1;
                        break;
+
                    case  1:
                        break;
                    }
@@ -647,11 +942,15 @@ char *regex;
                if(!server_happy()) {
                    puts(reply_line());
                } else if(err) {
-                   puts(err);
-                   puts(cmd);
+                   if (*err)
+                       puts(err);
+                   if (cmd)
+                       puts(cmd);
                } else if(added == 0) {
-                   printf("dir %s already added\n", ditem_path);
-                   dbprintf(("add_file: dir %s already added\n", ditem_path));
+                   quoted = quote_string(ditem_path);
+                   printf("dir %s already added\n", quoted);
+                   dbprintf(("add_file: dir %s already added\n", quoted));
+                   amfree(quoted);
                }
            }
            else /* It is a file */
@@ -661,79 +960,95 @@ char *regex;
                    printf("System error\n");
                    dbprintf(("add_file: (Failed) System error\n"));
                    break;
+
                case  0:
-                   printf("Added %s\n", ditem->path);
-                   dbprintf(("add_file: (Successful) Added %s\n",
-                             ditem->path));
+                   quoted = quote_string(ditem->path);
+                   printf("Added file %s\n", quoted);
+                   dbprintf(("add_file: (Successful) Added %s\n", quoted));
+                   amfree(quoted);
                    break;
+
                case  1:
-                   printf("File %s already added\n", ditem->path);
-                   dbprintf(("add_file: file %s already added\n",
-                             ditem->path));
-                   break;
+                   quoted = quote_string(ditem->path);
+                   printf("File %s already added\n", quoted);
+                   dbprintf(("add_file: file %s already added\n", quoted));
+                   amfree(quoted);
                }
            }
        }
     }
-    if (cmd != NULL)
-       amfree(cmd);
+
+    amfree(cmd);
     amfree(ditem_path);
     amfree(path_on_disk);
     amfree(path_on_disk_slash);
 
+    amfree(lditem.path);
+    amfree(lditem.date);
+    amfree(lditem.tape);
+
     if(! found_one) {
-       printf("File %s doesn't exist in directory\n", path);
+       quoted = quote_string(path);
+       printf("File %s doesn't exist in directory\n", quoted);
        dbprintf(("add_file: (Failed) File %s doesn't exist in directory\n",
-                 path));
+                 quoted));
+       amfree(quoted);
     }
 }
 
 
-void delete_glob(glob)
-char *glob;
+void
+delete_glob(
+    char *     glob)
 {
     char *regex;
     char *regex_path;
     char *s;
-
-    regex = glob_to_regex(glob);
-    dbprintf(("delete_glob (%s) -> %s\n", glob, regex));
+    char *uqglob = unquote_string(glob);
+    regex = glob_to_regex(uqglob);
+    dbprintf(("delete_glob (%s) -> %s\n", uqglob, regex));
     if ((s = validate_regexp(regex)) != NULL) {
        printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
        puts(s);
-       return;
+    } else {
+        /*
+         * glob_to_regex() anchors the beginning of the pattern with ^,
+         * but we will be tacking it onto the end of the current directory
+         * in add_file, so strip that off.  Also, it anchors the end with
+         * $, but we need to match an optional trailing /, so tack that on
+         * the end.
+         */
+        regex_path = stralloc(regex + 1);
+        regex_path[strlen(regex_path) - 1] = '\0';
+        strappend(regex_path, "[/]*$");
+        delete_file(uqglob, regex_path);
+        amfree(regex_path);
     }
-    /*
-     * glob_to_regex() anchors the beginning of the pattern with ^,
-     * but we will be tacking it onto the end of the current directory
-     * in add_file, so strip that off.  Also, it anchors the end with
-     * $, but we need to match an optional trailing /, so tack that on
-     * the end.
-     */
-    regex_path = stralloc(regex + 1);
     amfree(regex);
-    regex_path[strlen(regex_path) - 1] = '\0';
-    strappend(regex_path, "[/]*$");
-    delete_file(glob, regex_path);
-    amfree(regex_path);
+    amfree(uqglob);
 }
 
-void delete_regex(regex)
-char *regex;
+void
+delete_regex(
+    char *     regex)
 {
     char *s;
+    char *uqregex = unquote_string(regex);
 
     if ((s = validate_regexp(regex)) != NULL) {
        printf("\"%s\" is not a valid regular expression: ", regex);
        puts(s);
-       return;
+    } else {
+       delete_file(uqregex, uqregex);
     }
-    delete_file(regex, regex);
+    amfree(uqregex);
 }
 
-void delete_file(path, regex)
-char *path;
-char *regex;
+void
+delete_file(
+    char *     path,
+    char *     regex)
 {
     DIR_ITEM *ditem, lditem;
     char *path_on_disk = NULL;
@@ -741,17 +1056,19 @@ char *regex;
     char *cmd = NULL;
     char *err = NULL;
     int i;
-    int j;
-    char *date, *date_undo, date_undo_ch = '\0';
+    ssize_t j;
+    char *date;
     char *tape, *tape_undo, tape_undo_ch = '\0';
-    char *dir, *dir_undo, dir_undo_ch = '\0';
-    int  level, fileno;
+    char *dir_undo, dir_undo_ch = '\0';
+    int  level = 0;
+    off_t fileno;
     char *ditem_path = NULL;
     char *l = NULL;
     int  deleted;
     char *s;
     int ch;
     int found_one;
+    char *quoted;
 
     if (disk_path == NULL) {
        printf("Must select directory before deleting files\n");
@@ -760,14 +1077,31 @@ char *regex;
     memset(&lditem, 0, sizeof(lditem)); /* Prevent use of bogus data... */
 
     dbprintf(("delete_file: Looking for \"%s\"\n", path));
-    /* remove "/" at the end of the path */
-    j = strlen(regex)-1;
-    while(j >= 0 && regex[j] == '/') regex[j--] = '\0';
+
+    if (strcmp(regex, "[^/]*[/]*$") == 0) {
+       /* Looking for * find everything but single . */
+       regex = "([^/.]|\\.[^/]+|[^/.][^/]*)[/]*$";
+    } else {
+       /* remove "/" at end of path */
+       j = (ssize_t)(strlen(regex) - 1);
+       while(j >= 0 && regex[j] == '/') regex[j--] = '\0';
+    }
 
     /* convert path (assumed in cwd) to one on disk */
-    if (strcmp(disk_path, "/") == 0)
-       path_on_disk = stralloc2("/", regex);
-    else {
+    if (strcmp(disk_path, "/") == 0) {
+        if (*regex == '/') {
+           if (strcmp(regex, "/[/]*$") == 0) {
+               /* We want "/" to match the directory itself: "/." */
+               path_on_disk = stralloc("/\\.[/]*$");
+           } else {
+               /* No mods needed if already starts with '/' */
+               path_on_disk = stralloc(regex);
+           }
+       } else {
+           /* Prepend '/' */
+           path_on_disk = stralloc2("/", regex);
+       }
+    } else {
        char *clean_disk_path = clean_regex(disk_path);
        path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
        amfree(clean_disk_path);
@@ -780,12 +1114,14 @@ char *regex;
     found_one = 0;
     for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
     {
-       dbprintf(("delete_file: Pondering ditem->path=\"%s\"\n", ditem->path));
+       quoted = quote_string(ditem->path);
+       dbprintf(("delete_file: Pondering ditem->path=%s\n", quoted));
+       amfree(quoted);
        if (match(path_on_disk, ditem->path)
            || match(path_on_disk_slash, ditem->path))
        {
            found_one = 1;
-           j = strlen(ditem->path);
+           j = (ssize_t)strlen(ditem->path);
            if((j > 0 && ditem->path[j-1] == '/')
               || (j > 1 && ditem->path[j-2] == '/' && ditem->path[j-1] == '.'))
            {   /* It is a directory */
@@ -820,7 +1156,7 @@ char *regex;
                deleted=0;
                 lditem.path = newstralloc(lditem.path, ditem->path);
                amfree(cmd);
-               date_undo = tape_undo = dir_undo = NULL;
+               tape_undo = dir_undo = NULL;
                /* skip the last line -- duplicate of the preamble */
                while ((i = get_reply_line()) != 0)
                {
@@ -834,7 +1170,7 @@ char *regex;
                        if(cmd == NULL) {
                            if(tape_undo) *tape_undo = tape_undo_ch;
                            if(dir_undo) *dir_undo = dir_undo_ch;
-                           date_undo = tape_undo = dir_undo = NULL;
+                           tape_undo = dir_undo = NULL;
                            cmd = stralloc(l);  /* save for the error report */
                        }
                        continue;       /* throw the rest of the lines away */
@@ -859,9 +1195,7 @@ char *regex;
                    }
                    date = s - 1;
                    skip_non_whitespace(s, ch);
-                   date_undo = s - 1;
-                   date_undo_ch = *date_undo;
-                   *date_undo = '\0';
+                   *(s - 1) = '\0';
 
                    skip_whitespace(s, ch);
                    if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
@@ -883,7 +1217,8 @@ char *regex;
 
                    if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_ORLD)) {
                        skip_whitespace(s, ch);
-                       if(ch == '\0' || sscanf(s - 1, "%d", &fileno) != 1) {
+                       if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&fileno) != 1) {
                            err = "bad reply: cannot parse fileno field";
                            continue;
                        }
@@ -895,7 +1230,6 @@ char *regex;
                        err = "bad reply: missing directory field";
                        continue;
                    }
-                   dir = s - 1;
                    skip_non_whitespace(s, ch);
                    dir_undo = s - 1;
                    dir_undo_ch = *dir_undo;
@@ -922,10 +1256,10 @@ char *regex;
                if(!server_happy()) {
                    puts(reply_line());
                } else if(err) {
-                   if(*err) {
+                   if (*err)
                        puts(err);
-                   }
-                   puts(cmd);
+                   if (cmd)
+                       puts(cmd);
                } else if(deleted == 0) {
                    printf("Warning - dir '%s' not on tape list\n",
                           ditem_path);
@@ -969,14 +1303,16 @@ char *regex;
 
 
 /* print extract list into file. If NULL ptr passed print to screen */
-void display_extract_list(file)
-char *file;
+void
+display_extract_list(
+    char *     file)
 {
     EXTRACT_LIST *this;
     EXTRACT_LIST_ITEM *that;
     FILE *fp;
     char *pager;
     char *pager_command;
+    char *uqfile;
 
     if (file == NULL)
     {
@@ -998,11 +1334,14 @@ char *file;
     }
     else
     {
-       if ((fp = fopen(file, "w")) == NULL)
+       uqfile = unquote_string(file);
+       if ((fp = fopen(uqfile, "w")) == NULL)
        {
-           printf("Can't open file '%s' to print extract list into\n", file);
+           printf("Can't open file %s to print extract list into\n", file);
+           amfree(uqfile);
            return;
        }
+       amfree(uqfile);
     }
 
     for (this = extract_list; this != NULL; this = this->next)
@@ -1022,8 +1361,30 @@ char *file;
 }
 
 
+static int
+is_empty_dir(
+    char *fname)
+{
+    DIR *dir;
+    struct dirent *entry;
+    int gotentry;
+
+    if((dir = opendir(fname)) == NULL)
+        return 1;
+
+    gotentry = 0;
+    while(!gotentry && (entry = readdir(dir)) != NULL) {
+        gotentry = !is_dot_or_dotdot(entry->d_name);
+    }
+
+    closedir(dir);
+    return !gotentry;
+
+}
+
 /* returns 0 if extract list empty and 1 if it isn't */
-int is_extract_list_nonempty P((void))
+int
+is_extract_list_nonempty(void)
 {
     return (extract_list != NULL);
 }
@@ -1031,10 +1392,11 @@ int is_extract_list_nonempty P((void))
 
 /* prints continue prompt and waits for response,
    returns 0 if don't, non-0 if do */
-static int okay_to_continue(allow_tape, allow_skip, allow_retry)
-    int allow_tape;
-    int allow_skip;
-    int allow_retry;
+static int
+okay_to_continue(
+    int        allow_tape,
+    int        allow_skip,
+    int        allow_retry)
 {
     int ch;
     int ret = -1;
@@ -1070,7 +1432,9 @@ static int okay_to_continue(allow_tape, allow_skip, allow_retry)
            break;
        }
        s = line;
-       while ((ch = *s++) != '\0' && isspace(ch)) {}
+       while ((ch = *s++) != '\0' && isspace(ch)) {
+           (void)ch;   /* Quiet empty loop compiler warning */
+       }
        if (ch == '?') {
            if (get_tape) {
                printf("Enter a new device ([host:]device) or \"default\"\n");
@@ -1102,20 +1466,24 @@ static int okay_to_continue(allow_tape, allow_skip, allow_retry)
            ret = SKIP_TAPE;
        }
     }
+    /*@ignore@*/
     amfree(line);
+    /*@end@*/
     return ret;
 }
 
-static void send_to_tape_server(tss, cmd)
-int tss;
-char *cmd;
+static void
+send_to_tape_server(
+    security_stream_t *        stream,
+    char *             cmd)
 {
     char *msg = stralloc2(cmd, "\r\n");
 
-    if (fullwrite(tss, msg, strlen(msg)) < 0)
+    if (security_stream_write(stream, msg, strlen(msg)) < 0)
     {
        error("Error writing to tape server");
        exit(101);
+       /*NOTREACHED*/
     }
     amfree(msg);
 }
@@ -1124,57 +1492,39 @@ char *cmd;
 /* start up connection to tape server and set commands to initiate
    transfer of dump image.
    Return tape server socket on success, -1 on error. */
-static int extract_files_setup(label, fsf)
-char *label;
-int fsf;
+static int
+extract_files_setup(
+    char *     label,
+    off_t      fsf)
 {
-    struct servent *sp;
-    int my_port, my_data_port;
     char *disk_regex = NULL;
     char *host_regex = NULL;
-    char *service_name = NULL;
-    char *line = NULL;
     char *clean_datestamp, *ch, *ch1;
-    char *our_feature_string = NULL;
     char *tt = NULL;
+    char *req;
+    int response_error;
 
-    service_name = stralloc2("amidxtape", SERVICE_SUFFIX);
-
-    /* get tape server details */
-    if ((sp = getservbyname(service_name, "tcp")) == NULL)
-    {
-       printf("%s/tcp unknown protocol - config error?\n", service_name);
-       amfree(service_name);
-       return -1;
+    amidxtaped_secdrv = security_getdriver(authopt);
+    if (amidxtaped_secdrv == NULL) {
+       error("no '%s' security driver available for host '%s'",
+             authopt, tape_server_name);
     }
-    amfree(service_name);
-    seteuid(0);                                        /* it either works ... */
-    setegid(0);
-    tape_control_sock = stream_client_privileged(tape_server_name,
-                                                 ntohs(sp->s_port),
-                                                 -1,
-                                                 STREAM_BUFSIZE,
-                                                 &my_port,
-                                                 0);
-    if (tape_control_sock < 0)
-    {
-       printf("cannot connect to %s: %s\n", tape_server_name, strerror(errno));
-       return -1;
-    }
-    if (my_port >= IPPORT_RESERVED) {
-       aclose(tape_control_sock);
-       printf("did not get a reserved port: %d\n", my_port);
+
+    /* We assume that amidxtaped support fe_amidxtaped_options_features */
+    /*                               and fe_amidxtaped_options_auth     */
+    /* We should send a noop to really know                             */
+    req = vstralloc("SERVICE amidxtaped\n",
+                   "OPTIONS ", "features=", our_features_string, ";",
+                               "auth=", authopt, ";",
+                   "\n", NULL);
+    protocol_sendreq(tape_server_name, amidxtaped_secdrv,
+                    amidxtaped_client_get_security_conf, req, STARTUP_TIMEOUT,
+                    amidxtaped_response, &response_error);
+    amfree(req);
+    protocol_run();
+    if(response_error != 0) {
        return -1;
     }
-    setegid(getgid());
-    seteuid(getuid());                         /* put it back */
-
-    /* do the security thing */
-    line = get_security();
-    send_to_tape_server(tape_control_sock, line);
-    memset(line, '\0', strlen(line));
-    amfree(line);
 
     disk_regex = alloc(strlen(disk_name) * 2 + 3);
 
@@ -1232,22 +1582,24 @@ int fsf;
        }
     }
     *ch = '\0';
-
     /* push our feature list off to the tape server */
     /* XXX assumes that index server and tape server are equivalent, ew */
+
     if(am_has_feature(indexsrv_features, fe_amidxtaped_exchange_features)){
-       char buffer[32768] = "\0";
-
-       our_feature_string = am_feature_to_string(our_features);
-       tt = newstralloc2(tt, "FEATURES=", our_feature_string);
-       send_to_tape_server(tape_control_sock, tt);
-       if (read(tape_control_sock, buffer, sizeof(buffer)) <= 0) {
-           error("Could not read features from control socket\n");
-           /* NOTREACHED */
+       tt = newstralloc2(tt, "FEATURES=", our_features_string);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
+       get_amidxtaped_line();
+       if(strncmp(amidxtaped_line,"FEATURES=",9) == 0) {
+           tapesrv_features = am_string_to_feature(amidxtaped_line+9);
+       } else {
+           fprintf(stderr, "amrecover - expecting FEATURES line from amidxtaped\n");
+           stop_amidxtaped();
+           amfree(disk_regex);
+           amfree(host_regex);
+           amfree(clean_datestamp);
+           return -1;
        }
-       
-       tapesrv_features = am_string_to_feature(buffer);
-       amfree(our_feature_string);
+       am_release_feature_set(tapesrv_features);
     }
 
 
@@ -1259,29 +1611,29 @@ int fsf;
 
        if(am_has_feature(indexsrv_features, fe_amidxtaped_config)) {
            tt = newstralloc2(tt, "CONFIG=", config);
-           send_to_tape_server(tape_control_sock, tt);
+           send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
        }
        if(am_has_feature(indexsrv_features, fe_amidxtaped_label) &&
           label && label[0] != '/') {
            tt = newstralloc2(tt,"LABEL=",label);
-           send_to_tape_server(tape_control_sock, tt);
+           send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
        }
        if(am_has_feature(indexsrv_features, fe_amidxtaped_fsf)) {
            char v_fsf[100];
-           snprintf(v_fsf, 99, "%d", fsf);
+           snprintf(v_fsf, 99, OFF_T_FMT, (OFF_T_FMT_TYPE)fsf);
            tt = newstralloc2(tt, "FSF=",v_fsf);
-           send_to_tape_server(tape_control_sock, tt);
+           send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
        }
-       send_to_tape_server(tape_control_sock, "HEADER");
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, "HEADER");
        tt = newstralloc2(tt, "DEVICE=", dump_device_name);
-       send_to_tape_server(tape_control_sock, tt);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
        tt = newstralloc2(tt, "HOST=", host_regex);
-       send_to_tape_server(tape_control_sock, tt);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
        tt = newstralloc2(tt, "DISK=", disk_regex);
-       send_to_tape_server(tape_control_sock, tt);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
        tt = newstralloc2(tt, "DATESTAMP=", clean_datestamp);
-       send_to_tape_server(tape_control_sock, tt);
-       send_to_tape_server(tape_control_sock, "END");
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, "END");
        amfree(tt);
     }
     else if(am_has_feature(indexsrv_features, fe_amidxtaped_nargs)) {
@@ -1294,89 +1646,43 @@ int fsf;
         *   "diskname"
         *   "datestamp"
         */
-       send_to_tape_server(tape_control_sock, "6");
-       send_to_tape_server(tape_control_sock, "-h");
-       send_to_tape_server(tape_control_sock, "-p");
-       send_to_tape_server(tape_control_sock, dump_device_name);
-       send_to_tape_server(tape_control_sock, host_regex);
-       send_to_tape_server(tape_control_sock, disk_regex);
-       send_to_tape_server(tape_control_sock, clean_datestamp);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, "6");
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, "-h");
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, "-p");
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, dump_device_name);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, host_regex);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, disk_regex);
+       send_to_tape_server(amidxtaped_streams[CTLFD].fd, clean_datestamp);
 
        dbprintf(("Started amidxtaped with arguments \"6 -h -p %s %s %s %s\"\n",
                  dump_device_name, host_regex, disk_regex, clean_datestamp));
     }
 
-    /*
-     * split-restoring amidxtaped versions will expect to set up a data
-     * connection for dumpfile data, distinct from the socket we're already
-     * using for control data
-     */
-
-    if(am_has_feature(tapesrv_features, fe_recover_splits)){
-       char buffer[32768];
-       int data_port = -1;
-        int nread;
-
-        nread = read(tape_control_sock, buffer, sizeof(buffer));
-
-       if (nread <= 0) {
-           error("Could not read from control socket: %s\n", 
-                  strerror(errno));
-           /* NOTREACHED */
-        }
-
-       buffer[nread] = '\0';
-        if (sscanf(buffer, "CONNECT %d\n", &data_port) != 1) {
-           error("Recieved invalid port number message from control socket: %s\n",
-                  buffer);
-           /* NOTREACHED */
-        }      
-
-       tape_data_sock = stream_client_privileged(server_name,
-                                                 data_port,
-                                                 -1,
-                                                 STREAM_BUFSIZE,
-                                                 &my_data_port,
-                                                 0);
-       if(tape_data_sock == -1){
-           error("Unable to make data connection to server: %s\n",
-                     strerror(errno));
-           /* NOTREACHED */
-       }
-
-       amfree(our_feature_string);
-    
-       line = get_security();
-
-       send_to_tape_server(tape_data_sock, line);
-       memset(line, '\0', strlen(line));
-       amfree(line);
-    }
-
     amfree(disk_regex);
     amfree(host_regex);
     amfree(clean_datestamp);
 
-    return tape_control_sock;
+    return 0;
 }
 
 
-void read_file_header(buffer, file, buflen, tapedev)
-char *buffer;
-dumpfile_t *file;
-size_t buflen;
-int tapedev;
 /*
  * Reads the first block of a tape file.
  */
+
+void
+read_file_header(
+    char *     buffer,
+    dumpfile_t *file,
+    size_t     buflen,
+    int                tapedev)
 {
     ssize_t bytes_read;
-
     bytes_read = read_buffer(tapedev, buffer, buflen, READ_TIMEOUT);
     if(bytes_read < 0) {
        error("error reading header (%s), check amidxtaped.*.debug on server",
              strerror(errno));
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     if((size_t)bytes_read < buflen) {
@@ -1384,18 +1690,26 @@ int tapedev;
                get_pname(), (int)bytes_read, (bytes_read == 1) ? "" : "s");
        print_header(stdout, file);
        error("Can't read file header");
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     /* bytes_read == buflen */
-    parse_file_header(buffer, file, bytes_read);
+    parse_file_header(buffer, file, (size_t)bytes_read);
 }
 
-enum dumptypes {IS_UNKNOWN, IS_DUMP, IS_GNUTAR, IS_TAR, IS_SAMBA, IS_SAMBA_TAR};
-
-static void extract_files_child(in_fd, elist)
-    int in_fd;
-    EXTRACT_LIST *elist;
+enum dumptypes {
+       IS_UNKNOWN,
+       IS_DUMP,
+       IS_GNUTAR,
+       IS_TAR,
+       IS_SAMBA,
+       IS_SAMBA_TAR
+};
+
+static void
+extract_files_child(
+    int                        in_fd,
+    EXTRACT_LIST *     elist)
 {
     int save_errno;
     int extra_params = 0;
@@ -1420,7 +1734,7 @@ static void extract_files_child(in_fd, elist)
     if (dup2(in_fd, STDIN_FILENO) == -1)
     {
        error("dup2 failed in extract_files_child: %s", strerror(errno));
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     /* read the file header */
@@ -1430,7 +1744,7 @@ static void extract_files_child(in_fd, elist)
     if(file.type != F_DUMPFILE) {
        print_header(stdout, &file);
        error("bad header");
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     if (file.program != NULL) {
@@ -1488,8 +1802,8 @@ static void extract_files_child(in_fd, elist)
        break;
     }
 
-    restore_args = (char **)alloc((extra_params + files_off_tape + 1)
-                                 * sizeof(char *));
+    restore_args = (char **)alloc((size_t)((extra_params + files_off_tape + 1)
+                                 * sizeof(char *)));
     switch(dumptype) {
     case IS_SAMBA:
 #ifdef SAMBA_CLIENT
@@ -1663,34 +1977,18 @@ static void extract_files_child(in_fd, elist)
  * some extraction program, really) and the socket from which we're reading, so
  * that we can do things like prompt for human interaction for multiple tapes.
  */
-void writer_intermediary(ctl_fd, data_fd, elist)
-    int ctl_fd, data_fd;
-    EXTRACT_LIST *elist;
+int
+writer_intermediary(
+    EXTRACT_LIST *     elist)
 {
     int child_pipe[2];
     pid_t pid;
-    char buffer[DISK_BLOCK_BYTES];
-    ssize_t s;
-    ssize_t bytes_read;
     amwait_t extractor_status;
-    int max_fd, nfound;
-    fd_set readset, selectset;
-    struct timeval timeout;
-
-    /*
-     * If there's no distinct data channel (such as if we're talking to an
-     * older server), don't bother doing anything complicated.  Just run the
-     * extraction.
-     */
-    if(data_fd == -1){
-       extract_files_child(ctl_fd, elist);
-       /* NOTREACHED */
-    }
 
     if(pipe(child_pipe) == -1) {
        error("extract_list - error setting up pipe to extractor: %s\n",
-           strerror(errno));
-       /* NOTREACHED */
+             strerror(errno));
+       /*NOTREACHED*/
     }
 
     /* okay, ready to extract. fork a child to do the actual work */
@@ -1699,174 +1997,94 @@ void writer_intermediary(ctl_fd, data_fd, elist)
        /* never gets out of this clause */
        aclose(child_pipe[1]);
         extract_files_child(child_pipe[0], elist);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     /* This is the parent */
     if (pid == -1) {
-       error("writer_intermediary - error forking child");
-       /* NOTREACHED */
+       printf("writer_intermediary - error forking child");
+       return -1;
     }
 
     aclose(child_pipe[0]);
 
-    if(data_fd > ctl_fd) max_fd = data_fd+1;
-                    else max_fd = ctl_fd+1;
-    FD_ZERO(&readset);
-    FD_SET(data_fd, &readset);
-    FD_SET(ctl_fd, &readset);
+    security_stream_read(amidxtaped_streams[DATAFD].fd,
+                        read_amidxtaped_data, &(child_pipe[1]));
 
-    do {
-       timeout.tv_sec = READ_TIMEOUT;
-       timeout.tv_usec = 0;
-       FD_COPY(&readset, &selectset);
-        
-       nfound = select(max_fd, (SELECT_ARG_TYPE *)(&selectset), NULL, NULL,
-                       &timeout);
-       if(nfound < 0) {
-           fprintf(stderr,"select error: %s\n", strerror(errno));
-           break;
-       }
-        
-       if (nfound == 0) { /* timeout */
-           fprintf(stderr, "timeout waiting %d seconds for restore\n",
-                   READ_TIMEOUT);
-           fprintf(stderr, "increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n");
-           break;
-       }
-        
-       if(FD_ISSET(ctl_fd, &selectset)) {
-           bytes_read = read(ctl_fd, buffer, sizeof(buffer)-1);
-           switch(bytes_read) {
-            case -1:
-                if ((errno != EINTR) && (errno != EAGAIN)) {
-                    if (errno != EPIPE) {
-                        fprintf(stderr,"writer ctl fd read error: %s",
-                                strerror(errno));
-                    }
-                    FD_CLR(ctl_fd, &readset);
-                }
-                break;
-                
-            case  0:
-                FD_CLR(ctl_fd, &readset);
-                break;
-                
-            default: {
-                char desired_tape[MAX_TAPE_LABEL_BUF];
+    while(get_amidxtaped_line() >= 0) {
+       char desired_tape[MAX_TAPE_LABEL_BUF];
                 
-                buffer[bytes_read] = '\0';
-                /* if prompted for a tape, relay said prompt to the user */
-                if(sscanf(buffer, "FEEDME %s\n", desired_tape) == 1) {
-                    int done = 0;
-                    while (!done) {
-                        char *input = NULL;
-                        printf("Please insert tape %s. Continue? [Y|n]: ",
-                               desired_tape);
-                        fflush(stdout);
-                        
-                        input = agets(stdin); /* strips \n */
-                        if (strcasecmp("", input) == 0|| 
-                            strcasecmp("y", input) == 0|| 
-                            strcasecmp("yes", input) == 0) {
-                            send_to_tape_server(tape_control_sock, "OK");
-                            done = 1;
-                        } else if (strcasecmp("n", input) == 0|| 
-                                   strcasecmp("no", input) == 0) {
-                            send_to_tape_server(tape_control_sock, "ERROR");
-                            /* Abort!
-                               We are the middle process, so just die. */
-                            exit(EXIT_FAILURE);
-                        }
-                        amfree(input);
-                    }
-                } else {
-                    fprintf(stderr, "Strange message from tape server: %s", buffer);
-                    
-                   break;
+       /* if prompted for a tape, relay said prompt to the user */
+       if(sscanf(amidxtaped_line, "FEEDME %132s\n", desired_tape) == 1) {
+           int done;
+           printf("Load tape %s now\n", desired_tape);
+           done = okay_to_continue(am_has_feature(indexsrv_features,
+                                                  fe_amrecover_feedme_tape),
+                                   0, 0);
+           if (done == 1) {
+               if (am_has_feature(indexsrv_features,
+                                  fe_amrecover_feedme_tape)) {
+                   char *reply = stralloc2("TAPE ", tape_device_name);
+                   send_to_tape_server(amidxtaped_streams[CTLFD].fd, reply);
+                   amfree(reply);
+               } else {
+                   send_to_tape_server(amidxtaped_streams[CTLFD].fd, "OK");
                }
+           } else {
+               send_to_tape_server(amidxtaped_streams[CTLFD].fd, "ERROR");
+               break;
            }
-            }
-        }
-            
-        /* now read some dump data */
-        if(FD_ISSET(data_fd, &selectset)) {
-            bytes_read = read(data_fd, buffer, sizeof(buffer)-1);
-            switch(bytes_read) {
-            case -1:
-                if ((errno != EINTR) && (errno != EAGAIN)) {
-                    if (errno != EPIPE) {
-                        fprintf(stderr,"writer data fd read error: %s",
-                                strerror(errno));
-                    }
-                    FD_CLR(data_fd, &readset);
-                }
-                break;
-                
-            case  0:
-                FD_CLR(data_fd, &readset);
-                break;
-                
-            default:
-                /*
-                 * spit what we got from the server to the child
-                 *  process handling actual dumpfile extraction
-                 */
-                if((s = fullwrite(child_pipe[1], buffer, bytes_read)) < 0){
-                    if(errno == EPIPE) {
-                        error("%s: pipe data reader has quit: %s\n",
-                              get_pname(), strerror(errno));
-                        /* NOTREACHED */
-                    }
-                    error("Write error to extract child: %s\n",
-                          strerror(errno));
-                    /* NOTREACHED */
-                }
-                break;
-           }
+       } else if(strncmp(amidxtaped_line, "MESSAGE ", 8) == 0) {
+           printf("%s\n",&amidxtaped_line[8]);
+       } else {
+           fprintf(stderr, "Strange message from tape server: %s",
+                   amidxtaped_line);
+           break;
        }
-    } while(FD_ISSET(ctl_fd, &readset) || FD_ISSET(data_fd, &readset));
+    }
 
+    /* CTL might be close before DATA */
+    event_loop(0);
     aclose(child_pipe[1]);
 
     waitpid(pid, &extractor_status, 0);
     if(WEXITSTATUS(extractor_status) != 0){
        int ret = WEXITSTATUS(extractor_status);
         if(ret == 255) ret = -1;
-       error("Extractor child exited with status %d\n", ret);
-       /* NOTREACHED */
+       printf("Extractor child exited with status %d\n", ret);
+       return -1;
     }
-
-    exit(0);
+    return(0);
 }
 
 /* exec restore to do the actual restoration */
 
 /* does the actual extraction of files */
-/* The original design had the dump image being returned exactly as it
-   appears on the tape, and this routine getting from the index server
-   whether or not it is compressed, on the assumption that the tape
-   server may not know how to uncompress it. But
-   - Amrestore can't do that. It returns either compressed or uncompressed
-   (always). Amrestore assumes it can uncompress files. It is thus a good
-   idea to run the tape server on a machine with gzip.
-   - The information about compression in the disklist is really only
-   for future dumps. It is possible to change compression on a drive
-   so the information in the disklist may not necessarily relate to
-   the dump image on the tape.
-     Consequently the design was changed to assuming that amrestore can
-   uncompress any dump image and have it return an uncompressed file
-   always. */
-void extract_files P((void))
+/*
+ * The original design had the dump image being returned exactly as it
+ * appears on the tape, and this routine getting from the index server
+ * whether or not it is compressed, on the assumption that the tape
+ * server may not know how to uncompress it. But
+ * - Amrestore can't do that. It returns either compressed or uncompressed
+ * (always). Amrestore assumes it can uncompress files. It is thus a good
+ * idea to run the tape server on a machine with gzip.
+ * - The information about compression in the disklist is really only
+ * for future dumps. It is possible to change compression on a drive
+ * so the information in the disklist may not necessarily relate to
+ * the dump image on the tape.
+ *   Consequently the design was changed to assuming that amrestore can
+ * uncompress any dump image and have it return an uncompressed file
+ * always.
+ */
+void
+extract_files(void)
 {
     EXTRACT_LIST *elist;
-    pid_t pid;
-    amwait_t child_stat;
-    char buf[STR_SIZE];
+    char cwd[STR_SIZE];
     char *l;
     int first;
     int otc;
-    tapelist_t *tlist = NULL;
+    tapelist_t *tlist = NULL, *a_tlist;
 
     if (!is_extract_list_nonempty())
     {
@@ -1874,6 +2092,8 @@ void extract_files P((void))
        return;
     }
 
+    clean_extract_list();
+
     /* get tape device name from index server if none specified */
     if (tape_server_name == NULL) {
        tape_server_name = newstralloc(tape_server_name, server_name);
@@ -1900,7 +2120,7 @@ void extract_files P((void))
     }
 
     first=1;
-    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))
+    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist)) {
        if(elist->tape[0]!='/') {
            if(first) {
                printf("\nExtracting files using tape drive %s on host %s.\n",
@@ -1911,13 +2131,14 @@ void extract_files P((void))
            else
                printf("                               ");
            tlist = unmarshal_tapelist_str(elist->tape); 
-           for( ; tlist != NULL; tlist = tlist->next)
-               printf(" %s", tlist->label);
+           for(a_tlist = tlist ; a_tlist != NULL; a_tlist = a_tlist->next)
+               printf(" %s", a_tlist->label);
            printf("\n");
-           amfree(tlist);
+           free_tapelist(tlist);
        }
+    }
     first=1;
-    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))
+    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist)) {
        if(elist->tape[0]=='/') {
            if(first) {
                printf("\nExtracting files from holding disk on host %s.\n",
@@ -1928,14 +2149,22 @@ void extract_files P((void))
            else
                printf("                               ");
            tlist = unmarshal_tapelist_str(elist->tape); 
-           for( ; tlist != NULL; tlist = tlist->next)
-               printf(" %s", tlist->label);
+           for(a_tlist = tlist; a_tlist != NULL; a_tlist = a_tlist->next)
+               printf(" %s", a_tlist->label);
            printf("\n");
-           amfree(tlist);
+           free_tapelist(tlist);
        }
+    }
     printf("\n");
-    getcwd(buf, sizeof(buf));
-    printf("Restoring files into directory %s\n", buf);
+
+    if (getcwd(cwd, sizeof(cwd)) == NULL) {
+       perror("extract_list: Current working directory unavailable");
+       exit(1);
+    }
+
+    printf("Restoring files into directory %s\n", cwd);
+    check_file_overwrite(cwd);
+
 #ifdef SAMBA_CLIENT
     if (samba_extract_method == SAMBA_SMBCLIENT)
       printf("(unless it is a Samba backup, that will go through to the SMB server)\n");
@@ -1944,23 +2173,30 @@ void extract_files P((void))
        return;
     printf("\n");
 
+    if (!do_unlink_list()) {
+       fprintf(stderr, "Can't recover because I can't cleanup the cwd (%s)\n",
+               cwd);
+       return;
+    }
+    free_unlink_list();
+
     while ((elist = first_tape_list()) != NULL)
     {
        if(elist->tape[0]=='/') {
            dump_device_name = newstralloc(dump_device_name, elist->tape);
            printf("Extracting from file ");
            tlist = unmarshal_tapelist_str(dump_device_name); 
-           for( ; tlist != NULL; tlist = tlist->next)
-               printf(" %s", tlist->label);
+           for(a_tlist = tlist; a_tlist != NULL; a_tlist = a_tlist->next)
+               printf(" %s", a_tlist->label);
            printf("\n");
-           amfree(tlist);
+           free_tapelist(tlist);
        }
        else {
            printf("Extracting files using tape drive %s on host %s.\n",
                   tape_device_name, tape_server_name);
            tlist = unmarshal_tapelist_str(elist->tape); 
            printf("Load tape %s now\n", tlist->label);
-           amfree(tlist);
+           free_tapelist(tlist);
            otc = okay_to_continue(1,1,0);
            if (otc == 0)
                return;
@@ -1973,66 +2209,347 @@ void extract_files P((void))
        dump_datestamp = newstralloc(dump_datestamp, elist->date);
 
        /* connect to the tape handler daemon on the tape drive server */
-       if ((tape_control_sock = extract_files_setup(elist->tape, elist->fileno)) == -1)
+       if ((extract_files_setup(elist->tape, elist->fileno)) == -1)
        {
            fprintf(stderr, "amrecover - can't talk to tape server\n");
            return;
        }
 
-       /* okay, ready to extract. fork a child to do the actual work */
-       if ((pid = fork()) == 0)
-       {
-           /* this is the child process */
-           /* never gets out of this clause */
-           writer_intermediary(tape_control_sock, tape_data_sock, elist);
-           /*NOT REACHED*/
-       }
-       /* this is the parent */
-       if (pid == -1)
-       {
-           perror("extract_list - error forking child");
-           exit(1);
-       }
+       /* if the server have fe_amrecover_feedme_tape, it has asked for
+        * the tape itself, even if the restore didn't succeed, we should
+        * remove it.
+        */
+       if(writer_intermediary(elist) == 0 ||
+          am_has_feature(indexsrv_features, fe_amrecover_feedme_tape))
+           delete_tape_list(elist);    /* tape done so delete from list */
 
-       /* store the child pid globally so that it can be killed on intr */
-       extract_restore_child_pid = pid;
+       stop_amidxtaped();
+    }
+}
 
-       /* wait for the child process to finish */
-       if ((pid = waitpid(-1, &child_stat, 0)) == (pid_t)-1)
-       {
-           perror("extract_list - error waiting for child");
-           exit(1);
-       }
+static void
+amidxtaped_response(
+    void *             datap,
+    pkt_t *            pkt,
+    security_handle_t *        sech)
+{
+    int ports[NSTREAMS], *response_error = datap, i;
+    char *p;
+    char *tok;
+    char *extra = NULL;
+
+    assert(response_error != NULL);
+    assert(sech != NULL);
+    memset(ports, -1, SIZEOF(ports));
+
+    security_close_connection(sech, dump_hostname);
+    if (pkt == NULL) {
+       errstr = newvstralloc(errstr, "[request failed: ",
+                            security_geterror(sech), "]", NULL);
+       *response_error = 1;
+       return;
+    }
+
+    if (pkt->type == P_NAK) {
+#if defined(PACKET_DEBUG)
+       fprintf(stderr, "got nak response:\n----\n%s\n----\n\n", pkt->body);
+#endif
+
+       tok = strtok(pkt->body, " ");
+       if (tok == NULL || strcmp(tok, "ERROR") != 0)
+           goto bad_nak;
 
-       if(tape_data_sock != -1) {
-           aclose(tape_data_sock);
+       tok = strtok(NULL, "\n");
+       if (tok != NULL) {
+           errstr = newvstralloc(errstr, "NAK: ", tok, NULL);
+           *response_error = 1;
+       } else {
+bad_nak:
+           errstr = newstralloc(errstr, "request NAK");
+           *response_error = 2;
        }
+       return;
+    }
 
-       if (pid == extract_restore_child_pid)
-       {
-           extract_restore_child_pid = -1;
+    if (pkt->type != P_REP) {
+       errstr = newvstralloc(errstr, "received strange packet type ",
+                             pkt_type2str(pkt->type), ": ", pkt->body, NULL);
+       *response_error = 1;
+       return;
+    }
+
+#if defined(PACKET_DEBUG)
+    fprintf(stderr, "got response:\n----\n%s\n----\n\n", pkt->body);
+#endif
+
+    for(i = 0; i < NSTREAMS; i++) {
+        ports[i] = -1;
+        amidxtaped_streams[i].fd = NULL;
+    }
+
+    p = pkt->body;
+    while((tok = strtok(p, " \n")) != NULL) {
+       p = NULL;
+
+       /*
+        * Error response packets have "ERROR" followed by the error message
+        * followed by a newline.
+        */
+       if (strcmp(tok, "ERROR") == 0) {
+           tok = strtok(NULL, "\n");
+           if (tok == NULL)
+               tok = "[bogus error packet]";
+           errstr = newstralloc(errstr, tok);
+           *response_error = 2;
+           return;
        }
-       else
-       {
-           fprintf(stderr, "extract list - unknown child terminated?\n");
-           exit(1);
+
+
+        /*
+         * Regular packets have CONNECT followed by three streams
+         */
+        if (strcmp(tok, "CONNECT") == 0) {
+
+           /*
+            * Parse the three stream specifiers out of the packet.
+            */
+           for (i = 0; i < NSTREAMS; i++) {
+               tok = strtok(NULL, " ");
+               if (tok == NULL || strcmp(tok, amidxtaped_streams[i].name) != 0) {
+                   extra = vstralloc("CONNECT token is \"",
+                                     tok ? tok : "(null)",
+                                     "\": expected \"",
+                                     amidxtaped_streams[i].name,
+                                     "\"",
+                                     NULL);
+                   goto parse_error;
+               }
+               tok = strtok(NULL, " \n");
+               if (tok == NULL || sscanf(tok, "%d", &ports[i]) != 1) {
+                   extra = vstralloc("CONNECT ",
+                                     amidxtaped_streams[i].name,
+                                     " token is \"",
+                                     tok ? tok : "(null)",
+                                     "\": expected a port number",
+                                     NULL);
+                   goto parse_error;
+               }
+           }
+           continue;
        }
-       if ((WIFEXITED(child_stat) != 0) && (WEXITSTATUS(child_stat) != 0))
-       {
-           fprintf(stderr,
-                   "extract_list - child returned non-zero status: %d\n",
-                   WEXITSTATUS(child_stat));
-           otc = okay_to_continue(0,0,1);
-           if(otc == 0)
-               return;
-           else if(otc == 1) {
-               delete_tape_list(elist); /* tape failed so delete from list */
+
+       /*
+        * OPTIONS [options string] '\n'
+        */
+       if (strcmp(tok, "OPTIONS") == 0) {
+           tok = strtok(NULL, "\n");
+           if (tok == NULL) {
+               extra = stralloc("OPTIONS token is missing");
+               goto parse_error;
            }
-           else { /* RETRY_TAPE */
+/*
+           while((p = strchr(tok, ';')) != NULL) {
+               *p++ = '\0';
+#define sc "features="
+               if(strncmp(tok, sc, sizeof(sc)-1) == 0) {
+                   tok += sizeof(sc) - 1;
+#undef sc
+                   am_release_feature_set(their_features);
+                   if((their_features = am_string_to_feature(tok)) == NULL) {
+                       errstr = newvstralloc(errstr,
+                                             "OPTIONS: bad features value: ",
+                                             tok,
+                                             NULL);
+                       goto parse_error;
+                   }
+               }
+               tok = p;
            }
+*/
+           continue;
        }
-       else {
-           delete_tape_list(elist);    /* tape done so delete from list */
+/*
+       extra = vstralloc("next token is \"",
+                         tok ? tok : "(null)",
+                         "\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\"",
+                         NULL);
+       goto parse_error;
+*/
+    }
+
+    /*
+     * Connect the streams to their remote ports
+     */
+    for (i = 0; i < NSTREAMS; i++) {
+       if (ports[i] == -1)
+           continue;
+       amidxtaped_streams[i].fd = security_stream_client(sech, ports[i]);
+       dbprintf(("amidxtaped_streams[%d].fd = %p\n",i, amidxtaped_streams[i].fd));
+       if (amidxtaped_streams[i].fd == NULL) {
+           errstr = newvstralloc(errstr,
+                       "[could not connect ", amidxtaped_streams[i].name, " stream: ",
+                       security_geterror(sech), "]", NULL);
+           goto connect_error;
        }
     }
+    /*
+     * Authenticate the streams
+     */
+    for (i = 0; i < NSTREAMS; i++) {
+       if (amidxtaped_streams[i].fd == NULL)
+           continue;
+       if (security_stream_auth(amidxtaped_streams[i].fd) < 0) {
+           errstr = newvstralloc(errstr,
+               "[could not authenticate ", amidxtaped_streams[i].name, " stream: ",
+               security_stream_geterror(amidxtaped_streams[i].fd), "]", NULL);
+           goto connect_error;
+       }
+    }
+
+    /*
+     * The CTLFD and DATAFD streams are mandatory.  If we didn't get
+     * them, complain.
+     */
+    if (amidxtaped_streams[CTLFD].fd == NULL) {
+        errstr = newstralloc(errstr, "[couldn't open CTL streams]");
+        goto connect_error;
+    }
+    if (amidxtaped_streams[DATAFD].fd == NULL) {
+        errstr = newstralloc(errstr, "[couldn't open DATA streams]");
+        goto connect_error;
+    }
+
+    /* everything worked */
+    *response_error = 0;
+    return;
+
+parse_error:
+    errstr = newvstralloc(errstr,
+                         "[parse of reply message failed: ",
+                         extra ? extra : "(no additional information)",
+                         "]",
+                         NULL);
+    amfree(extra);
+    *response_error = 2;
+    return;
+
+connect_error:
+    stop_amidxtaped();
+    *response_error = 1;
+}
+
+/*
+ * This is called when everything needs to shut down so event_loop()
+ * will exit.
+ */
+static void
+stop_amidxtaped(void)
+{
+    int i;
+
+    for (i = 0; i < NSTREAMS; i++) {
+        if (amidxtaped_streams[i].fd != NULL) {
+            security_stream_close(amidxtaped_streams[i].fd);
+            amidxtaped_streams[i].fd = NULL;
+        }
+    }
+}
+
+static char* ctl_buffer = NULL;
+/* gets a "line" from server and put in server_line */
+/* server_line is terminated with \0, \r\n is striped */
+/* returns -1 if error */
+
+int
+get_amidxtaped_line(void)
+{
+    ssize_t size;
+    char *newbuf, *s;
+    void *buf;
+
+    amfree(amidxtaped_line);
+    if (!ctl_buffer)
+       ctl_buffer = stralloc("");
+
+    while (!strstr(ctl_buffer,"\r\n")) {
+        size = security_stream_read_sync(amidxtaped_streams[CTLFD].fd, &buf);
+        if(size < 0) {
+            return -1;
+        }
+        else if(size == 0) {
+            return -1;
+        }
+        newbuf = alloc(strlen(ctl_buffer)+size+1);
+        strncpy(newbuf, ctl_buffer, (size_t)(strlen(ctl_buffer) + size + 1));
+        memcpy(newbuf+strlen(ctl_buffer), buf, (size_t)size);
+        newbuf[strlen(ctl_buffer)+size] = '\0';
+        amfree(ctl_buffer);
+        ctl_buffer = newbuf;
+    }
+
+    s = strstr(ctl_buffer,"\r\n");
+    *s = '\0';
+    newbuf = stralloc(s+2);
+    amidxtaped_line = stralloc(ctl_buffer);
+    amfree(ctl_buffer);
+    ctl_buffer = newbuf;
+    return 0;
+}
+
+
+static void
+read_amidxtaped_data(
+    void *     cookie,
+    void *     buf,
+    ssize_t    size)
+{
+    int fd;
+
+    assert(cookie != NULL);
+
+    fd = *(int *)cookie;
+    if (size < 0) {
+       errstr = newstralloc2(errstr, "amidxtaped read: ",
+                security_stream_geterror(amidxtaped_streams[DATAFD].fd));
+       return;
+    }
+
+    /*
+     * EOF.  Stop and return.
+     */
+    if (size == 0) {
+       security_stream_close(amidxtaped_streams[DATAFD].fd);
+       amidxtaped_streams[DATAFD].fd = NULL;
+       /*
+        * If the mesg fd has also shut down, then we're done.
+        */
+       return;
+    }
+
+    assert(buf != NULL);
+
+    /*
+     * We ignore errors while writing to the index file.
+     */
+    (void)fullwrite(fd, buf, (size_t)size);
+    security_stream_read(amidxtaped_streams[DATAFD].fd, read_amidxtaped_data, cookie);
+}
+
+char *
+amidxtaped_client_get_security_conf(
+    char *     string,
+    void *     arg)
+{
+    (void)arg; /* Quiet unused parameter warning */
+
+    if(!string || !*string)
+       return(NULL);
+
+    if(strcmp(string, "auth")==0) {
+       return(client_getconf_str(CLN_AUTH));
+    }
+    if(strcmp(string, "ssh_keys")==0) {
+       return(client_getconf_str(CLN_SSH_KEYS));
+    }
+    return(NULL);
 }
index a89759b971a6dd08719ffbbc2d044eb2a62b7500..02690158827ac191d9660732e1e0b117b4e666ab 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: help.c,v 1.8 2002/03/06 19:23:20 martinea Exp $
+ * $Id: help.c,v 1.12 2006/05/25 01:47:14 johnfranks Exp $
  *
  * implements the "help" command in amrecover
  */
 
+#include "amanda.h"
 #include "amrecover.h"
 
 /* print a list of valid commands */
-void help_list P((void))
+void
+help_list(void)
 {
     printf("valid commands are:\n\n");
 
@@ -54,11 +56,13 @@ void help_list P((void))
     printf("mode              - show the method used to extract SMB shares\n");
     printf("pwd               - show cwd on virtual file system\n");
     printf("quit\n");
-    printf("listdisk [diskdevice] - list disks\n");
+    printf("listhost          - list hosts\n");
+    printf("listdisk [diskdevice]              - list disks\n");
     printf("setdate {YYYY-MM-DD|--MM-DD|---DD} - set date of look\n");
-    printf("setdisk diskname [mountpoint] - select disk on dump host\n");
-    printf("sethost host      - select dump host\n");
-    printf("settape [host:][device|default] - select tape server and/or device\n");
-    printf("setmode smb|tar   - select the method used to extract SMB shares\n");
+    printf("        {YYYY-MM-DD-HH-MM-SS}      - set date of look\n");
+    printf("setdisk diskname [mountpoint]      - select disk on dump host\n");
+    printf("sethost host                       - select dump host\n");
+    printf("settape [host:][device|default]    - select tape server and/or device\n");
+    printf("setmode smb|tar                 - select the method used to extract SMB shares\n");
     printf("\n");
 }
index 65163a7450134b090bfacd3fa0ed5410c29d835e..a3840a380520bb4c36d886ebff691e638a5d3bfb 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: set_commands.c,v 1.23 2004/02/11 13:15:18 martinea Exp $
+ * $Id: set_commands.c,v 1.26 2006/07/05 13:14:58 martinea Exp $
  *
  * implements the "set" commands in amrecover
  */
@@ -37,8 +37,9 @@ extern unsigned short samba_extract_method;
 #endif /* SAMBA_CLIENT */
 
 /* sets a date, mapping given date into standard form if needed */
-int set_date(date)
-char *date;
+int
+set_date(
+    char *     date)
 {
     char *cmd = NULL;
 
@@ -68,13 +69,13 @@ char *date;
        }
     }
     amfree(cmd);
-
     return 0;
 }
 
 
-void set_host(host)
-char *host;
+void
+set_host(
+    const char *host)
 {
     char *cmd = NULL;
     struct hostent *hp;
@@ -138,10 +139,21 @@ char *host;
     amfree(cmd);
 }
 
+void
+list_host(void)
+{
+    char *cmd = NULL;
+
+    cmd = stralloc("LISTHOST");
+    if (converse(cmd) == -1)
+        exit(1);
+    amfree(cmd);
+}
 
-void set_disk(dsk, mtpt)
-char *dsk;
-char *mtpt;
+void
+set_disk(
+    char *     dsk,
+    char *     mtpt)
 {
     char *cmd = NULL;
 
@@ -209,8 +221,9 @@ char *mtpt;
     }
 }
 
-void list_disk(amdevice)
-char *amdevice;
+void
+list_disk(
+    char *     amdevice)
 {
     char *cmd = NULL;
 
@@ -228,8 +241,9 @@ char *amdevice;
     }
 }
 
-void cd_glob(glob)
-char *glob;
+void
+cd_glob(
+    char *     glob)
 {
     char *regex;
     char *regex_path;
@@ -278,8 +292,9 @@ char *glob;
     amfree(path_on_disk);
 }
 
-void cd_regex(regex)
-char *regex;
+void
+cd_regex(
+    char *     regex)
 {
     char *s;
 
@@ -310,9 +325,10 @@ char *regex;
     amfree(path_on_disk);
 }
 
-void cd_dir(path_on_disk, default_dir)
-char *path_on_disk;
-char *default_dir;
+void
+cd_dir(
+    char *     path_on_disk,
+    char *     default_dir)
 {
     char *path_on_disk_slash = NULL;
     char *dir = NULL;
@@ -343,10 +359,12 @@ char *default_dir;
                    dir[strlen(dir)-1] = '\0'; /* remove last / */
                /* remove everything before the last / */
                dir1 = rindex(dir,'/');
-               dir1++;
-               dir2 = stralloc(dir1);
-               amfree(dir);
-               dir = dir2;
+               if (dir1) {
+                   dir1++;
+                   dir2 = stralloc(dir1);
+                   amfree(dir);
+                   dir = dir2;
+               }
            }
        }
     }
@@ -364,8 +382,9 @@ char *default_dir;
     amfree(dir);
 }
 
-void set_directory(dir)
-char *dir;
+void
+set_directory(
+    char *     dir)
 {
     char *cmd = NULL;
     char *new_dir = NULL;
@@ -376,11 +395,13 @@ char *dir;
     if(strcmp(dir,".")==0) {
        show_directory();               /* say where we are */
        return;
+       /*NOTREACHED*/
     }
 
     if (disk_name == NULL) {
        printf("Must select disk before setting directory\n");
        return;
+       /*NOTREACHED*/
     }
 
     ldir = stralloc(dir);
@@ -402,6 +423,7 @@ char *dir;
                       mount_point);
                amfree(ldir);
                return;
+               /*NOTREACHED*/
            }
            new_dir = stralloc(ldir+strlen(mount_point));
            if (strlen(new_dir) == 0) {
@@ -435,9 +457,12 @@ char *dir;
                /* at top of disk */
                printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
                       mount_point);
+               /*@ignore@*/
                amfree(new_dir);
+               /*@end@*/
                amfree(ldir);
                return;
+               /*NOTREACHED*/
            }
            de = strrchr(new_dir, '/'); /* always at least 1 */
            if (de == new_dir)
@@ -450,17 +475,22 @@ char *dir;
                *de = '\0';
            }
        } else {
+           /*@ignore@*/
            if (strcmp(new_dir, "/") != 0) {
                strappend(new_dir, "/");
            }
            strappend(new_dir, ldir);
+           /*@end@*/
        }
     }
 
     cmd = stralloc2("OISD ", new_dir);
-    if (exchange(cmd) == -1)
+    if (exchange(cmd) == -1) {
        exit(1);
+       /*NOTREACHED*/
+    }
     amfree(cmd);
+
     if (server_happy())
     {
        disk_path = newstralloc(disk_path, new_dir);
@@ -472,13 +502,16 @@ char *dir;
        printf("Invalid directory - %s\n", dir);
     }
 
+    /*@ignore@*/
     amfree(new_dir);
     amfree(ldir);
+    /*@end@*/
 }
 
 
 /* prints the current working directory */
-void show_directory P((void))
+void
+show_directory(void)
 {
     if (mount_point == NULL || disk_path == NULL)
         printf("Must select disk first\n");
@@ -492,8 +525,9 @@ void show_directory P((void))
 
 
 /* set the tape server and device */
-void set_tape (tape)
-    char *tape;
+void
+set_tape(
+    char *     tape)
 {
     char *tapedev = strchr(tape, ':');
 
@@ -539,8 +573,9 @@ void set_tape (tape)
                server_name);
 }
 
-void set_mode (mode)
-int mode;
+void
+set_mode(
+    int                mode)
 {
 #ifdef SAMBA_CLIENT
   if (mode == SAMBA_SMBCLIENT) {
@@ -552,10 +587,13 @@ int mode;
       samba_extract_method = SAMBA_TAR;
     }
   }
+#else
+  (void)mode;  /* Quiet unused parameter warning */
 #endif /* SAMBA_CLIENT */
 }
 
-void show_mode (void) 
+void
+show_mode(void) 
 {
 #ifdef SAMBA_CLIENT
   printf ("SAMBA dumps are extracted ");
index c618a6340b2d563a92e81f7db091f01f8bdde32b..c7c39eff4d8ed5a1916ad432be8bcf3ad49ca4b9 100644 (file)
    /* Put the tokens into the symbol table, so that GDB and other debuggers
       know about them.  */
    enum yytokentype {
-     LISTDISK = 258,
-     SETHOST = 259,
-     SETDISK = 260,
-     SETDATE = 261,
-     SETTAPE = 262,
-     SETMODE = 263,
-     CD = 264,
-     CDX = 265,
-     QUIT = 266,
-     DHIST = 267,
-     LS = 268,
-     ADD = 269,
-     ADDX = 270,
-     EXTRACT = 271,
-     LIST = 272,
-     DELETE = 273,
-     DELETEX = 274,
-     PWD = 275,
-     CLEAR = 276,
-     HELP = 277,
-     LCD = 278,
-     LPWD = 279,
-     MODE = 280,
-     SMB = 281,
-     TAR = 282,
-     PATH = 283,
-     DATE = 284
+     LISTHOST = 258,
+     LISTDISK = 259,
+     SETHOST = 260,
+     SETDISK = 261,
+     SETDATE = 262,
+     SETTAPE = 263,
+     SETMODE = 264,
+     CD = 265,
+     CDX = 266,
+     QUIT = 267,
+     DHIST = 268,
+     LS = 269,
+     ADD = 270,
+     ADDX = 271,
+     EXTRACT = 272,
+     LIST = 273,
+     DELETE = 274,
+     DELETEX = 275,
+     PWD = 276,
+     CLEAR = 277,
+     HELP = 278,
+     LCD = 279,
+     LPWD = 280,
+     MODE = 281,
+     SMB = 282,
+     TAR = 283,
+     PATH = 284,
+     DATE = 285
    };
 #endif
 /* Tokens.  */
-#define LISTDISK 258
-#define SETHOST 259
-#define SETDISK 260
-#define SETDATE 261
-#define SETTAPE 262
-#define SETMODE 263
-#define CD 264
-#define CDX 265
-#define QUIT 266
-#define DHIST 267
-#define LS 268
-#define ADD 269
-#define ADDX 270
-#define EXTRACT 271
-#define LIST 272
-#define DELETE 273
-#define DELETEX 274
-#define PWD 275
-#define CLEAR 276
-#define HELP 277
-#define LCD 278
-#define LPWD 279
-#define MODE 280
-#define SMB 281
-#define TAR 282
-#define PATH 283
-#define DATE 284
+#define LISTHOST 258
+#define LISTDISK 259
+#define SETHOST 260
+#define SETDISK 261
+#define SETDATE 262
+#define SETTAPE 263
+#define SETMODE 264
+#define CD 265
+#define CDX 266
+#define QUIT 267
+#define DHIST 268
+#define LS 269
+#define ADD 270
+#define ADDX 271
+#define EXTRACT 272
+#define LIST 273
+#define DELETE 274
+#define DELETEX 275
+#define PWD 276
+#define CLEAR 277
+#define HELP 278
+#define LCD 279
+#define LPWD 280
+#define MODE 281
+#define SMB 282
+#define TAR 283
+#define PATH 284
+#define DATE 285
 
 
 
 #include "amanda.h"
 #include "amrecover.h"
 
-void yyerror P((char *s));
-extern int yylex P((void));
+void           yyerror(char *s);
+extern int     yylex(void);
+extern char *  yytext;
+
 
 
 /* Enabling traces.  */
@@ -146,15 +150,15 @@ extern int yylex P((void));
 #endif
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 40 "uparse.y"
+#line 42 "uparse.y"
 typedef union YYSTYPE {
-  int intval;
-  double floatval;
-  char *strval;
-  int subtok;
+       int     intval;
+       double  floatval;
+       char *  strval;
+       int     subtok;
 } YYSTYPE;
 /* Line 196 of yacc.c.  */
-#line 158 "uparse.c"
+#line 162 "uparse.c"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -166,7 +170,7 @@ typedef union YYSTYPE {
 
 
 /* Line 219 of yacc.c.  */
-#line 170 "uparse.c"
+#line 174 "uparse.c"
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
 # define YYSIZE_T __SIZE_TYPE__
@@ -315,22 +319,22 @@ union yyalloc
 #endif
 
 /* YYFINAL -- State number of the termination state. */
-#define YYFINAL  54
+#define YYFINAL  55
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   44
+#define YYLAST   45
 
 /* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  30
+#define YYNTOKENS  31
 /* YYNNTS -- Number of nonterminals. */
 #define YYNNTS  16
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  47
+#define YYNRULES  49
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  60
+#define YYNSTATES  61
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   284
+#define YYMAXUTOK   285
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -366,7 +370,7 @@ static const unsigned char yytranslate[] =
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29
+      25,    26,    27,    28,    29,    30
 };
 
 #if YYDEBUG
@@ -375,37 +379,37 @@ static const unsigned char yytranslate[] =
 static const unsigned char yyprhs[] =
 {
        0,     0,     3,     5,     7,     9,    11,    13,    15,    17,
-      19,    21,    23,    26,    28,    31,    34,    38,    41,    44,
-      46,    49,    52,    55,    58,    60,    62,    65,    67,    69,
-      71,    73,    75,    78,    81,    83,    86,    89,    91,    94,
-      97,    99,   102,   105,   107,   109,   112,   114
+      19,    21,    23,    24,    26,    29,    31,    34,    37,    41,
+      44,    47,    49,    52,    55,    58,    61,    63,    65,    68,
+      70,    72,    74,    76,    78,    81,    84,    86,    89,    92,
+      94,    97,   100,   102,   105,   108,   110,   112,   115,   117
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const yysigned_char yyrhs[] =
 {
-      31,     0,    -1,    32,    -1,    33,    -1,    34,    -1,    35,
-      -1,    37,    -1,    39,    -1,    41,    -1,    43,    -1,    44,
-      -1,    45,    -1,     3,    28,    -1,     3,    -1,     6,    29,
-      -1,     4,    28,    -1,     5,    28,    28,    -1,     5,    28,
-      -1,     7,    28,    -1,     7,    -1,     9,    28,    -1,    10,
-      28,    -1,     8,    26,    -1,     8,    27,    -1,    12,    -1,
-      13,    -1,    17,    28,    -1,    17,    -1,    20,    -1,    21,
-      -1,    25,    -1,    11,    -1,    14,    36,    -1,    36,    28,
-      -1,    28,    -1,    15,    38,    -1,    38,    28,    -1,    28,
-      -1,    18,    40,    -1,    40,    28,    -1,    28,    -1,    19,
-      42,    -1,    42,    28,    -1,    28,    -1,    24,    -1,    23,
-      28,    -1,    22,    -1,    16,    -1
+      32,     0,    -1,    33,    -1,    34,    -1,    35,    -1,    36,
+      -1,    38,    -1,    40,    -1,    42,    -1,    44,    -1,    45,
+      -1,    46,    -1,    -1,     3,    -1,     4,    29,    -1,     4,
+      -1,     7,    30,    -1,     5,    29,    -1,     6,    29,    29,
+      -1,     6,    29,    -1,     8,    29,    -1,     8,    -1,    10,
+      29,    -1,    11,    29,    -1,     9,    27,    -1,     9,    28,
+      -1,    13,    -1,    14,    -1,    18,    29,    -1,    18,    -1,
+      21,    -1,    22,    -1,    26,    -1,    12,    -1,    15,    37,
+      -1,    37,    29,    -1,    29,    -1,    16,    39,    -1,    39,
+      29,    -1,    29,    -1,    19,    41,    -1,    41,    29,    -1,
+      29,    -1,    20,    43,    -1,    43,    29,    -1,    29,    -1,
+      25,    -1,    24,    29,    -1,    23,    -1,    17,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned char yyrline[] =
 {
-       0,    63,    63,    64,    65,    66,    67,    68,    69,    70,
-      71,    72,    76,    77,    78,    79,    80,    81,    82,    83,
-      84,    85,    86,    91,    99,   100,   101,   102,   103,   104,
-     105,   109,   113,   117,   118,   122,   126,   127,   131,   135,
-     136,   140,   144,   145,   149,   150,   159,   163
+       0,    65,    65,    66,    67,    68,    69,    70,    71,    72,
+      73,    74,    75,    84,    85,    86,    87,    88,    89,    90,
+      91,    92,    93,    94,    95,   100,   108,   109,   110,   111,
+     112,   113,   114,   118,   122,   126,   127,   131,   135,   136,
+     140,   144,   145,   149,   153,   154,   158,   159,   168,   172
 };
 #endif
 
@@ -414,11 +418,11 @@ static const unsigned char yyrline[] =
    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
 static const char *const yytname[] =
 {
-  "$end", "error", "$undefined", "LISTDISK", "SETHOST", "SETDISK",
-  "SETDATE", "SETTAPE", "SETMODE", "CD", "CDX", "QUIT", "DHIST", "LS",
-  "ADD", "ADDX", "EXTRACT", "LIST", "DELETE", "DELETEX", "PWD", "CLEAR",
-  "HELP", "LCD", "LPWD", "MODE", "SMB", "TAR", "PATH", "DATE", "$accept",
-  "ucommand", "set_command", "display_command", "quit_command",
+  "$end", "error", "$undefined", "LISTHOST", "LISTDISK", "SETHOST",
+  "SETDISK", "SETDATE", "SETTAPE", "SETMODE", "CD", "CDX", "QUIT", "DHIST",
+  "LS", "ADD", "ADDX", "EXTRACT", "LIST", "DELETE", "DELETEX", "PWD",
+  "CLEAR", "HELP", "LCD", "LPWD", "MODE", "SMB", "TAR", "PATH", "DATE",
+  "$accept", "ucommand", "set_command", "display_command", "quit_command",
   "add_command", "add_path", "addx_command", "addx_path", "delete_command",
   "delete_path", "deletex_command", "deletex_path", "local_command",
   "help_command", "extract_command", 0
@@ -432,28 +436,29 @@ static const unsigned short int yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,   279,   280,   281,   282,   283,   284
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const unsigned char yyr1[] =
 {
-       0,    30,    31,    31,    31,    31,    31,    31,    31,    31,
-      31,    31,    32,    32,    32,    32,    32,    32,    32,    32,
-      32,    32,    32,    32,    33,    33,    33,    33,    33,    33,
-      33,    34,    35,    36,    36,    37,    38,    38,    39,    40,
-      40,    41,    42,    42,    43,    43,    44,    45
+       0,    31,    32,    32,    32,    32,    32,    32,    32,    32,
+      32,    32,    32,    33,    33,    33,    33,    33,    33,    33,
+      33,    33,    33,    33,    33,    33,    34,    34,    34,    34,
+      34,    34,    34,    35,    36,    37,    37,    38,    39,    39,
+      40,    41,    41,    42,    43,    43,    44,    44,    45,    46
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const unsigned char yyr2[] =
 {
        0,     2,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     2,     1,     2,     2,     3,     2,     2,     1,
-       2,     2,     2,     2,     1,     1,     2,     1,     1,     1,
-       1,     1,     2,     2,     1,     2,     2,     1,     2,     2,
-       1,     2,     2,     1,     1,     2,     1,     1
+       1,     1,     0,     1,     2,     1,     2,     2,     3,     2,
+       2,     1,     2,     2,     2,     2,     1,     1,     2,     1,
+       1,     1,     1,     1,     2,     2,     1,     2,     2,     1,
+       2,     2,     1,     2,     2,     1,     1,     2,     1,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -461,19 +466,20 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const unsigned char yydefact[] =
 {
-       0,    13,     0,     0,     0,    19,     0,     0,     0,    31,
-      24,    25,     0,     0,    47,    27,     0,     0,    28,    29,
-      46,     0,    44,    30,     0,     2,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,    15,    17,    14,    18,
-      22,    23,    20,    21,    34,    32,    37,    35,    26,    40,
-      38,    43,    41,    45,     1,    16,    33,    36,    39,    42
+      12,    13,    15,     0,     0,     0,    21,     0,     0,     0,
+      33,    26,    27,     0,     0,    49,    29,     0,     0,    30,
+      31,    48,     0,    46,    32,     0,     2,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    14,    17,    19,    16,
+      20,    24,    25,    22,    23,    36,    34,    39,    37,    28,
+      42,    40,    45,    43,    47,     1,    18,    35,    38,    41,
+      44
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
 static const yysigned_char yydefgoto[] =
 {
-      -1,    24,    25,    26,    27,    28,    45,    29,    47,    30,
-      50,    31,    52,    32,    33,    34
+      -1,    25,    26,    27,    28,    29,    46,    30,    48,    31,
+      51,    32,    53,    33,    34,    35
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
@@ -481,12 +487,13 @@ static const yysigned_char yydefgoto[] =
 #define YYPACT_NINF -6
 static const yysigned_char yypact[] =
 {
-      -3,    -5,    -1,     0,     1,     3,    -2,     4,     5,    -6,
-      -6,    -6,     6,     7,    -6,     8,     9,    10,    -6,    -6,
-      -6,    11,    -6,    -6,    26,    -6,    -6,    -6,    -6,    -6,
-      -6,    -6,    -6,    -6,    -6,    -6,    -6,    12,    -6,    -6,
-      -6,    -6,    -6,    -6,    -6,    13,    -6,    14,    -6,    -6,
-      15,    -6,    16,    -6,    -6,    -6,    -6,    -6,    -6,    -6
+      -3,    -6,    -5,    -1,     0,     1,     3,    -2,     4,     5,
+      -6,    -6,    -6,     6,     7,    -6,     8,     9,    10,    -6,
+      -6,    -6,    11,    -6,    -6,    27,    -6,    -6,    -6,    -6,
+      -6,    -6,    -6,    -6,    -6,    -6,    -6,    -6,    12,    -6,
+      -6,    -6,    -6,    -6,    -6,    -6,    13,    -6,    14,    -6,
+      -6,    15,    -6,    16,    -6,    -6,    -6,    -6,    -6,    -6,
+      -6
 };
 
 /* YYPGOTO[NTERM-NUM].  */
@@ -505,18 +512,18 @@ static const unsigned char yytable[] =
 {
        1,     2,     3,     4,     5,     6,     7,     8,     9,    10,
       11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-      21,    22,    23,    35,    40,    41,    54,    36,    37,     0,
-      38,    39,    42,    43,    44,    46,    48,    49,    51,    53,
-      55,    56,    57,    58,    59
+      21,    22,    23,    24,    36,    41,    42,    55,    37,    38,
+       0,    39,    40,    43,    44,    45,    47,    49,    50,    52,
+      54,    56,    57,    58,    59,    60
 };
 
 static const yysigned_char yycheck[] =
 {
        3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
       13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      23,    24,    25,    28,    26,    27,     0,    28,    28,    -1,
-      29,    28,    28,    28,    28,    28,    28,    28,    28,    28,
-      28,    28,    28,    28,    28
+      23,    24,    25,    26,    29,    27,    28,     0,    29,    29,
+      -1,    30,    29,    29,    29,    29,    29,    29,    29,    29,
+      29,    29,    29,    29,    29,    29
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -525,10 +532,11 @@ static const unsigned char yystos[] =
 {
        0,     3,     4,     5,     6,     7,     8,     9,    10,    11,
       12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-      22,    23,    24,    25,    31,    32,    33,    34,    35,    37,
-      39,    41,    43,    44,    45,    28,    28,    28,    29,    28,
-      26,    27,    28,    28,    28,    36,    28,    38,    28,    28,
-      40,    28,    42,    28,     0,    28,    28,    28,    28,    28
+      22,    23,    24,    25,    26,    32,    33,    34,    35,    36,
+      38,    40,    42,    44,    45,    46,    29,    29,    29,    30,
+      29,    27,    28,    29,    29,    29,    37,    29,    39,    29,
+      29,    41,    29,    43,    29,     0,    29,    29,    29,    29,
+      29
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1198,57 +1206,72 @@ yyreduce:
   switch (yyn)
     {
         case 12:
-#line 76 "uparse.y"
-    { list_disk((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 75 "uparse.y"
+    {
+           char * errstr = vstralloc("Invalid command: ", yytext, NULL);
+           yyerror(errstr);
+           amfree(errstr);
+           YYERROR;
+       }
     break;
 
   case 13:
-#line 77 "uparse.y"
-    { list_disk(NULL); }
+#line 84 "uparse.y"
+    { list_host(); }
     break;
 
   case 14:
-#line 78 "uparse.y"
-    { set_date((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 85 "uparse.y"
+    { list_disk((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
   case 15:
-#line 79 "uparse.y"
-    { set_host((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 86 "uparse.y"
+    { list_disk(NULL); }
     break;
 
   case 16:
-#line 80 "uparse.y"
-    { set_disk((yyvsp[-1].strval), (yyvsp[0].strval)); amfree((yyvsp[-1].strval)); amfree((yyvsp[0].strval)); }
+#line 87 "uparse.y"
+    { set_date((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
   case 17:
-#line 81 "uparse.y"
-    { set_disk((yyvsp[0].strval), NULL); amfree((yyvsp[0].strval)); }
+#line 88 "uparse.y"
+    { set_host((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
   case 18:
-#line 82 "uparse.y"
-    { set_tape((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 89 "uparse.y"
+    { set_disk((yyvsp[-1].strval), (yyvsp[0].strval)); amfree((yyvsp[-1].strval)); amfree((yyvsp[0].strval)); }
     break;
 
   case 19:
-#line 83 "uparse.y"
-    { set_tape(""); }
+#line 90 "uparse.y"
+    { set_disk((yyvsp[0].strval), NULL); amfree((yyvsp[0].strval)); }
     break;
 
   case 20:
-#line 84 "uparse.y"
-    { cd_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 91 "uparse.y"
+    { set_tape((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
   case 21:
-#line 85 "uparse.y"
-    { cd_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 92 "uparse.y"
+    { set_tape(""); }
     break;
 
   case 22:
-#line 86 "uparse.y"
+#line 93 "uparse.y"
+    { cd_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 23:
+#line 94 "uparse.y"
+    { cd_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+    break;
+
+  case 24:
+#line 95 "uparse.y"
     {
 #ifdef SAMBA_CLIENT
                         set_mode(SAMBA_SMBCLIENT);
@@ -1256,8 +1279,8 @@ yyreduce:
                     }
     break;
 
-  case 23:
-#line 91 "uparse.y"
+  case 25:
+#line 100 "uparse.y"
     {
 #ifdef SAMBA_CLIENT
                         set_mode(SAMBA_TAR);
@@ -1265,93 +1288,93 @@ yyreduce:
                     }
     break;
 
-  case 24:
-#line 99 "uparse.y"
+  case 26:
+#line 108 "uparse.y"
     { list_disk_history(); }
     break;
 
-  case 25:
-#line 100 "uparse.y"
+  case 27:
+#line 109 "uparse.y"
     { list_directory(); }
     break;
 
-  case 26:
-#line 101 "uparse.y"
+  case 28:
+#line 110 "uparse.y"
     { display_extract_list((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 27:
-#line 102 "uparse.y"
+  case 29:
+#line 111 "uparse.y"
     { display_extract_list(NULL); }
     break;
 
-  case 28:
-#line 103 "uparse.y"
+  case 30:
+#line 112 "uparse.y"
     { show_directory(); }
     break;
 
-  case 29:
-#line 104 "uparse.y"
+  case 31:
+#line 113 "uparse.y"
     { clear_extract_list(); }
     break;
 
-  case 30:
-#line 105 "uparse.y"
+  case 32:
+#line 114 "uparse.y"
     { show_mode (); }
     break;
 
-  case 31:
-#line 109 "uparse.y"
+  case 33:
+#line 118 "uparse.y"
     { quit(); }
     break;
 
-  case 33:
-#line 117 "uparse.y"
+  case 35:
+#line 126 "uparse.y"
     { add_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 34:
-#line 118 "uparse.y"
+  case 36:
+#line 127 "uparse.y"
     { add_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 36:
-#line 126 "uparse.y"
+  case 38:
+#line 135 "uparse.y"
     { add_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 37:
-#line 127 "uparse.y"
+  case 39:
+#line 136 "uparse.y"
     { add_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 39:
-#line 135 "uparse.y"
+  case 41:
+#line 144 "uparse.y"
     { delete_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 40:
-#line 136 "uparse.y"
+  case 42:
+#line 145 "uparse.y"
     { delete_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 42:
-#line 144 "uparse.y"
+  case 44:
+#line 153 "uparse.y"
     { delete_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 43:
-#line 145 "uparse.y"
+  case 45:
+#line 154 "uparse.y"
     { delete_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
     break;
 
-  case 44:
-#line 149 "uparse.y"
+  case 46:
+#line 158 "uparse.y"
     { char buf[STR_SIZE]; puts(getcwd(buf, sizeof(buf))); }
     break;
 
-  case 45:
-#line 150 "uparse.y"
+  case 47:
+#line 159 "uparse.y"
     {
                if (chdir((yyvsp[0].strval)) == -1) {
                        perror((yyvsp[0].strval));
@@ -1360,13 +1383,13 @@ yyreduce:
        }
     break;
 
-  case 46:
-#line 159 "uparse.y"
+  case 48:
+#line 168 "uparse.y"
     { help_list(); }
     break;
 
-  case 47:
-#line 163 "uparse.y"
+  case 49:
+#line 172 "uparse.y"
     { extract_files(); }
     break;
 
@@ -1375,7 +1398,7 @@ yyreduce:
     }
 
 /* Line 1126 of yacc.c.  */
-#line 1379 "uparse.c"
+#line 1402 "uparse.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -1643,14 +1666,13 @@ yyreturn:
 }
 
 
-#line 167 "uparse.y"
+#line 176 "uparse.y"
 
 
-void yyerror(s)
-char *s;
+void
+yyerror(
+    char *     s)
 {
-  printf("Invalid command - %s\n", s);
+       printf("%s\n", s);
 }
 
-
-
index 08173326bb9400c3d18870a97300424b9b19da08..30d97fae14d0b01316e74461d91156235cec75b7 100644 (file)
    /* Put the tokens into the symbol table, so that GDB and other debuggers
       know about them.  */
    enum yytokentype {
-     LISTDISK = 258,
-     SETHOST = 259,
-     SETDISK = 260,
-     SETDATE = 261,
-     SETTAPE = 262,
-     SETMODE = 263,
-     CD = 264,
-     CDX = 265,
-     QUIT = 266,
-     DHIST = 267,
-     LS = 268,
-     ADD = 269,
-     ADDX = 270,
-     EXTRACT = 271,
-     LIST = 272,
-     DELETE = 273,
-     DELETEX = 274,
-     PWD = 275,
-     CLEAR = 276,
-     HELP = 277,
-     LCD = 278,
-     LPWD = 279,
-     MODE = 280,
-     SMB = 281,
-     TAR = 282,
-     PATH = 283,
-     DATE = 284
+     LISTHOST = 258,
+     LISTDISK = 259,
+     SETHOST = 260,
+     SETDISK = 261,
+     SETDATE = 262,
+     SETTAPE = 263,
+     SETMODE = 264,
+     CD = 265,
+     CDX = 266,
+     QUIT = 267,
+     DHIST = 268,
+     LS = 269,
+     ADD = 270,
+     ADDX = 271,
+     EXTRACT = 272,
+     LIST = 273,
+     DELETE = 274,
+     DELETEX = 275,
+     PWD = 276,
+     CLEAR = 277,
+     HELP = 278,
+     LCD = 279,
+     LPWD = 280,
+     MODE = 281,
+     SMB = 282,
+     TAR = 283,
+     PATH = 284,
+     DATE = 285
    };
 #endif
 /* Tokens.  */
-#define LISTDISK 258
-#define SETHOST 259
-#define SETDISK 260
-#define SETDATE 261
-#define SETTAPE 262
-#define SETMODE 263
-#define CD 264
-#define CDX 265
-#define QUIT 266
-#define DHIST 267
-#define LS 268
-#define ADD 269
-#define ADDX 270
-#define EXTRACT 271
-#define LIST 272
-#define DELETE 273
-#define DELETEX 274
-#define PWD 275
-#define CLEAR 276
-#define HELP 277
-#define LCD 278
-#define LPWD 279
-#define MODE 280
-#define SMB 281
-#define TAR 282
-#define PATH 283
-#define DATE 284
+#define LISTHOST 258
+#define LISTDISK 259
+#define SETHOST 260
+#define SETDISK 261
+#define SETDATE 262
+#define SETTAPE 263
+#define SETMODE 264
+#define CD 265
+#define CDX 266
+#define QUIT 267
+#define DHIST 268
+#define LS 269
+#define ADD 270
+#define ADDX 271
+#define EXTRACT 272
+#define LIST 273
+#define DELETE 274
+#define DELETEX 275
+#define PWD 276
+#define CLEAR 277
+#define HELP 278
+#define LCD 279
+#define LPWD 280
+#define MODE 281
+#define SMB 282
+#define TAR 283
+#define PATH 284
+#define DATE 285
 
 
 
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 40 "uparse.y"
+#line 42 "uparse.y"
 typedef union YYSTYPE {
-  int intval;
-  double floatval;
-  char *strval;
-  int subtok;
+       int     intval;
+       double  floatval;
+       char *  strval;
+       int     subtok;
 } YYSTYPE;
 /* Line 1447 of yacc.c.  */
-#line 103 "uparse.h"
+#line 105 "uparse.h"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
index 872d0b65adda6793766a626ca878eb1d3aa4235b..35d6d3e43162221058007dcfc3fd8f7a8b617248 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: uparse.y,v 1.11 2003/01/01 23:28:17 martinea Exp $
+ * $Id: uparse.y,v 1.13 2006/05/25 01:47:14 johnfranks Exp $
  *
  * parser for amrecover interactive language
  */
 #include "amanda.h"
 #include "amrecover.h"
 
-void yyerror P((char *s));
-extern int yylex P((void));
+void           yyerror(char *s);
+extern int     yylex(void);
+extern char *  yytext;
+
 %}
 
 /* DECLARATIONS */
 %union {
-  int intval;
-  double floatval;
-  char *strval;
-  int subtok;
+       int     intval;
+       double  floatval;
+       char *  strval;
+       int     subtok;
 }
 
        /* literal keyword tokens */
 
-%token LISTDISK SETHOST SETDISK SETDATE SETTAPE SETMODE
+%token LISTHOST LISTDISK SETHOST SETDISK SETDATE SETTAPE SETMODE
 %token CD CDX QUIT DHIST LS ADD ADDX EXTRACT
 %token LIST DELETE DELETEX PWD CLEAR HELP LCD LPWD MODE SMB TAR
 
@@ -70,10 +72,17 @@ ucommand:
   |     local_command
   |    help_command
   |     extract_command
+  |     {
+           char * errstr = vstralloc("Invalid command: ", yytext, NULL);
+           yyerror(errstr);
+           amfree(errstr);
+           YYERROR;
+       } /* Quiets compiler warnings about unused label */
   ;
 
 set_command:
-       LISTDISK PATH { list_disk($2); amfree($2); }
+       LISTHOST { list_host(); }
+  |    LISTDISK PATH { list_disk($2); amfree($2); }
   |    LISTDISK { list_disk(NULL); }
   |    SETDATE DATE { set_date($2); amfree($2); }
   |     SETHOST PATH { set_host($2); amfree($2); }
@@ -166,10 +175,9 @@ extract_command:
 /* ADDITIONAL C CODE */
 %%
 
-void yyerror(s)
-char *s;
+void
+yyerror(
+    char *     s)
 {
-  printf("Invalid command - %s\n", s);
+       printf("%s\n", s);
 }
-
-
index efabc189a241e6fd3292332d1e7f19cc6611b112..2b8045f27984aff86abdbc6f08ea0e0f2eda7e11 100644 (file)
@@ -291,144 +291,153 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
        *yy_cp = '\0'; \
        yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 38
-#define YY_END_OF_BUFFER 39
-static yyconst short int yy_accept[121] =
+#define YY_NUM_RULES 40
+#define YY_END_OF_BUFFER 41
+static yyconst short int yy_accept[131] =
     {   0,
-        0,    0,    0,    0,   39,   31,   37,   32,   31,   31,
-       21,   31,   31,   31,   31,   31,   31,   31,   31,   31,
-       31,   31,   36,   35,   33,   38,   31,   37,   31,   31,
-       31,   31,    7,   31,   31,   31,   31,   31,   31,   31,
-       31,   12,   31,   31,   31,   31,   31,   31,   36,   34,
-       31,   31,   31,   13,    8,   31,   31,   31,   31,   31,
-       31,   22,   31,   31,   31,   18,   31,   31,   25,   26,
-       28,   31,   31,   14,   31,   31,   10,   31,   20,   31,
-       15,   23,   27,    9,   31,   31,   31,   31,   29,   30,
-       19,   31,   31,   31,   31,   31,   31,   31,   31,   31,
-
-       16,   31,   31,   31,   31,   31,   31,   31,   31,   17,
-       24,   11,   31,    4,    3,    2,    5,    6,    1,    0
+        0,    0,    0,    0,   41,   40,   39,   38,   34,   38,
+       38,   22,   38,   38,   38,   38,   38,   38,   38,   38,
+       38,   38,   38,   35,   37,   40,   39,   38,   38,   38,
+       38,   38,    8,   38,   38,   38,   38,   38,   38,   38,
+       38,   13,   38,   38,   38,   38,   38,   38,   35,   36,
+       38,   38,   38,   14,    9,   38,   38,   38,   38,   38,
+       38,   23,   38,   38,   38,   19,   38,   38,   26,   27,
+       29,   38,   38,   15,   38,   38,   11,   38,   21,   38,
+       16,   24,   28,   10,   38,   38,   38,   38,   30,   31,
+       20,   38,   38,   38,   38,   38,   38,   38,   38,   38,
+
+       38,   38,   17,   38,   38,   38,   38,   38,   38,   38,
+       38,   38,   38,   18,   25,   12,   38,   38,    5,    4,
+        3,    6,    7,   38,    2,    1,   33,   38,   32,    0
     } ;
 
 static yyconst int yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    1,    4,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    5,    1,    1,    6,    6,    6,
-        6,    6,    6,    6,    6,    6,    6,    1,    1,    1,
-        1,    1,    7,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    8,    1,    1,    1,    1,    9,   10,   11,   12,
-
-       13,    1,    1,   14,   15,    1,   16,   17,   18,    1,
-       19,   20,   21,   22,   23,   24,   25,    1,   26,   27,
-       28,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
+        1,    2,    4,    5,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    6,    4,    4,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    4,    4,    4,
+        4,    4,    8,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    9,    4,    4,    4,    4,   10,   11,   12,   13,
+
+       14,    4,    4,   15,   16,    4,   17,   18,   19,    4,
+       20,   21,   22,   23,   24,   25,   26,    4,   27,   28,
+       29,    4,    4,    4,    4,    4,    1,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,    4
     } ;
 
-static yyconst int yy_meta[29] =
+static yyconst int yy_meta[30] =
     {   0,
-        1,    2,    3,    4,    1,    1,    1,    3,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1
+        1,    1,    2,    3,    4,    3,    3,    3,    5,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3
     } ;
 
-static yyconst short int yy_base[124] =
+static yyconst short int yy_base[135] =
     {   0,
-        0,    0,   26,   28,  142,    0,  139,  143,  135,   32,
-        0,  127,   23,  125,  110,   26,   31,  117,  109,  109,
-       30,  124,    0,  143,  143,  128,    0,  129,   39,  124,
-       44,  117,  101,  114,  109,   32,  108,  101,  111,   99,
-       95,    0,  108,  107,  103,   93,  106,   93,    0,  143,
-      108,   47,   52,   86,    0,  103,   98,   86,   87,   88,
-       83,    0,   82,   93,   91,    0,   79,   47,    0,    0,
-       96,   95,   94,    0,   77,   74,    0,   88,    0,   77,
-       83,    0,    0,    0,   51,   75,   74,   83,   85,   84,
-        0,   76,   77,   65,   71,   61,   61,   60,   70,   61,
-
-       50,   46,   41,   45,   54,   48,   39,   49,   42,    0,
-        0,    0,   17,    0,    0,    0,    0,    0,    0,  143,
-       71,   75,   78
+        0,    0,   25,   26,  161,  162,   30,    0,  162,  154,
+       30,    0,  146,   25,  144,  129,   25,   28,  136,  128,
+      128,   28,  143,    0,  162,    0,   43,    0,   44,  145,
+       47,  138,  122,  135,  130,   32,  129,  122,  132,  120,
+      116,    0,  129,  128,  124,  114,  127,  114,    0,  162,
+      129,   49,   52,  107,    0,  124,  119,  107,  108,  109,
+      104,    0,  103,  114,  112,    0,  100,   47,    0,    0,
+      117,  116,  115,    0,   98,   95,    0,  109,    0,   98,
+       48,    0,    0,    0,   54,   97,   96,  105,  107,   61,
+        0,   99,  100,   88,   94,   89,   83,   83,   82,   92,
+
+       83,   96,   74,   76,   71,   75,   74,   83,   79,   70,
+       80,   79,   67,    0,    0,    0,   72,   58,    0,    0,
+        0,    0,    0,   64,    0,    0,   69,   62,   58,  162,
+       76,   79,   84,   87
     } ;
 
-static yyconst short int yy_def[124] =
+static yyconst short int yy_def[135] =
     {   0,
-      120,    1,  121,  121,  120,  122,  120,  120,  122,  122,
-      122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
-      122,  122,  123,  120,  120,  120,  122,  120,  122,  122,
-      122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
-      122,  122,  122,  122,  122,  122,  122,  122,  123,  120,
-      122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
-      122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
-      122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
-      122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
-      122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
-
-      122,  122,  122,  122,  122,  122,  122,  122,  122,  122,
-      122,  122,  122,  122,  122,  122,  122,  122,  122,    0,
-      120,  120,  120
+      130,    1,  131,  131,  130,  130,  130,  132,  130,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  133,  130,  134,  130,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  133,  130,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,  132,  132,  132,  132,  132,    0,
+      130,  130,  130,  130
     } ;
 
-static yyconst short int yy_nxt[172] =
+static yyconst short int yy_nxt[192] =
     {   0,
-        6,    7,    6,    8,    9,   10,   11,    6,   12,    6,
-       13,   14,   15,   16,    6,    6,   17,   18,    6,   19,
-       20,    6,   21,   22,    6,    6,    6,    6,   24,   25,
-       24,   25,  119,   26,   33,   26,   30,   31,   37,   34,
-       38,   39,   46,   51,   52,   40,   58,   47,   30,   31,
-       41,   72,   52,   42,  118,   59,   73,   53,   85,   96,
-       86,  117,  116,  115,   87,   97,  114,  113,  112,  111,
-       88,   23,   23,   23,   23,   27,  110,   27,   49,   49,
-      109,  108,  107,  106,  105,  104,  103,  102,  101,   90,
-       89,  100,   99,   98,   95,   94,   93,   92,   91,   90,
-
-       89,   71,   84,   83,   82,   81,   80,   79,   78,   77,
-       76,   75,   74,   71,   70,   69,   68,   67,   66,   65,
-       64,   63,   62,   61,   60,   57,   56,   55,   54,   53,
-       28,   50,   48,   45,   44,   43,   36,   35,   32,   29,
-       28,  120,    5,  120,  120,  120,  120,  120,  120,  120,
-      120,  120,  120,  120,  120,  120,  120,  120,  120,  120,
-      120,  120,  120,  120,  120,  120,  120,  120,  120,  120,
-      120
+        6,    7,    7,    8,    9,   10,   11,   12,    8,   13,
+        8,   14,   15,   16,   17,    8,    8,   18,   19,    8,
+       20,   21,    8,   22,   23,    8,    8,    8,    8,   25,
+       25,   27,   27,   26,   26,   30,   31,   33,   37,   39,
+       38,   46,   34,   40,   27,   27,   47,   58,   41,   51,
+       52,   42,   30,   31,   72,   52,   59,   73,   53,   85,
+       95,   86,   96,   97,  129,   87,  102,   90,  129,   98,
+      127,   88,  124,  113,  128,  127,   24,   24,   24,   24,
+       24,   28,  126,   28,   49,   49,   49,   50,  125,   50,
+       50,   50,  123,  122,  121,  120,  119,  118,  117,  116,
+
+      115,  114,  113,  112,  111,  110,  109,  108,  107,  106,
+      105,  104,  103,   89,  101,  100,   99,   94,   93,   92,
+       91,   90,   89,   71,   84,   83,   82,   81,   80,   79,
+       78,   77,   76,   75,   74,   71,   70,   69,   68,   67,
+       66,   65,   64,   63,   62,   61,   60,   57,   56,   55,
+       54,   53,   48,   45,   44,   43,   36,   35,   32,   29,
+      130,    5,  130,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130
+
     } ;
 
-static yyconst short int yy_chk[172] =
+static yyconst short int yy_chk[192] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    3,    3,
-        4,    4,  113,    3,   13,    4,   10,   10,   16,   13,
-       16,   17,   21,   29,   29,   17,   36,   21,   31,   31,
-       17,   52,   52,   17,  109,   36,   53,   53,   68,   85,
-       68,  108,  107,  106,   68,   85,  105,  104,  103,  102,
-       68,  121,  121,  121,  121,  122,  101,  122,  123,  123,
-      100,   99,   98,   97,   96,   95,   94,   93,   92,   90,
-       89,   88,   87,   86,   81,   80,   78,   76,   75,   73,
-
-       72,   71,   67,   65,   64,   63,   61,   60,   59,   58,
-       57,   56,   54,   51,   48,   47,   46,   45,   44,   43,
-       41,   40,   39,   38,   37,   35,   34,   33,   32,   30,
-       28,   26,   22,   20,   19,   18,   15,   14,   12,    9,
-        7,    5,  120,  120,  120,  120,  120,  120,  120,  120,
-      120,  120,  120,  120,  120,  120,  120,  120,  120,  120,
-      120,  120,  120,  120,  120,  120,  120,  120,  120,  120,
-      120
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    3,
+        4,    7,    7,    3,    4,   11,   11,   14,   17,   18,
+       17,   22,   14,   18,   27,   27,   22,   36,   18,   29,
+       29,   18,   31,   31,   52,   52,   36,   53,   53,   68,
+       81,   68,   81,   85,  129,   68,   90,   90,  128,   85,
+      124,   68,  113,  113,  127,  127,  131,  131,  131,  131,
+      131,  132,  118,  132,  133,  133,  133,  134,  117,  134,
+      134,  134,  112,  111,  110,  109,  108,  107,  106,  105,
+
+      104,  103,  102,  101,  100,   99,   98,   97,   96,   95,
+       94,   93,   92,   89,   88,   87,   86,   80,   78,   76,
+       75,   73,   72,   71,   67,   65,   64,   63,   61,   60,
+       59,   58,   57,   56,   54,   51,   48,   47,   46,   45,
+       44,   43,   41,   40,   39,   38,   37,   35,   34,   33,
+       32,   30,   23,   21,   20,   19,   16,   15,   13,   10,
+        5,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      130
+
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -445,7 +454,7 @@ char *yytext;
 #line 1 "uscan.l"
 #define INITIAL 0
 /*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * amanda, the advanced maryland automatic network disk archiver
  * Copyright (c) 1991-2000 University of Maryland at College Park
  * All Rights Reserved.
  *
@@ -470,27 +479,41 @@ char *yytext;
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: uscan.l,v 1.22 2004/02/11 13:03:29 martinea Exp $
+ * $Id: uscan.l,v 1.27 2006/07/05 11:15:56 martinea Exp $
  *
  * lexer for amrecover interactive language
  */
 #line 32 "uscan.l"
 #include "amanda.h"
-#undef ECHO
 #include "uparse.h"
 
+/*
+ * We redefine this here to prevent compiler warning about ignoring fwrite
+ * return value...
+ */
+#undef ECHO
+#define ECHO do {                                              \
+       if (fwrite(yytext, (size_t)yyleng, 1, yyout) <= 0) {    \
+           yyerror("ECHO failure");                            \
+       }                                                       \
+} while (0)
+
 #define YY_NO_UNPUT
 
-#define        DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD")    /* includes null */
+#define        DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD-HH-MM-SS")   /* includes null */
+
+#define YY_DECL        int yylex(void)
+extern int     yylex(void);
 
-extern void yyerror P((char *s));
-extern int  yyparse P((void));
-static int  ll_parse_date P((int type, char *text));
-#define quotedstring 1
+extern void    yyerror(char *s);
+extern int     yyparse(void);
+static int     ll_parse_date(int type, char *text);
+int            process_line(char *line);
+#define quotedpath 1
 
-#line 48 "uscan.l"
+#line 62 "uscan.l"
 static char *string_buf = NULL;
-#line 494 "uscan.c"
+#line 517 "uscan.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -641,14 +664,14 @@ YY_DECL
        register char *yy_cp = NULL, *yy_bp = NULL;
        register int yy_act;
 
-#line 51 "uscan.l"
+#line 65 "uscan.l"
 
 
 
     /* literal keyword tokens */
 
 
-#line 652 "uscan.c"
+#line 675 "uscan.c"
 
        if ( yy_init )
                {
@@ -699,13 +722,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 121 )
+                               if ( yy_current_state >= 131 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_base[yy_current_state] != 143 );
+               while ( yy_base[yy_current_state] != 162 );
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
@@ -733,217 +756,229 @@ do_action:      /* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 57 "uscan.l"
-{ return LISTDISK; }
+#line 71 "uscan.l"
+{ return LISTHOST; }
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 58 "uscan.l"
-{ return SETHOST; }
+#line 72 "uscan.l"
+{ return LISTDISK; }
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 59 "uscan.l"
-{ return SETDISK; }
+#line 73 "uscan.l"
+{ return SETHOST; }
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 60 "uscan.l"
-{ return SETDATE; }
+#line 74 "uscan.l"
+{ return SETDISK; }
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 61 "uscan.l"
-{ return SETMODE; }
+#line 75 "uscan.l"
+{ return SETDATE; }
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 62 "uscan.l"
-{ return SETTAPE; }
+#line 76 "uscan.l"
+{ return SETMODE; }
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 63 "uscan.l"
-{ return CD; }
+#line 77 "uscan.l"
+{ return SETTAPE; }
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 64 "uscan.l"
-{ return CDX; }
+#line 78 "uscan.l"
+{ return CD; }
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 65 "uscan.l"
-{ return QUIT; }
+#line 79 "uscan.l"
+{ return CDX; }
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 66 "uscan.l"
+#line 80 "uscan.l"
 { return QUIT; }
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 67 "uscan.l"
-{ return DHIST; }
+#line 81 "uscan.l"
+{ return QUIT; }
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 68 "uscan.l"
-{ return LS; }
+#line 82 "uscan.l"
+{ return DHIST; }
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 69 "uscan.l"
-{ return ADD; }
+#line 83 "uscan.l"
+{ return LS; }
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 70 "uscan.l"
-{ return ADDX; }
+#line 84 "uscan.l"
+{ return ADD; }
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 71 "uscan.l"
-{ return LIST; }
+#line 85 "uscan.l"
+{ return ADDX; }
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 72 "uscan.l"
-{ return DELETE; }
+#line 86 "uscan.l"
+{ return LIST; }
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 73 "uscan.l"
-{ return DELETEX; }
+#line 87 "uscan.l"
+{ return DELETE; }
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 74 "uscan.l"
-{ return PWD; }
+#line 88 "uscan.l"
+{ return DELETEX; }
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 75 "uscan.l"
-{ return CLEAR; }
+#line 89 "uscan.l"
+{ return PWD; }
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 76 "uscan.l"
-{ return HELP; }
+#line 90 "uscan.l"
+{ return CLEAR; }
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 77 "uscan.l"
+#line 91 "uscan.l"
 { return HELP; }
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 78 "uscan.l"
-{ return LCD; }
+#line 92 "uscan.l"
+{ return HELP; }
        YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 79 "uscan.l"
-{ return LPWD; }
+#line 93 "uscan.l"
+{ return LCD; }
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 80 "uscan.l"
-{ return EXTRACT; }
+#line 94 "uscan.l"
+{ return LPWD; }
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 81 "uscan.l"
-{ return SMB; }
+#line 95 "uscan.l"
+{ return EXTRACT; }
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 82 "uscan.l"
-{ return TAR; }
+#line 96 "uscan.l"
+{ return SMB; }
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 83 "uscan.l"
+#line 97 "uscan.l"
+{ return TAR; }
+       YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 98 "uscan.l"
 { return MODE; }
        YY_BREAK
 
     /* dates */
 
-case 28:
-YY_RULE_SETUP
-#line 89 "uscan.l"
-{ return ll_parse_date(1, yytext); }
-       YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 90 "uscan.l"
-{ return ll_parse_date(2, yytext); }
+#line 104 "uscan.l"
+{ return ll_parse_date(1, yytext); }
        YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 91 "uscan.l"
-{ return ll_parse_date(3, yytext); }
+#line 105 "uscan.l"
+{ return ll_parse_date(2, yytext); }
        YY_BREAK
-
-    /* file names */
-
 case 31:
 YY_RULE_SETUP
-#line 97 "uscan.l"
-{
-  yylval.strval = stralloc(yytext); return PATH;
-}
+#line 106 "uscan.l"
+{ return ll_parse_date(3, yytext); }
        YY_BREAK
-
-    /* quoted file names */
-
 case 32:
 YY_RULE_SETUP
-#line 105 "uscan.l"
-{ if(string_buf != NULL) {printf("ERROR:string_buf != NULL: %s\n",string_buf);}; BEGIN(quotedstring); }
+#line 107 "uscan.l"
+{ return ll_parse_date(4, yytext); }
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 107 "uscan.l"
-{ /* saw closing quote - all done */
-  BEGIN(INITIAL);
-  if(string_buf) {
-    yylval.strval = string_buf;
-    string_buf = NULL;
-  } else {
-    yylval.strval = "";
-  }
-  return PATH;
-}
+#line 108 "uscan.l"
+{ return ll_parse_date(5, yytext); }
        YY_BREAK
+
+    /* quoted file names */
+
 case 34:
 YY_RULE_SETUP
-#line 118 "uscan.l"
+#line 114 "uscan.l"
 {
-  /* escaped quote */
-  strappend(string_buf, "\\\"");
+    if(string_buf != NULL) {
+       printf("ERROR:string_buf != NULL: %s\n",string_buf);
+    }
+    BEGIN(quotedpath);
+    strappend(string_buf, yytext);
 }
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 123 "uscan.l"
+#line 122 "uscan.l"
 {
-  /* error - unterminated string constant */
-  yyerror("unterminated string");
-  amfree(string_buf);
+    strappend(string_buf, yytext);
 }
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 129 "uscan.l"
-{ strappend(string_buf, yytext); }
+#line 126 "uscan.l"
+{
+    /* escaped character (including quote) */
+    strappend(string_buf, yytext);
+}
+       YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 131 "uscan.l"
+{ /* saw closing quote - all done */
+    strappend(string_buf, yytext);
+    yylval.strval = string_buf;
+    string_buf = NULL;
+    BEGIN(INITIAL);
+    return PATH;
+}
+       YY_BREAK
+
+    /* file names */
+
+case 38:
+YY_RULE_SETUP
+#line 143 "uscan.l"
+{
+    yylval.strval = stralloc(yytext);
+    return PATH;
+}
        YY_BREAK
 
     /* whitespace */
 
-case 37:
+case 39:
 YY_RULE_SETUP
-#line 135 "uscan.l"
+#line 152 "uscan.l"
 ;     /* whitespace */
        YY_BREAK
 
@@ -955,14 +990,14 @@ YY_RULE_SETUP
 .      { yyerror("invalid character"); }
 #endif
 
-case 38:
+case 40:
 YY_RULE_SETUP
-#line 148 "uscan.l"
+#line 165 "uscan.l"
 ECHO;
        YY_BREAK
-#line 964 "uscan.c"
+#line 999 "uscan.c"
 case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(quotedstring):
+case YY_STATE_EOF(quotedpath):
        yyterminate();
 
        case YY_END_OF_BUFFER:
@@ -1253,7 +1288,7 @@ static yy_state_type yy_get_previous_state()
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 121 )
+                       if ( yy_current_state >= 131 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1288,11 +1323,11 @@ yy_state_type yy_current_state;
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 121 )
+               if ( yy_current_state >= 131 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 120);
+       yy_is_jam = (yy_current_state == 130);
 
        return yy_is_jam ? 0 : yy_current_state;
        }
@@ -1843,11 +1878,12 @@ int main()
        return 0;
        }
 #endif
-#line 148 "uscan.l"
+#line 165 "uscan.l"
 
 
-int process_line(line)
-char *line;
+int
+process_line(
+    char *     line)
 {
     YY_BUFFER_STATE b;
     int result;
@@ -1858,47 +1894,84 @@ char *line;
     return result;
 }
 
-static int ll_parse_date(type, text)
-int type;
-char *text;
+static int
+ll_parse_date(
+    int                type,
+    char *     text)
 {
     time_t now;
     struct tm *t;
-    int y, m, d;
+    int y=2000, m=0, d=1, h=0, mi=0, s=0;
     int ret;
 
     now = time((time_t *)NULL);
     t = localtime(&now);
-    y = 1900+t->tm_year;
-    m = t->tm_mon+1;
-    d = t->tm_mday;
-    if(type == 1) {
-       sscanf(text, "---%d", &d);
-    } else if(type == 2) {
-       sscanf(text, "--%d-%d", &m, &d);
-    } else {
-       sscanf(text, "%d-%d-%d", &y, &m, &d);
-       if(y < 70) {
-           y += 2000;
-       } else if(y < 100) {
-           y += 1900;
+    if (t) {
+       y = 1900+t->tm_year;
+       m = t->tm_mon+1;
+       d = t->tm_mday;
+    }
+    switch(type) {
+    case 1:
+       if (sscanf(text, "---%d", &d) != 1) {
+           yyerror("invalid date");
+        }
+        break;
+    case 2:
+       if (sscanf(text, "--%d-%d", &m, &d) != 2) {
+           yyerror("invalid date");
+        }
+        break;
+    case 3:
+       if (sscanf(text, "%d-%d-%d", &y, &m, &d) != 3) {
+           yyerror("invalid date");        
+        }
+        break;
+    case 4:
+       if (sscanf(text, "%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi, &s) != 6) {
+           yyerror("invalid date");
+       }
+        break;
+    case 5:
+       if (sscanf(text, "%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi) != 5) {
+           yyerror("invalid date");
        }
+        break;
     }
+
     ret = PATH;                                /* cause a parse error */
+    if(y < 70) {
+       y += 2000;
+    } else if(y < 100) {
+       y += 1900;
+    }
     if(y < 1000 || y > 9999) {
        yyerror("invalid year");
     } else if(m < 1 || m > 12) {
        yyerror("invalid month");
     } else if(d < 1 || d > 31) {
        yyerror("invalid day");
-    } else {
+    } else if(h < 0 || h > 24) {
+       yyerror("invalid hour");
+    } else if(mi < 0 || mi > 59) {
+       yyerror("invalid minute");
+    } else if(s < 0 || s > 59) {
+       yyerror("invalid second");
+    } else if(type < 4) {
        yylval.strval = alloc(DATE_ALLOC_SIZE);
        snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
        ret = DATE;
+    } else {
+       yylval.strval = alloc(DATE_ALLOC_SIZE);
+       snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d-%02d-%02d-%02d", y, m, d, h, mi, s);
+       ret = DATE;
     }
     return ret;
 }
 
-int yywrap() {
+int
+yywrap(void)
+{
   return 1;
 }
+
index 66624ae090e53848b7acca0296b066dca908f732..fbd97a2c92bda2724a53e3cb4a7950c586be18f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * amanda, the advanced maryland automatic network disk archiver
  * Copyright (c) 1991-2000 University of Maryland at College Park
  * All Rights Reserved.
  *
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: uscan.l,v 1.22 2004/02/11 13:03:29 martinea Exp $
+ * $Id: uscan.l,v 1.27 2006/07/05 11:15:56 martinea Exp $
  *
  * lexer for amrecover interactive language
  */
 %{
 #include "amanda.h"
-#undef ECHO
 #include "uparse.h"
 
+/*
+ * We redefine this here to prevent compiler warning about ignoring fwrite
+ * return value...
+ */
+#undef ECHO
+#define ECHO do {                                              \
+       if (fwrite(yytext, (size_t)yyleng, 1, yyout) <= 0) {    \
+           yyerror("ECHO failure");                            \
+       }                                                       \
+} while (0)
+
 #define YY_NO_UNPUT
 
-#define        DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD")    /* includes null */
+#define        DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD-HH-MM-SS")   /* includes null */
+
+#define YY_DECL        int yylex(void)
+extern int     yylex(void);
 
-extern void yyerror P((char *s));
-extern int  yyparse P((void));
-static int  ll_parse_date P((int type, char *text));
+extern void    yyerror(char *s);
+extern int     yyparse(void);
+static int     ll_parse_date(int type, char *text);
+int            process_line(char *line);
 %}
 
-%x quotedstring
+%x quotedpath
 
 %{
 static char *string_buf = NULL;
@@ -54,33 +68,34 @@ static char *string_buf = NULL;
     /* literal keyword tokens */
 %}
 
+listhost       { return LISTHOST; }
 listdisk       { return LISTDISK; }
-sethost        { return SETHOST; }
-setdisk        { return SETDISK; }
-setdate { return SETDATE; }
-setmode        { return SETMODE; }
-settape { return SETTAPE; }
-cd     { return CD; }
-cdx    { return CDX; }
-quit    { return QUIT; }
-exit    { return QUIT; }
-history { return DHIST; }
-ls      { return LS; }
-add     { return ADD; }
-addx    { return ADDX; }
-list    { return LIST; }
-delete  { return DELETE; }
-deletex { return DELETEX; }
-pwd     { return PWD; }
-clear   { return CLEAR; }
-help    { return HELP; }
-\?      { return HELP; }
-lcd     { return LCD; }
-lpwd    { return LPWD; }
-extract { return EXTRACT; }
-smb     { return SMB; }
-tar     { return TAR; }
-mode    { return MODE; }
+sethost                { return SETHOST; }
+setdisk                { return SETDISK; }
+setdate                { return SETDATE; }
+setmode                { return SETMODE; }
+settape                { return SETTAPE; }
+cd             { return CD; }
+cdx            { return CDX; }
+quit           { return QUIT; }
+exit           { return QUIT; }
+history                { return DHIST; }
+ls             { return LS; }
+add            { return ADD; }
+addx           { return ADDX; }
+list           { return LIST; }
+delete         { return DELETE; }
+deletex                { return DELETEX; }
+pwd            { return PWD; }
+clear          { return CLEAR; }
+help           { return HELP; }
+\?             { return HELP; }
+lcd            { return LCD; }
+lpwd           { return LPWD; }
+extract                { return EXTRACT; }
+smb            { return SMB; }
+tar            { return TAR; }
+mode           { return MODE; }
 
 %{
     /* dates */
@@ -89,50 +104,52 @@ mode    { return MODE; }
 ---[0-9]+              { return ll_parse_date(1, yytext); }
 --[0-9]+-[0-9]+                { return ll_parse_date(2, yytext); }
 [0-9]+-[0-9]+-[0-9]+   { return ll_parse_date(3, yytext); }
+[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+      { return ll_parse_date(4, yytext); }
+[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+     { return ll_parse_date(5, yytext); }
 
 %{
-    /* file names */
+    /* quoted file names */
 %}
 
-[^ \t\r"]+             {
-  yylval.strval = stralloc(yytext); return PATH;
+\"                     {
+    if(string_buf != NULL) {
+       printf("ERROR:string_buf != NULL: %s\n",string_buf);
+    }
+    BEGIN(quotedpath);
+    strappend(string_buf, yytext);
 }
 
-%{
-    /* quoted file names */
-%}
+<quotedpath>[^\\\"]+   {
+    strappend(string_buf, yytext);
+}
 
-\"               { if(string_buf != NULL) {printf("ERROR:string_buf != NULL: %s\n",string_buf);}; BEGIN(quotedstring); }
+<quotedpath>\\.        {
+    /* escaped character (including quote) */
+    strappend(string_buf, yytext);
+}
 
-<quotedstring>\"        { /* saw closing quote - all done */
-  BEGIN(INITIAL);
-  if(string_buf) {
+<quotedpath>\" { /* saw closing quote - all done */
+    strappend(string_buf, yytext);
     yylval.strval = string_buf;
     string_buf = NULL;
-  } else {
-    yylval.strval = "";
-  }
-  return PATH;
+    BEGIN(INITIAL);
+    return PATH;
 }
 
-<quotedstring>\\\" {
-  /* escaped quote */
-  strappend(string_buf, "\\\"");
-}
+%{
+    /* file names */
+%}
 
-<quotedstring>\n        {
-  /* error - unterminated string constant */
-  yyerror("unterminated string");
-  amfree(string_buf);
+[^[:space:][:cntrl:]"]+                {
+    yylval.strval = stralloc(yytext);
+    return PATH;
 }
 
-<quotedstring>[^\\\n\"]+        { strappend(string_buf, yytext); }
-
 %{
     /* whitespace */
 %}
 
-[ \t\r]+       ;     /* whitespace */
+[[:space:]]+   ;     /* whitespace */
 
 %{
     /* anything else */
@@ -147,8 +164,9 @@ mode    { return MODE; }
 
 %%
 
-int process_line(line)
-char *line;
+int
+process_line(
+    char *     line)
 {
     YY_BUFFER_STATE b;
     int result;
@@ -159,47 +177,84 @@ char *line;
     return result;
 }
 
-static int ll_parse_date(type, text)
-int type;
-char *text;
+static int
+ll_parse_date(
+    int                type,
+    char *     text)
 {
     time_t now;
     struct tm *t;
-    int y, m, d;
+    int y=2000, m=0, d=1, h=0, mi=0, s=0;
     int ret;
 
     now = time((time_t *)NULL);
     t = localtime(&now);
-    y = 1900+t->tm_year;
-    m = t->tm_mon+1;
-    d = t->tm_mday;
-    if(type == 1) {
-       sscanf(text, "---%d", &d);
-    } else if(type == 2) {
-       sscanf(text, "--%d-%d", &m, &d);
-    } else {
-       sscanf(text, "%d-%d-%d", &y, &m, &d);
-       if(y < 70) {
-           y += 2000;
-       } else if(y < 100) {
-           y += 1900;
+    if (t) {
+       y = 1900+t->tm_year;
+       m = t->tm_mon+1;
+       d = t->tm_mday;
+    }
+    switch(type) {
+    case 1:
+       if (sscanf(text, "---%d", &d) != 1) {
+           yyerror("invalid date");
+        }
+        break;
+    case 2:
+       if (sscanf(text, "--%d-%d", &m, &d) != 2) {
+           yyerror("invalid date");
+        }
+        break;
+    case 3:
+       if (sscanf(text, "%d-%d-%d", &y, &m, &d) != 3) {
+           yyerror("invalid date");        
+        }
+        break;
+    case 4:
+       if (sscanf(text, "%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi, &s) != 6) {
+           yyerror("invalid date");
        }
+        break;
+    case 5:
+       if (sscanf(text, "%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi) != 5) {
+           yyerror("invalid date");
+       }
+        break;
     }
+
     ret = PATH;                                /* cause a parse error */
+    if(y < 70) {
+       y += 2000;
+    } else if(y < 100) {
+       y += 1900;
+    }
     if(y < 1000 || y > 9999) {
        yyerror("invalid year");
     } else if(m < 1 || m > 12) {
        yyerror("invalid month");
     } else if(d < 1 || d > 31) {
        yyerror("invalid day");
-    } else {
+    } else if(h < 0 || h > 24) {
+       yyerror("invalid hour");
+    } else if(mi < 0 || mi > 59) {
+       yyerror("invalid minute");
+    } else if(s < 0 || s > 59) {
+       yyerror("invalid second");
+    } else if(type < 4) {
        yylval.strval = alloc(DATE_ALLOC_SIZE);
        snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
        ret = DATE;
+    } else {
+       yylval.strval = alloc(DATE_ALLOC_SIZE);
+       snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d-%02d-%02d-%02d", y, m, d, h, mi, s);
+       ret = DATE;
     }
     return ret;
 }
 
-int yywrap() {
+int
+yywrap(void)
+{
   return 1;
 }
+
index 3882b378647c26b6ae8b1e40502d05ef16d7eada..b4d9b990d67ee1a41317d24a579f65b156d2b329 100644 (file)
@@ -31,7 +31,7 @@ JUNKLINT=possible pointer alignment|null effect
 # arrangements to build forward-reference header files
 .SUFFIXES:     .ih .h
 .c.ih:
-       sh ./mkh $(MKHFLAGS) -p $< >$@
+       sh ./mkh -A $(MKHFLAGS) -p $< >$@
 
 default:       r
 
@@ -46,7 +46,7 @@ purge:
 REGEXH=regex.h
 REGEXHSRC=regex2.h $(REGSRC)
 $(REGEXH):     $(REGEXHSRC) mkh
-       sh ./mkh $(MKHFLAGS) -i _REGEX_H_ $(REGEXHSRC) >regex.tmp
+       sh ./mkh -A $(MKHFLAGS) -i _REGEX_H_ $(REGEXHSRC) >regex.tmp
        cmp -s regex.tmp regex.h 2>/dev/null || cp regex.tmp regex.h
        rm -f regex.tmp
 
@@ -128,3 +128,6 @@ clean:      tidy
 # don't do this one unless you know what you're doing
 spotless:      clean
        rm -f mkh regex.h
+
+lint:
+
index 017b43ddced090840c58bc8f31a8655f9c2ac86c..61a65cef429131a1278b93c690582f17ec33d3eb 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef CCLASS_H
+#define CCLASS_H
+
 /* character-class table */
 static struct cclass {
        char *name;
@@ -43,3 +46,5 @@ static struct cclass {
        NULL, NULL, ""
     }
 };
+
+#endif /* !CCLASS_H */
index a33a8af2a7804bcb12369bd448d7c986d9c12419..8d5c602db20e12b68a577566fc51942bc4935c32 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef CNAME_H
+#define CNAME_H
+
 /* character-name table */
 static struct cname {
        char *name;
@@ -100,3 +103,5 @@ static struct cname {
        { "DEL",                        '\177' },
        { NULL,                         0 }
 };
+
+#endif /* !CNAME_H */
index 638bf5ac913d76d719b7403ba7a1cc5db28b0619..3663b7539e1c1a37b36c323d46daacac2f0a8713 100644 (file)
@@ -1,9 +1,4 @@
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <sys/types.h>
+#include "amanda.h"
 #include <regex.h>
 
 #include "utils.h"
@@ -235,8 +230,8 @@ int ch;
        static char buf[10];
 
        if (isprint(ch) || ch == ' ')
-               snprintf(buf, sizeof(buf), "%c", ch);
+               snprintf(buf, SIZEOF(buf), "%c", ch);
        else
-               snprintf(buf, sizeof(buf), "\\%o", ch);
+               snprintf(buf, SIZEOF(buf), "\\%o", ch);
        return(buf);
 }
index 304369eb293cb868e9a1be2f8bb723848b4e93e2..3439b5a2a16bfa4b2db2385acb61c0bbb35ad4d7 100644 (file)
@@ -1,3 +1,5 @@
+#include "amanda.h"
+
 /*
  * The matching engine and friends.  This file is #included by regexec.c
  * after suitable #defines of a variety of macros used herein, so that
@@ -63,20 +65,20 @@ struct match {
  ==    size_t nmatch, regmatch_t pmatch[], int eflags);
  */
 static int                     /* 0 success, REG_NOMATCH failure */
-matcher(g, string, nmatch, pmatch, eflags)
-register struct re_guts *g;
-const char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
+matcher(
+    struct re_guts *   g,
+    const char *       string,
+    size_t             nmatch,
+    regmatch_t         pmatch[],
+    int                        eflags)
 {
        register const char *endp;
-       register int i;
+       register size_t i;
        struct match mv;
        register struct match *m = &mv;
        register const char *dp;
-       const register sopno gf = g->firststate+1;      /* +1 for OEND */
-       const register sopno gl = g->laststate;
+       const sopno gf = g->firststate+1;       /* +1 for OEND */
+       const sopno gl = g->laststate;
        const char *start;
        const char *stop;
 
@@ -84,8 +86,8 @@ int eflags;
        if (g->cflags&REG_NOSUB)
                nmatch = 0;
        if (eflags&REG_STARTEND) {
-               start = string + pmatch[0].rm_so;
-               stop = string + pmatch[0].rm_eo;
+               start = string + (int)pmatch[0].rm_so;
+               stop = string + (int)pmatch[0].rm_eo;
        } else {
                start = string;
                stop = start + strlen(start);
@@ -95,15 +97,19 @@ int eflags;
 
        /* prescreening; this does wonders for this rather slow code */
        if (g->must != NULL) {
-               for (dp = start; dp < stop; dp++)
-                       if (*dp == g->must[0] && stop - dp >= g->mlen &&
-                               memcmp(dp, g->must, (size_t)g->mlen) == 0)
+               for (dp = start; dp < stop; dp++) {
+                       if ((*dp == g->must[0]) &&
+                           ((sopno)(stop - dp) >= g->mlen) &&
+                           (memcmp(dp, g->must, (size_t)g->mlen) == 0)) {
                                break;
+                       }
+               }
                if (dp == stop)         /* we didn't find g->must */
                        return(REG_NOMATCH);
        }
 
        /* match struct setup */
+       memset(m, 0, SIZEOF(*m));
        m->g = g;
        m->eflags = eflags;
        m->pmatch = NULL;
@@ -116,20 +122,18 @@ int eflags;
        SETUP(m->fresh);
        SETUP(m->tmp);
        SETUP(m->empty);
-       CLEAR(m->empty);
 
        /* this loop does only one repetition except for backrefs */
        for (;;) {
                endp = fast(m, start, stop, gf, gl);
-               if (endp == NULL) {             /* a miss */
+               if ((endp == NULL) || (m->coldp == NULL)) {     /* a miss */
                        STATETEARDOWN(m);
                        return(REG_NOMATCH);
                }
+
                if (nmatch == 0 && !g->backrefs)
                        break;          /* no further info needed */
 
-               /* where? */
-               assert(m->coldp != NULL);
                for (;;) {
                        NOTE("finding start");
                        endp = slow(m, m->coldp, stop, gf, gl);
@@ -143,21 +147,23 @@ int eflags;
 
                /* oh my, he wants the subexpressions... */
                if (m->pmatch == NULL)
-                       m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) *
-                                                       sizeof(regmatch_t));
+                       m->pmatch = (regmatch_t *)alloc((m->g->nsub + 1) *
+                                                       SIZEOF(regmatch_t));
                if (m->pmatch == NULL) {
                        STATETEARDOWN(m);
                        return(REG_ESPACE);
                }
                for (i = 1; i <= m->g->nsub; i++)
-                       m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
+                       m->pmatch[i].rm_so = m->pmatch[i].rm_eo = (regoff_t)-1;
                if (!g->backrefs && !(m->eflags&REG_BACKR)) {
                        NOTE("dissecting");
                        dp = dissect(m, m->coldp, endp, gf, gl);
                } else {
-                       if (g->nplus > 0 && m->lastpos == NULL)
-                               m->lastpos = (const char **)malloc((g->nplus+1) *
-                                                       sizeof(const char *));
+                       if (g->nplus > 0 && m->lastpos == NULL) {
+                               m->lastpos = (const char **)
+                                   alloc(((size_t)g->nplus+1) *
+                                               SIZEOF(const char *));
+                       }
                        if (g->nplus > 0 && m->lastpos == NULL) {
                                free(m->pmatch);
                                STATETEARDOWN(m);
@@ -200,18 +206,20 @@ int eflags;
        }
 
        /* fill in the details if requested */
+       /*@ignore@*/
        if (nmatch > 0) {
-               pmatch[0].rm_so = m->coldp - m->offp;
-               pmatch[0].rm_eo = endp - m->offp;
+               pmatch[0].rm_so = (regoff_t)(m->coldp - m->offp);
+               pmatch[0].rm_eo = (regoff_t)(endp - m->offp);
        }
+       /*@end@*/
        if (nmatch > 1) {
                assert(m->pmatch != NULL);
                for (i = 1; i < nmatch; i++)
                        if (i <= m->g->nsub)
                                pmatch[i] = m->pmatch[i];
                        else {
-                               pmatch[i].rm_so = -1;
-                               pmatch[i].rm_eo = -1;
+                               pmatch[i].rm_so = (regoff_t)-1;
+                               pmatch[i].rm_eo = (regoff_t)-1;
                        }
        }
 
@@ -225,26 +233,26 @@ int eflags;
 
 /*
  - dissect - figure out what matched what, no back references
- == static const char *dissect(register struct match *m, char *start, \
- ==    char *stop, sopno startst, sopno stopst);
+ == static const char *dissect(register struct match *m, const char *start, \
+ ==    const char *stop, sopno startst, sopno stopst);
  */
 static const char *                    /* == stop (success) always */
-dissect(m, start, stop, startst, stopst)
-register struct match *m;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
+dissect(
+    struct match *     m,
+    const char *       start,
+    const char *       stop,
+    sopno              startst,
+    sopno              stopst)
 {
-       register int i;
-       register sopno ss;      /* start sop of current subRE */
-       register sopno es;      /* end sop of current subRE */
+       size_t i;
+       register sopno ss;              /* start sop of current subRE */
+       register sopno es;              /* end sop of current subRE */
        register const char *sp;        /* start of string matched by it */
        register const char *stp;       /* string matched by it cannot pass here */
-       register const char *rest;      /* start of rest of string */
+       register const char *rest = NULL;/* start of rest of string */
        register const char *tail;      /* string unmatched by rest of RE */
-       register sopno ssub;    /* start sop of subsubRE */
-       register sopno esub;    /* end sop of subsubRE */
+       register sopno ssub;            /* start sop of subsubRE */
+       register sopno esub;            /* end sop of subsubRE */
        register const char *ssp;       /* start of string matched by subsubRE */
        register const char *sep;       /* end of string matched by subsubRE */
        register const char *oldssp;    /* previous ssp */
@@ -260,6 +268,7 @@ sopno stopst;
                case OQUEST_:
                        es += OPND(m->g->strip[es]);
                        break;
+
                case OCH_:
                        while (OP(m->g->strip[es]) != O_CH)
                                es += OPND(m->g->strip[es]);
@@ -270,30 +279,33 @@ sopno stopst;
                /* figure out what it matched */
                switch (OP(m->g->strip[ss])) {
                case OEND:
-                       assert(nope);
                        break;
+
                case OCHAR:
                        sp++;
                        break;
+
                case OBOL:
                case OEOL:
                case OBOW:
                case OEOW:
                        break;
+
                case OANY:
                case OANYOF:
                        sp++;
                        break;
+
                case OBACK_:
                case O_BACK:
-                       assert(nope);
                        break;
+
                /* cases where length of match is hard to find */
                case OQUEST_:
                        stp = stop;
+                       rest = slow(m, sp, stp, ss, es);
                        for (;;) {
                                /* how long could this one be? */
-                               rest = slow(m, sp, stp, ss, es);
                                assert(rest != NULL);   /* it did match */
                                /* could the rest match the rest? */
                                tail = slow(m, rest, stop, es, stopst);
@@ -302,6 +314,7 @@ sopno stopst;
                                /* no -- try a shorter match for this one */
                                stp = rest - 1;
                                assert(stp >= sp);      /* it did work */
+                               rest = slow(m, sp, stp, ss, es);
                        }
                        ssub = ss + 1;
                        esub = es - 1;
@@ -309,10 +322,10 @@ sopno stopst;
                        if (slow(m, sp, rest, ssub, esub) != NULL) {
                                dp = dissect(m, sp, rest, ssub, esub);
                                assert(dp == rest);
-                       } else          /* no */
-                               assert(sp == rest);
+                       }
                        sp = rest;
                        break;
+
                case OPLUS_:
                        stp = stop;
                        for (;;) {
@@ -331,12 +344,13 @@ sopno stopst;
                        esub = es - 1;
                        ssp = sp;
                        oldssp = ssp;
+                       sep = slow(m, ssp, rest, ssub, esub);
                        for (;;) {      /* find last match of innards */
-                               sep = slow(m, ssp, rest, ssub, esub);
                                if (sep == NULL || sep == ssp)
                                        break;  /* failed or matched null */
                                oldssp = ssp;   /* on to next try */
                                ssp = sep;
+                               sep = slow(m, ssp, rest, ssub, esub);
                        }
                        if (sep == NULL) {
                                /* last successful match */
@@ -347,8 +361,9 @@ sopno stopst;
                        assert(slow(m, ssp, sep, ssub, esub) == rest);
                        dp = dissect(m, ssp, sep, ssub, esub);
                        assert(dp == sep);
-                       sp = rest;
+                       sp = dp;
                        break;
+
                case OCH_:
                        stp = stop;
                        for (;;) {
@@ -366,6 +381,7 @@ sopno stopst;
                        ssub = ss + 1;
                        esub = ss + OPND(m->g->strip[ss]) - 1;
                        assert(OP(m->g->strip[esub]) == OOR1);
+                       /*@ignore@*/
                        for (;;) {      /* find first matching branch */
                                if (slow(m, sp, rest, ssub, esub) == rest)
                                        break;  /* it matched all of it */
@@ -382,27 +398,30 @@ sopno stopst;
                        }
                        dp = dissect(m, sp, rest, ssub, esub);
                        assert(dp == rest);
-                       sp = rest;
+                       sp = dp;
+                       /*@end@*/
                        break;
+
                case O_PLUS:
                case O_QUEST:
                case OOR1:
                case OOR2:
                case O_CH:
-                       assert(nope);
                        break;
+
                case OLPAREN:
-                       i = OPND(m->g->strip[ss]);
+                       i = (size_t)OPND(m->g->strip[ss]);
                        assert(0 < i && i <= m->g->nsub);
-                       m->pmatch[i].rm_so = sp - m->offp;
+                       m->pmatch[i].rm_so = (regoff_t)(sp - m->offp);
                        break;
+
                case ORPAREN:
-                       i = OPND(m->g->strip[ss]);
+                       i = (size_t)OPND(m->g->strip[ss]);
                        assert(0 < i && i <= m->g->nsub);
-                       m->pmatch[i].rm_eo = sp - m->offp;
+                       m->pmatch[i].rm_eo = (regoff_t)(sp - m->offp);
                        break;
+
                default:                /* uh oh */
-                       assert(nope);
                        break;
                }
        }
@@ -417,15 +436,15 @@ sopno stopst;
  ==    const char *stop, sopno startst, sopno stopst, sopno lev);
  */
 static const char *            /* == stop (success) or NULL (failure) */
-backref(m, start, stop, startst, stopst, lev)
-register struct match *m;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
-sopno lev;                     /* PLUS nesting level */
+backref(
+    struct match *     m,
+    const char *       start,
+    const char *       stop,
+    sopno              startst,
+    sopno              stopst,
+    sopno              lev)                    /* PLUS nesting level */
 {
-       register int i;
+       register size_t i;
        register sopno ss;      /* start sop of current subRE */
        register const char *sp;/* start of string matched by it */
        register sopno ssub;    /* start sop of subsubRE */
@@ -460,41 +479,36 @@ sopno lev;                        /* PLUS nesting level */
                                return(NULL);
                        break;
                case OBOL:
-                       if ( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
+                       if (!((sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
                                        (sp < m->endp && *(sp-1) == '\n' &&
-                                               (m->g->cflags&REG_NEWLINE)) )
-                               { /* yes */ }
-                       else
+                                               (m->g->cflags&REG_NEWLINE)))) {
                                return(NULL);
+                       }
                        break;
                case OEOL:
-                       if ( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+                       if (!((sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
                                        (sp < m->endp && *sp == '\n' &&
-                                               (m->g->cflags&REG_NEWLINE)) )
-                               { /* yes */ }
-                       else
+                                               (m->g->cflags&REG_NEWLINE)))) {
                                return(NULL);
+                       }
                        break;
                case OBOW:
-                       if (( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
-                                       (sp < m->endp && *(sp-1) == '\n' &&
-                                               (m->g->cflags&REG_NEWLINE)) ||
-                                       (sp > m->beginp &&
-                                                       !ISWORD(*(sp-1))) ) &&
-                                       (sp < m->endp && ISWORD(*sp)) )
-                               { /* yes */ }
-                       else
+                       if (!(((sp == m->beginp && !(m->eflags&REG_NOTBOL))
+                           || ((sp < m->endp) && (*(sp-1) == '\n')
+                             && (m->g->cflags & REG_NEWLINE))
+                           || (((sp > m->beginp) && !ISWORD(*(sp-1)))
+                             && (sp < m->endp && ISWORD(*sp)))))) {
                                return(NULL);
+                       }
                        break;
                case OEOW:
-                       if ((sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+                       if (!(((sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
                                        (sp < m->endp && *sp == '\n' &&
                                                (m->g->cflags&REG_NEWLINE)) ||
                                        (sp < m->endp && !ISWORD(*sp)) ) &&
-                                       (sp > m->beginp && ISWORD(*(sp-1))) )
-                               { /* yes */ }
-                       else
+                                       (sp > m->beginp && ISWORD(*(sp-1))))) {
                                return(NULL);
+                       }
                        break;
                case O_QUEST:
                        break;
@@ -523,34 +537,34 @@ sopno lev;                        /* PLUS nesting level */
        s = m->g->strip[ss];
        switch (OP(s)) {
        case OBACK_:            /* the vilest depths */
-               i = OPND(s);
+               i = (size_t)OPND(s);
                assert(0 < i && i <= m->g->nsub);
-               if (m->pmatch[i].rm_eo == -1)
+               if (m->pmatch[i].rm_eo == (regoff_t)-1)
                        return(NULL);
-               assert(m->pmatch[i].rm_so != -1);
-               len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
-               assert(stop - m->beginp >= len);
+               assert(m->pmatch[i].rm_so != (regoff_t)-1);
+               len = (size_t)(m->pmatch[i].rm_eo - m->pmatch[i].rm_so);
+               assert((size_t)(stop - m->beginp) >= len);
                if (sp > stop - len)
                        return(NULL);   /* not enough left to match */
-               ssp = m->offp + m->pmatch[i].rm_so;
+               ssp = m->offp + (size_t)m->pmatch[i].rm_so;
                if (memcmp(sp, ssp, len) != 0)
                        return(NULL);
                while (m->g->strip[ss] != SOP(O_BACK, i))
                        ss++;
                return(backref(m, sp+len, stop, ss+1, stopst, lev));
-               break;
+
        case OQUEST_:           /* to null or not */
                dp = backref(m, sp, stop, ss+1, stopst, lev);
                if (dp != NULL)
                        return(dp);     /* not */
                return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev));
-               break;
+
        case OPLUS_:
                assert(m->lastpos != NULL);
                assert(lev+1 <= m->g->nplus);
                m->lastpos[lev+1] = sp;
                return(backref(m, sp, stop, ss+1, stopst, lev+1));
-               break;
+
        case O_PLUS:
                if (sp == m->lastpos[lev])      /* last pass matched null */
                        return(backref(m, sp, stop, ss+1, stopst, lev-1));
@@ -559,9 +573,8 @@ sopno lev;                  /* PLUS nesting level */
                dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev);
                if (dp == NULL)
                        return(backref(m, sp, stop, ss+1, stopst, lev-1));
-               else
-                       return(dp);
-               break;
+               return(dp);
+
        case OCH_:              /* find the right one, if any */
                ssub = ss + 1;
                esub = ss + OPND(s) - 1;
@@ -572,7 +585,7 @@ sopno lev;                  /* PLUS nesting level */
                                return(dp);
                        /* that one missed, try next one */
                        if (OP(m->g->strip[esub]) == O_CH)
-                               return(NULL);   /* there is none */
+                               break;
                        esub++;
                        assert(OP(m->g->strip[esub]) == OOR2);
                        ssub = esub + 1;
@@ -582,37 +595,33 @@ sopno lev;                        /* PLUS nesting level */
                        else
                                assert(OP(m->g->strip[esub]) == O_CH);
                }
-               break;
+               return(NULL);   /* there is none */
+
        case OLPAREN:           /* must undo assignment if rest fails */
-               i = OPND(s);
+               i = (size_t)OPND(s);
                assert(0 < i && i <= m->g->nsub);
                offsave = m->pmatch[i].rm_so;
-               m->pmatch[i].rm_so = sp - m->offp;
+               m->pmatch[i].rm_so = (regoff_t)(sp - m->offp);
                dp = backref(m, sp, stop, ss+1, stopst, lev);
                if (dp != NULL)
                        return(dp);
                m->pmatch[i].rm_so = offsave;
                return(NULL);
-               break;
+
        case ORPAREN:           /* must undo assignment if rest fails */
-               i = OPND(s);
+               i = (size_t)OPND(s);
                assert(0 < i && i <= m->g->nsub);
                offsave = m->pmatch[i].rm_eo;
-               m->pmatch[i].rm_eo = sp - m->offp;
+               m->pmatch[i].rm_eo = (regoff_t)(sp - m->offp);
                dp = backref(m, sp, stop, ss+1, stopst, lev);
                if (dp != NULL)
                        return(dp);
                m->pmatch[i].rm_eo = offsave;
                return(NULL);
-               break;
+
        default:                /* uh oh */
-               assert(nope);
                break;
        }
-
-       /* "can't happen" */
-       assert(nope);
-       /* NOTREACHED */
        return((const char *)NULL);     /* dummy */
 }
 
@@ -622,12 +631,12 @@ sopno lev;                        /* PLUS nesting level */
  ==    const char *stop, sopno startst, sopno stopst);
  */
 static const char *                    /* where tentative match ended, or NULL */
-fast(m, start, stop, startst, stopst)
-register struct match *m;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
+fast(
+    struct match *     m,
+    const char *       start,
+    const char *       stop,
+    sopno              startst,
+    sopno              stopst)
 {
        register states st = m->st;
        register states fresh = m->fresh;
@@ -713,12 +722,12 @@ sopno stopst;
  ==    const char *stop, sopno startst, sopno stopst);
  */
 static const char *                    /* where it ended */
-slow(m, start, stop, startst, stopst)
-register struct match *m;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
+slow(
+    struct match *     m,
+    const char *       start,
+    const char *       stop,
+    sopno              startst,
+    sopno              stopst)
 {
        register states st = m->st;
        register states empty = m->empty;
@@ -809,20 +818,20 @@ sopno stopst;
  == #define    NNONCHAR        (CODEMAX-CHAR_MAX)
  */
 static states
-step(g, start, stop, bef, ch, aft)
-register struct re_guts *g;
-sopno start;                   /* start state within strip */
-sopno stop;                    /* state after stop state within strip */
-register states bef;           /* states reachable before */
-int ch;                                /* character or NONCHAR code */
-register states aft;           /* states already known reachable after */
+step(
+    struct re_guts *   g,
+    sopno              start,  /* start state within strip */
+    sopno              stop,   /* state after stop state within strip */
+    register states    bef,    /* states reachable before */
+    int                        ch,     /* character or NONCHAR code */
+    states             aft)    /* states already known reachable after */
 {
        register cset *cs;
        register sop s;
        register sopno pc;
-       register onestate here;         /* note, macros know this name */
+       register sopno here;            /* note, macros know this name */
        register sopno look;
-       register long i;
+       register unsigned long i;
 
        for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
                s = g->strip[pc];
@@ -870,7 +879,7 @@ register states aft;                /* states already known reachable after */
                        break;
                case O_PLUS:            /* both forward and back */
                        FWD(aft, aft, 1);
-                       i = ISSETBACK(aft, OPND(s));
+                       i = (unsigned long)ISSETBACK(aft, OPND(s));
                        BACK(aft, aft, OPND(s));
                        if (!i && ISSETBACK(aft, OPND(s))) {
                                /* oho, must reconsider loop body */
@@ -914,7 +923,6 @@ register states aft;                /* states already known reachable after */
                        FWD(aft, aft, 1);
                        break;
                default:                /* ooooops... */
-                       assert(nope);
                        break;
                }
        }
@@ -931,12 +939,12 @@ register states aft;              /* states already known reachable after */
  == #endif
  */
 static void
-print(m, caption, st, ch, d)
-struct match *m;
-char *caption;
-states st;
-int ch;
-FILE *d;
+print(
+    struct match *     m,
+    char *             caption,
+    states             st,
+    int                        ch,
+    FILE *             d)
 {
        register struct re_guts *g = m->g;
        register int i;
@@ -964,13 +972,13 @@ FILE *d;
  == #endif
  */
 static void
-at(m, title, start, stop, startst, stopst)
-struct match *m;
-const char *title;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
+at(
+    struct match *     m,
+    const char *       title,
+    const char *       start,
+    const char *       stop,
+    sopno              startst,
+    sopno              stopst)
 {
        if (!(m->eflags&REG_TRACE))
                return;
@@ -994,15 +1002,15 @@ sopno stopst;
  * the non-debug compilation anyway, so it doesn't matter much.
  */
 static char *                  /* -> representation */
-pchar(ch)
-int ch;
+pchar(
+    int                ch)
 {
        static char pbuf[10];
 
        if (isprint(ch) || ch == ' ')
-               snprintf(pbuf, sizeof(pbuf), "%c", ch);
+               snprintf(pbuf, SIZEOF(pbuf), "%c", ch);
        else
-               snprintf(pbuf, sizeof(pbuf), "\\%o", ch);
+               snprintf(pbuf, SIZEOF(pbuf), "\\%o", ch);
        return(pbuf);
 }
 #endif
index 9105cc5e8750bf866c80bb3d353eaf88b0cc1602..8519d3669ce6a0e1bf2199600436c80dc4f7091d 100644 (file)
@@ -1,8 +1,5 @@
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
+#include "amanda.h"
 #include <regex.h>
-#include <assert.h>
 
 #include "main.ih"
 
@@ -76,9 +73,9 @@ char *argv[];
 
        err = regcomp(&re, argv[optind++], copts);
        if (err) {
-               len = regerror(err, &re, erbuf, sizeof(erbuf));
+               len = regerror(err, &re, erbuf, SIZEOF(erbuf));
                fprintf(stderr, "error %s, %d/%d `%s'\n",
-                       eprint(err), len, sizeof(erbuf), erbuf);
+                       eprint(err), len, SIZEOF(erbuf), erbuf);
                exit(status);
        }
        regprint(&re, stdout);  
@@ -94,9 +91,9 @@ char *argv[];
        }
        err = regexec(&re, argv[optind], (size_t)NS, subs, eopts);
        if (err) {
-               len = regerror(err, &re, erbuf, sizeof(erbuf));
+               len = regerror(err, &re, erbuf, SIZEOF(erbuf));
                fprintf(stderr, "error %s, %d/%d `%s'\n",
-                       eprint(err), len, sizeof(erbuf), erbuf);
+                       eprint(err), len, SIZEOF(erbuf), erbuf);
                exit(status);
        }
        if (!(copts&REG_NOSUB)) {
@@ -138,7 +135,7 @@ FILE *in;
        char *bpname = "REG_BADPAT";
        regex_t re;
 
-       while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
+       while (fgets(inbuf, (int)sizeof(inbuf), in) != NULL) {
                line++;
                if (inbuf[0] == '#' || inbuf[0] == '\n')
                        continue;                       /* NOTE CONTINUE */
@@ -163,7 +160,7 @@ FILE *in;
                                        options('c', f[1]) &~ REG_EXTENDED);
        }
 
-       ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
+       ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, SIZEOF(erbuf));
        if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) {
                fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n",
                                                        erbuf, badpat);
@@ -176,14 +173,14 @@ FILE *in;
                                                erbuf, SHORT-1, badpat);
                status = 1;
        }
-       ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
+       ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, SIZEOF(erbuf));
        if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
                fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n",
                                                erbuf, bpname);
                status = 1;
        }
        re.re_endp = bpname;
-       ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
+       ne = regerror(REG_ATOI, &re, erbuf, SIZEOF(erbuf));
        if (atoi(erbuf) != (int)REG_BADPAT) {
                fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
                                                erbuf, (long)REG_BADPAT);
@@ -223,17 +220,17 @@ int opts;                 /* may not match f1 */
        char f0copy[1000];
        char f2copy[1000];
 
-       strncpy(f0copy, f0, sizeof(f0copy)-1);
-       f0copy[sizeof(f0copy)-1] = '\0';
+       strncpy(f0copy, f0, SIZEOF(f0copy)-1);
+       f0copy[SIZEOF(f0copy)-1] = '\0';
        re.re_endp = (opts&REG_PEND) ? f0copy + strlen(f0copy) : NULL;
        fixstr(f0copy);
        err = regcomp(&re, f0copy, opts);
        if (err != 0 && (!opt('C', f1) || err != efind(f2))) {
                /* unexpected error or wrong error */
-               len = regerror(err, &re, erbuf, sizeof(erbuf));
+               len = regerror(err, &re, erbuf, SIZEOF(erbuf));
                fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
                                        line, type, eprint(err), len,
-                                       sizeof(erbuf), erbuf);
+                                       SIZEOF(erbuf), erbuf);
                status = 1;
        } else if (err == 0 && opt('C', f1)) {
                /* unexpected success */
@@ -248,8 +245,8 @@ int opts;                   /* may not match f1 */
                return;
        }
 
-       strncpy(f2copy, f2, sizeof(f2copy)-1);
-       f2copy[sizeof(f2copy)-1] = '\0';
+       strncpy(f2copy, f2, SIZEOF(f2copy)-1);
+       f2copy[SIZEOF(f2copy)-1] = '\0';
        fixstr(f2copy);
 
        if (options('e', f1)&REG_STARTEND) {
@@ -262,10 +259,10 @@ int opts;                 /* may not match f1 */
 
        if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
                /* unexpected error or wrong error */
-               len = regerror(err, &re, erbuf, sizeof(erbuf));
+               len = regerror(err, &re, erbuf, SIZEOF(erbuf));
                fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n",
                                        line, type, eprint(err), len,
-                                       sizeof(erbuf), erbuf);
+                                       SIZEOF(erbuf), erbuf);
                status = 1;
        } else if (err != 0) {
                /* nothing more to check */
@@ -427,7 +424,7 @@ char *should;
                                (sub.rm_so != -1 && sub.rm_eo == -1) ||
                                (sub.rm_so != -1 && sub.rm_so < 0) ||
                                (sub.rm_eo != -1 && sub.rm_eo < 0) ) {
-               snprintf(grump, sizeof(grump),
+               snprintf(grump, SIZEOF(grump),
                            "start %ld end %ld", (long)sub.rm_so,
                            (long)sub.rm_eo);
                return(grump);
@@ -441,7 +438,7 @@ char *should;
 
        /* check for in range */
        if (sub.rm_eo > strlen(str)) {
-               snprintf(grump, sizeof(grump),
+               snprintf(grump, SIZEOF(grump),
                            "start %ld end %ld, past end of string",
                            (long)sub.rm_so, (long)sub.rm_eo);
                return(grump);
@@ -453,13 +450,13 @@ char *should;
 
        /* check for not supposed to match */
        if (should == NULL) {
-               snprintf(grump, sizeof(grump), "matched `%.*s'", len, p);
+               snprintf(grump, SIZEOF(grump), "matched `%.*s'", len, p);
                return(grump);
        }
 
        /* check for wrong match */
        if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
-               snprintf(grump, sizeof(grump),
+               snprintf(grump, SIZEOF(grump),
                            "matched `%.*s' instead", len, p);
                return(grump);
        }
@@ -473,7 +470,7 @@ char *should;
        if (shlen == 0)
                shlen = 1;      /* force check for end-of-string */
        if (strncmp(p, at, shlen) != 0) {
-               snprintf(grump, sizeof(grump), "matched null at `%.20s'", p);
+               snprintf(grump, SIZEOF(grump), "matched null at `%.20s'", p);
                return(grump);
        }
        return(NULL);
@@ -490,8 +487,8 @@ int err;
        static char epbuf[100];
        size_t len;
 
-       len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
-       assert(len <= sizeof(epbuf));
+       len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, SIZEOF(epbuf));
+       assert(len <= SIZEOF(epbuf));
        return(epbuf);
 }
 
@@ -507,9 +504,9 @@ char *name;
        size_t n;
        regex_t re;
 
-       snprintf(efbuf, sizeof(efbuf), "REG_%s", name);
-       assert(strlen(efbuf) < sizeof(efbuf));
+       snprintf(efbuf, SIZEOF(efbuf), "REG_%s", name);
+       assert(strlen(efbuf) < SIZEOF(efbuf));
        re.re_endp = efbuf;
-       (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
+       (void) regerror(REG_ATOI, &re, efbuf, SIZEOF(efbuf));
        return(atoi(efbuf));
 }
index 252b246c7bd2538dda8890409c73e7a90e487064..92d2bfa9b5a4d8b5e2a935419f3d8523410ed5c7 100644 (file)
@@ -25,6 +25,11 @@ do
                        "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1(/*\2*/);'
                shift
                ;;
+       -A)     # funny Amanda P macro
+               peel="$peel
+                       "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1 P((\2));'
+               shift
+               ;;
        -b)     # funny Berkeley __P macro
                peel="$peel
                        "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1 __P((\2));'
index 08e8a9fcf4acce40b497f88e6b25f1fed7a61046..2f9fa70b53e6a63ffebb4df870b456a939e73fea 100644 (file)
@@ -1,11 +1,5 @@
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
+#include "amanda.h"
 #include <regex.h>
-
 #include "utils.h"
 #include "regex2.h"
 
@@ -21,8 +15,8 @@ struct parse {
        char *end;              /* end of string (-> NUL normally) */
        int error;              /* has an error been seen? */
        sop *strip;             /* malloced strip */
-       sopno ssize;            /* malloced strip size (allocated) */
-       sopno slen;             /* malloced strip length (used) */
+       size_t ssize;           /* malloced strip size (allocated) */
+       size_t slen;            /* malloced strip length (used) */
        int ncsalloc;           /* number of csets allocated */
        struct re_guts *g;
 #      define  NPAREN  10      /* we need to remember () 1-9 for back refs */
@@ -56,13 +50,13 @@ static char nuls[10];               /* place to point scanner in event of error */
 #define        MUSTEAT(c, e)   (REQUIRE(MORE() && GETNEXT() == (c), e))
 #define        MUSTNOTSEE(c, e)        (REQUIRE(!MORE() || PEEK() != (c), e))
 #define        EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
-#define        INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
-#define        AHEAD(pos)              dofwd(p, pos, HERE()-(pos))
-#define        ASTERN(sop, pos)        EMIT(sop, HERE()-pos)
-#define        HERE()          (p->slen)
-#define        THERE()         (p->slen - 1)
-#define        THERETHERE()    (p->slen - 2)
-#define        DROP(n) (p->slen -= (n))
+#define        INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(size_t)(pos)+1, (size_t)pos)
+#define        AHEAD(pos)              dofwd(p, (size_t)pos, HERE()-(size_t)(pos))
+#define        ASTERN(sop, pos)        EMIT(sop, HERE()-(size_t)(pos))
+#define        HERE()          (size_t)(p->slen)
+#define        THERE()         (size_t)(p->slen - 1)
+#define        THERETHERE()    (size_t)(p->slen - 2)
+#define        DROP(n)         (p->slen = p->slen - (size_t)(n))
 
 #ifndef NDEBUG
 static int never = 0;          /* for use in asserts; shuts lint up */
@@ -70,6 +64,45 @@ static int never = 0;                /* for use in asserts; shuts lint up */
 #define        never   0               /* some <assert.h>s have bugs too */
 #endif
 
+static void p_ere(struct parse *p, int stop);
+static void p_ere_exp(struct parse *p);
+static void p_str(struct parse *p);
+static void p_bre(struct parse *p, int end1, int end2);
+static int p_simp_re(struct parse *p, int starordinary);
+static int p_count(struct parse *p);
+static void p_bracket(struct parse *p);
+static void p_b_term(struct parse *p, cset *cs);
+static void p_b_cclass(struct parse *p, cset *cs);
+static void p_b_eclass(struct parse *p, cset *cs);
+static char p_b_symbol(struct parse *p);
+static char p_b_coll_elem(struct parse *p, int endc);
+static char othercase(int ch);
+static void bothcases(struct parse *p, int ch);
+static void ordinary(struct parse *p, int ch);
+static void nonnewline(struct parse *p);
+static void repeat(struct parse *p, sopno start, int from, int to);
+static int seterr(struct parse *p, int e);
+static cset * allocset(struct parse *p);
+static void freeset(struct parse *p, cset *cs);
+static int freezeset(struct parse *p, cset *cs);
+static int firstch(struct parse *p, cset *cs);
+static int nch(struct parse *p, cset *cs);
+static void mcadd(struct parse *p, cset *cs, char *cp);
+static void mcinvert(struct parse *p, cset *cs);
+static void mccase(struct parse *p, cset *cs);
+static int isinsets(struct re_guts *g, int c);
+static int samesets(struct re_guts *g, int c1, int c2);
+static void categorize(struct parse *p, struct re_guts *g);
+static sopno dupl(struct parse *p, sopno start, sopno finish);
+static void doemit(struct parse *p, sop op, size_t opnd);
+static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos);
+static void dofwd(struct parse *p, sopno pos, sop value);
+static void enlarge(struct parse *p, sopno size);
+static void stripsnug(struct parse *p, struct re_guts *g);
+static void findmust(struct parse *p, struct re_guts *g);
+static sopno pluscount(struct parse *p, struct re_guts *g);
+
+
 /*
  - regcomp - interface for parser and compilation
  = extern int regcomp(regex_t *, const char *, int);
@@ -83,16 +116,16 @@ static int never = 0;              /* for use in asserts; shuts lint up */
  = #define     REG_DUMP        0200
  */
 int                            /* 0 success, otherwise REG_something */
-regcomp(preg, pattern, cflags)
-regex_t *preg;
-const char *pattern;
-int cflags;
+regcomp(
+    regex_t *  preg,
+    const char *pattern,
+    int                cflags)
 {
        struct parse pa;
-       register struct re_guts *g;
-       register struct parse *p = &pa;
-       register int i;
-       register size_t len;
+       struct re_guts *g;
+       struct parse *p = &pa;
+       int i;
+       size_t len;
 #ifdef REDEBUG
 #      define  GOODFLAGS(f)    (f)
 #else
@@ -100,23 +133,27 @@ int cflags;
 #endif
 
        cflags = GOODFLAGS(cflags);
+#if !defined(__lint) /* Lint global check knows nobody calls with this combo */
        if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
                return(REG_INVARG);
 
-       if (cflags&REG_PEND) {
+       if (cflags & REG_PEND) {
+               /*@ignore@*/
                if (preg->re_endp < pattern)
                        return(REG_INVARG);
-               len = preg->re_endp - pattern;
+               len = (size_t)(preg->re_endp - pattern);
+               /*@end@*/
        } else
+#endif
                len = strlen((char *)pattern);
 
        /* do the mallocs early so failure handling is easy */
-       g = (struct re_guts *)malloc(sizeof(struct re_guts) +
-                                                       (NC-1)*sizeof(cat_t));
+       g = (struct re_guts *)malloc(SIZEOF(struct re_guts) +
+                                                       (NC-1)*SIZEOF(cat_t));
        if (g == NULL)
                return(REG_ESPACE);
-       p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
-       p->strip = (sop *)malloc(p->ssize * sizeof(sop));
+       p->ssize = (sopno)(((len / (size_t)2) * (size_t)3) + (size_t)1);
+       p->strip = (sop *)malloc((size_t)p->ssize * SIZEOF(sop));
        p->slen = 0;
        if (p->strip == NULL) {
                free((char *)g);
@@ -146,15 +183,15 @@ int cflags;
        g->nsub = 0;
        g->ncategories = 1;     /* category 0 is "everything else" */
        g->categories = &g->catspace[-(CHAR_MIN)];
-       (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t));
+       (void) memset((char *)g->catspace, 0, NC*SIZEOF(cat_t));
        g->backrefs = 0;
 
        /* do it */
        EMIT(OEND, 0);
-       g->firststate = THERE();
-       if (cflags&REG_EXTENDED)
+       g->firststate = (sopno)THERE();
+       if (cflags & REG_EXTENDED)
                p_ere(p, OUT);
-       else if (cflags&REG_NOSPEC)
+       else if (cflags & REG_NOSPEC)
                p_str(p);
        else
                p_bre(p, OUT, OUT);
@@ -167,9 +204,11 @@ int cflags;
        findmust(p, g);
        g->nplus = pluscount(p, g);
        g->magic = MAGIC2;
+       /*@ignore@*/
        preg->re_nsub = g->nsub;
        preg->re_g = g;
        preg->re_magic = MAGIC1;
+       /*@end@*/
 #ifndef REDEBUG
        /* not debugging, so can't rely on the assert() in regexec() */
        if (g->iflags&BAD)
@@ -184,25 +223,25 @@ int cflags;
 
 /*
  - p_ere - ERE parser top level, concatenation and alternation
- == static void p_ere(register struct parse *p, int stop);
+ == static void p_ere(struct parse *p, int stop);
  */
 static void
-p_ere(p, stop)
-register struct parse *p;
-int stop;                      /* character this ERE should end at */
+p_ere(
+    struct parse *     p,
+    int                        stop)   /* character this ERE should end at */
 {
-       register char c;
-       register sopno prevback = 0;
-       register sopno prevfwd = 0;
-       register sopno conc;
-       register int first = 1;         /* is this the first alternative? */
+       char c;
+       sopno prevback = 0;
+       sopno prevfwd = 0;
+       sopno conc;
+       int first = 1;          /* is this the first alternative? */
 
        for (;;) {
                /* do a bunch of concatenated expressions */
                conc = HERE();
                while (MORE() && (c = PEEK()) != '|' && c != stop)
                        p_ere_exp(p);
-               REQUIRE(HERE() != conc, REG_EMPTY);     /* require nonempty */
+               (void)REQUIRE(HERE() != conc, REG_EMPTY);       /* require nonempty */
 
                if (!EAT('|'))
                        break;          /* NOTE BREAK OUT */
@@ -230,17 +269,17 @@ int stop;                 /* character this ERE should end at */
 
 /*
  - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
- == static void p_ere_exp(register struct parse *p);
+ == static void p_ere_exp(struct parse *p);
  */
 static void
-p_ere_exp(p)
-register struct parse *p;
+p_ere_exp(
+    struct parse *     p)
 {
-       register char c;
-       register sopno pos;
-       register int count;
-       register int count2;
-       register sopno subno;
+       char c;
+       sopno pos;
+       int count;
+       int count2;
+       sopno subno;
        int wascaret = 0;
 
        assert(MORE());         /* caller should have ensured this */
@@ -249,7 +288,7 @@ register struct parse *p;
        pos = HERE();
        switch (c) {
        case '(':
-               REQUIRE(MORE(), REG_EPAREN);
+               (void)REQUIRE(MORE(), REG_EPAREN);
                p->g->nsub++;
                subno = p->g->nsub;
                if (subno < NPAREN)
@@ -262,7 +301,7 @@ register struct parse *p;
                        assert(p->pend[subno] != 0);
                }
                EMIT(ORPAREN, subno);
-               MUSTEAT(')', REG_EPAREN);
+               (void)MUSTEAT(')', REG_EPAREN);
                break;
 #ifndef POSIX_MISTAKE
        case ')':               /* happens only if no current unmatched ( */
@@ -305,12 +344,12 @@ register struct parse *p;
                p_bracket(p);
                break;
        case '\\':
-               REQUIRE(MORE(), REG_EESCAPE);
+               (void)REQUIRE(MORE(), REG_EESCAPE);
                c = GETNEXT();
                ordinary(p, c);
                break;
        case '{':               /* okay as ordinary except if digit follows */
-               REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT);
+               (void)REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT);
                /* FALLTHROUGH */
        default:
                ordinary(p, c);
@@ -326,7 +365,7 @@ register struct parse *p;
                return;         /* no repetition, we're done */
        NEXT();
 
-       REQUIRE(!wascaret, REG_BADRPT);
+       (void)REQUIRE(!wascaret, REG_BADRPT);
        switch (c) {
        case '*':       /* implemented as +? */
                /* this case does not require the (y|) trick, noKLUDGE */
@@ -353,16 +392,16 @@ register struct parse *p;
                if (EAT(',')) {
                        if (isdigit(PEEK())) {
                                count2 = p_count(p);
-                               REQUIRE(count <= count2, REG_BADBR);
+                               (void)REQUIRE(count <= count2, REG_BADBR);
                        } else          /* single number with comma */
-                               count2 = INFINITY;
+                               count2 = (int)REINFINITY;
                } else          /* just a single number */
                        count2 = count;
                repeat(p, pos, count, count2);
                if (!EAT('}')) {        /* error heuristics */
                        while (MORE() && PEEK() != '}')
                                NEXT();
-                       REQUIRE(MORE(), REG_EBRACE);
+                       (void)REQUIRE(MORE(), REG_EBRACE);
                        SETERROR(REG_BADBR);
                }
                break;
@@ -379,21 +418,21 @@ register struct parse *p;
 
 /*
  - p_str - string (no metacharacters) "parser"
- == static void p_str(register struct parse *p);
+ == static void p_str(struct parse *p);
  */
 static void
-p_str(p)
-register struct parse *p;
+p_str(
+    struct parse *     p)
 {
-       REQUIRE(MORE(), REG_EMPTY);
+       (void)REQUIRE(MORE(), REG_EMPTY);
        while (MORE())
                ordinary(p, GETNEXT());
 }
 
 /*
  - p_bre - BRE parser top level, anchoring and concatenation
- == static void p_bre(register struct parse *p, register int end1, \
- ==    register int end2);
+ == static void p_bre(struct parse *p, register int end1, \
+ ==    int end2);
  * Giving end1 as OUT essentially eliminates the end1/end2 check.
  *
  * This implementation is a bit of a kludge, in that a trailing $ is first
@@ -403,14 +442,14 @@ register struct parse *p;
  * The amount of lookahead needed to avoid this kludge is excessive.
  */
 static void
-p_bre(p, end1, end2)
-register struct parse *p;
-register int end1;             /* first terminating character */
-register int end2;             /* second terminating character */
+p_bre(
+    struct parse *     p,
+    int                        end1,           /* first terminating character */
+    int                        end2)           /* second terminating character */
 {
-       register sopno start = HERE();
-       register int first = 1;                 /* first subexpression? */
-       register int wasdollar = 0;
+       sopno start = HERE();
+       int first = 1;                  /* first subexpression? */
+       int wasdollar = 0;
 
        if (EAT('^')) {
                EMIT(OBOL, 0);
@@ -428,24 +467,24 @@ register int end2;                /* second terminating character */
                p->g->neol++;
        }
 
-       REQUIRE(HERE() != start, REG_EMPTY);    /* require nonempty */
+       (void)REQUIRE(HERE() != start, REG_EMPTY);      /* require nonempty */
 }
 
 /*
  - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
- == static int p_simp_re(register struct parse *p, int starordinary);
+ == static int p_simp_re(struct parse *p, int starordinary);
  */
 static int                     /* was the simple RE an unbackslashed $? */
-p_simp_re(p, starordinary)
-register struct parse *p;
-int starordinary;              /* is a leading * an ordinary character? */
+p_simp_re(
+    struct parse *     p,
+    int                        starordinary)/* is a leading * an ordinary character? */
 {
-       register int c;
-       register int count;
-       register int count2;
-       register sopno pos;
-       register int i;
-       register sopno subno;
+       int c;
+       int count;
+       int count2;
+       sopno pos;
+       int i;
+       sopno subno;
 #      define  BACKSL  (1<<CHAR_BIT)
 
        pos = HERE();           /* repetion op, if any, covers from here */
@@ -453,7 +492,7 @@ int starordinary;           /* is a leading * an ordinary character? */
        assert(MORE());         /* caller should have ensured this */
        c = GETNEXT();
        if (c == '\\') {
-               REQUIRE(MORE(), REG_EESCAPE);
+               (void)REQUIRE(MORE(), REG_EESCAPE);
                c = BACKSL | (unsigned char)GETNEXT();
        }
        switch (c) {
@@ -483,7 +522,7 @@ int starordinary;           /* is a leading * an ordinary character? */
                        assert(p->pend[subno] != 0);
                }
                EMIT(ORPAREN, subno);
-               REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
+               (void)REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
                break;
        case BACKSL|')':        /* should not get here -- must be user */
        case BACKSL|'}':
@@ -501,19 +540,19 @@ int starordinary;         /* is a leading * an ordinary character? */
                i = (c&~BACKSL) - '0';
                assert(i < NPAREN);
                if (p->pend[i] != 0) {
-                       assert(i <= p->g->nsub);
+                       assert(i <= (int)p->g->nsub);
                        EMIT(OBACK_, i);
                        assert(p->pbegin[i] != 0);
                        assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
                        assert(OP(p->strip[p->pend[i]]) == ORPAREN);
-                       (void) dupl(p, p->pbegin[i]+1, p->pend[i]);
+                       (void)dupl(p, p->pbegin[i]+1, p->pend[i]);
                        EMIT(O_BACK, i);
                } else
                        SETERROR(REG_ESUBREG);
                p->g->backrefs = 1;
                break;
        case '*':
-               REQUIRE(starordinary, REG_BADRPT);
+               (void)REQUIRE(starordinary, REG_BADRPT);
                /* FALLTHROUGH */
        default:
                ordinary(p, c &~ BACKSL);
@@ -531,16 +570,16 @@ int starordinary;         /* is a leading * an ordinary character? */
                if (EAT(',')) {
                        if (MORE() && isdigit(PEEK())) {
                                count2 = p_count(p);
-                               REQUIRE(count <= count2, REG_BADBR);
+                               (void)REQUIRE(count <= count2, REG_BADBR);
                        } else          /* single number with comma */
-                               count2 = INFINITY;
+                               count2 = REINFINITY;
                } else          /* just a single number */
                        count2 = count;
                repeat(p, pos, count, count2);
                if (!EATTWO('\\', '}')) {       /* error heuristics */
                        while (MORE() && !SEETWO('\\', '}'))
                                NEXT();
-                       REQUIRE(MORE(), REG_EBRACE);
+                       (void)REQUIRE(MORE(), REG_EBRACE);
                        SETERROR(REG_BADBR);
                }
        } else if (c == (unsigned char)'$')     /* $ (but not \$) ends it */
@@ -551,37 +590,37 @@ int starordinary;         /* is a leading * an ordinary character? */
 
 /*
  - p_count - parse a repetition count
- == static int p_count(register struct parse *p);
+ == static int p_count(struct parse *p);
  */
 static int                     /* the value */
-p_count(p)
-register struct parse *p;
+p_count(
+    struct parse *     p)
 {
-       register int count = 0;
-       register int ndigits = 0;
+       int count = 0;
+       int ndigits = 0;
 
        while (MORE() && isdigit(PEEK()) && count <= DUPMAX) {
                count = count*10 + (GETNEXT() - '0');
                ndigits++;
        }
 
-       REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
+       (void)REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
        return(count);
 }
 
 /*
  - p_bracket - parse a bracketed character list
- == static void p_bracket(register struct parse *p);
+ == static void p_bracket(struct parse *p);
  *
  * Note a significant property of this code:  if the allocset() did SETERROR,
  * no set operations are done.
  */
 static void
-p_bracket(p)
-register struct parse *p;
+p_bracket(
+    struct parse *     p)
 {
-       register cset *cs = allocset(p);
-       register int invert = 0;
+       cset *cs = allocset(p);
+       int invert = 0;
 
        /* Dept of Truly Sickening Special-Case Kludges */
        if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
@@ -605,14 +644,14 @@ register struct parse *p;
                p_b_term(p, cs);
        if (EAT('-'))
                CHadd(cs, '-');
-       MUSTEAT(']', REG_EBRACK);
+       (void)MUSTEAT(']', REG_EBRACK);
 
        if (p->error != 0)      /* don't mess things up further */
                return;
 
        if (p->g->cflags&REG_ICASE) {
-               register int i;
-               register int ci;
+               int i;
+               int ci;
 
                for (i = p->g->csetsize - 1; i >= 0; i--)
                        if (CHIN(cs, i) && isalpha(i)) {
@@ -624,7 +663,7 @@ register struct parse *p;
                        mccase(p, cs);
        }
        if (invert) {
-               register int i;
+               int i;
 
                for (i = p->g->csetsize - 1; i >= 0; i--)
                        if (CHIN(cs, i))
@@ -648,26 +687,26 @@ register struct parse *p;
 
 /*
  - p_b_term - parse one term of a bracketed character list
- == static void p_b_term(register struct parse *p, register cset *cs);
+ == static void p_b_term(struct parse *p, register cset *cs);
  */
 static void
-p_b_term(p, cs)
-register struct parse *p;
-register cset *cs;
+p_b_term(
+    struct parse *     p,
+    cset *             cs)
 {
-       register char c;
-       register char start, finish;
-       register int i;
+       char c;
+       char start, finish;
+       int i;
 
        /* classify what we've got */
        switch ((MORE()) ? PEEK() : '\0') {
        case '[':
-               c = (MORE2()) ? PEEK2() : '\0';
+               c = (char)((MORE2()) ? PEEK2() : '\0');
                break;
        case '-':
                SETERROR(REG_ERANGE);
                return;                 /* NOTE RETURN */
-               break;
+
        default:
                c = '\0';
                break;
@@ -676,36 +715,36 @@ register cset *cs;
        switch (c) {
        case ':':               /* character class */
                NEXT2();
-               REQUIRE(MORE(), REG_EBRACK);
+               (void)REQUIRE(MORE(), REG_EBRACK);
                c = PEEK();
-               REQUIRE(c != '-' && c != ']', REG_ECTYPE);
+               (void)REQUIRE(c != '-' && c != ']', REG_ECTYPE);
                p_b_cclass(p, cs);
-               REQUIRE(MORE(), REG_EBRACK);
-               REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
+               (void)REQUIRE(MORE(), REG_EBRACK);
+               (void)REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
                break;
        case '=':               /* equivalence class */
                NEXT2();
-               REQUIRE(MORE(), REG_EBRACK);
+               (void)REQUIRE(MORE(), REG_EBRACK);
                c = PEEK();
-               REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
+               (void)REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
                p_b_eclass(p, cs);
-               REQUIRE(MORE(), REG_EBRACK);
-               REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
+               (void)REQUIRE(MORE(), REG_EBRACK);
+               (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
                break;
        default:                /* symbol, ordinary character, or range */
 /* xxx revision needed for multichar stuff */
-               start = p_b_symbol(p);
+               start = (char)p_b_symbol(p);
                if (SEE('-') && MORE2() && PEEK2() != ']') {
                        /* range */
                        NEXT();
                        if (EAT('-'))
                                finish = '-';
                        else
-                               finish = p_b_symbol(p);
+                               finish = (char)p_b_symbol(p);
                } else
                        finish = start;
 /* xxx what about signed chars here... */
-               REQUIRE(start <= finish, REG_ERANGE);
+               (void)REQUIRE(start <= finish, REG_ERANGE);
                for (i = start; i <= finish; i++)
                        CHadd(cs, i);
                break;
@@ -714,22 +753,22 @@ register cset *cs;
 
 /*
  - p_b_cclass - parse a character-class name and deal with it
- == static void p_b_cclass(register struct parse *p, register cset *cs);
+ == static void p_b_cclass(struct parse *p, register cset *cs);
  */
 static void
-p_b_cclass(p, cs)
-register struct parse *p;
-register cset *cs;
+p_b_cclass(
+    struct parse *     p,
+    cset *             cs)
 {
-       register char *sp = p->next;
-       register struct cclass *cp;
-       register size_t len;
-       register char *u;
-       register char c;
+       char *sp = p->next;
+       struct cclass *cp;
+       size_t len;
+       char *u;
+       char c;
 
        while (MORE() && isalpha(PEEK()))
                NEXT();
-       len = p->next - sp;
+       len = (size_t)(p->next - sp);
        for (cp = cclasses; cp->name != NULL; cp++)
                if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
                        break;
@@ -748,68 +787,68 @@ register cset *cs;
 
 /*
  - p_b_eclass - parse an equivalence-class name and deal with it
- == static void p_b_eclass(register struct parse *p, register cset *cs);
+ == static void p_b_eclass(struct parse *p, register cset *cs);
  *
  * This implementation is incomplete. xxx
  */
 static void
-p_b_eclass(p, cs)
-register struct parse *p;
-register cset *cs;
+p_b_eclass(
+    struct parse *     p,
+    cset *             cs)
 {
-       register char c;
+       char c;
 
-       c = p_b_coll_elem(p, '=');
+       c = (char)p_b_coll_elem(p, '=');
        CHadd(cs, c);
 }
 
 /*
  - p_b_symbol - parse a character or [..]ed multicharacter collating symbol
- == static char p_b_symbol(register struct parse *p);
+ == static char p_b_symbol(struct parse *p);
  */
 static char                    /* value of symbol */
-p_b_symbol(p)
-register struct parse *p;
+p_b_symbol(
+    struct parse *     p)
 {
-       register char value;
+       char value;
 
-       REQUIRE(MORE(), REG_EBRACK);
+       (void)REQUIRE(MORE(), REG_EBRACK);
        if (!EATTWO('[', '.'))
                return(GETNEXT());
 
        /* collating symbol */
-       value = p_b_coll_elem(p, '.');
-       REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
+       value = (char)p_b_coll_elem(p, '.');
+       (void)REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
        return(value);
 }
 
 /*
  - p_b_coll_elem - parse a collating-element name and look it up
- == static char p_b_coll_elem(register struct parse *p, int endc);
+ == static char p_b_coll_elem(struct parse *p, int endc);
  */
 static char                    /* value of collating element */
-p_b_coll_elem(p, endc)
-register struct parse *p;
-int endc;                      /* name ended by endc,']' */
+p_b_coll_elem(
+    struct parse *     p,
+    int                        endc)   /* name ended by endc,']' */
 {
-       register char *sp = p->next;
-       register struct cname *cp;
-       register int len;
+       char *sp = p->next;
+       struct cname *cp;
+       size_t len;
 
        while (MORE() && !SEETWO(endc, ']'))
                NEXT();
        if (!MORE()) {
                SETERROR(REG_EBRACK);
-               return(0);
+               return((char)0);
        }
-       len = p->next - sp;
+       len = (size_t)(p->next - sp);
        for (cp = cnames; cp->name != NULL; cp++)
                if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
                        return(cp->code);       /* known name */
        if (len == 1)
                return(*sp);    /* single character */
        SETERROR(REG_ECOLLATE);                 /* neither */
-       return(0);
+       return((char)0);
 }
 
 /*
@@ -817,8 +856,8 @@ int endc;                   /* name ended by endc,']' */
  == static char othercase(int ch);
  */
 static char                    /* if no counterpart, return ch */
-othercase(ch)
-int ch;
+othercase(
+    int                ch)
 {
        assert(isalpha(ch));
        if (isupper(ch))
@@ -831,23 +870,23 @@ int ch;
 
 /*
  - bothcases - emit a dualcase version of a two-case character
- == static void bothcases(register struct parse *p, int ch);
+ == static void bothcases(struct parse *p, int ch);
  *
  * Boy, is this implementation ever a kludge...
  */
 static void
-bothcases(p, ch)
-register struct parse *p;
-int ch;
+bothcases(
+    struct parse *     p,
+    int                        ch)
 {
-       register char *oldnext = p->next;
-       register char *oldend = p->end;
-       char bracket[3];
+       char *oldnext = p->next;
+       char *oldend = p->end;
+       static char bracket[3];
 
        assert(othercase(ch) != ch);    /* p_bracket() would recurse */
        p->next = bracket;
        p->end = bracket+2;
-       bracket[0] = ch;
+       bracket[0] = (char)ch;
        bracket[1] = ']';
        bracket[2] = '\0';
        p_bracket(p);
@@ -858,37 +897,37 @@ int ch;
 
 /*
  - ordinary - emit an ordinary character
- == static void ordinary(register struct parse *p, register int ch);
+ == static void ordinary(struct parse *p, register int ch);
  */
 static void
-ordinary(p, ch)
-register struct parse *p;
-register int ch;
+ordinary(
+    struct parse *     p,
+    int                        ch)
 {
-       register cat_t *cap = p->g->categories;
+       cat_t *cap = p->g->categories;
 
        if ((p->g->cflags&REG_ICASE) && isalpha(ch) && othercase(ch) != ch)
                bothcases(p, ch);
        else {
                EMIT(OCHAR, (unsigned char)ch);
                if (cap[ch] == 0)
-                       cap[ch] = p->g->ncategories++;
+                       cap[ch] = (cat_t)(p->g->ncategories++);
        }
 }
 
 /*
  - nonnewline - emit REG_NEWLINE version of OANY
- == static void nonnewline(register struct parse *p);
+ == static void nonnewline(struct parse *p);
  *
  * Boy, is this implementation ever a kludge...
  */
 static void
-nonnewline(p)
-register struct parse *p;
+nonnewline(
+    struct parse *     p)
 {
-       register char *oldnext = p->next;
-       register char *oldend = p->end;
-       char bracket[4];
+       char *oldnext = p->next;
+       char *oldend = p->end;
+       static char bracket[4];
 
        p->next = bracket;
        p->end = bracket+3;
@@ -904,21 +943,21 @@ register struct parse *p;
 
 /*
  - repeat - generate code for a bounded repetition, recursively if needed
- == static void repeat(register struct parse *p, sopno start, int from, int to);
+ == static void repeat(struct parse *p, sopno start, int from, int to);
  */
 static void
-repeat(p, start, from, to)
-register struct parse *p;
-sopno start;                   /* operand from here to end of strip */
-int from;                      /* repeated from this number */
-int to;                                /* to this number of times (maybe INFINITY) */
+repeat(
+    struct parse *     p,
+    sopno              start,  /* operand from here to end of strip */
+    int                        from,   /* repeated from this number */
+    int                        to)     /* to this number of times (maybe REINFINITY) */
 {
-       register sopno finish = HERE();
+       sopno finish = HERE();
 #      define  N       2
 #      define  INF     3
 #      define  REP(f, t)       ((f)*8 + (t))
-#      define  MAP(n)  (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
-       register sopno copy;
+#      define  MAP(n)  (((n) <= 1) ? (n) : ((n) == REINFINITY) ? INF : N)
+       sopno copy;
 
        if (p->error != 0)      /* head off possible runaway recursion */
                return;
@@ -976,12 +1015,12 @@ int to;                          /* to this number of times (maybe INFINITY) */
 
 /*
  - seterr - set an error condition
- == static int seterr(register struct parse *p, int e);
+ == static int seterr(struct parse *p, int e);
  */
 static int                     /* useless but makes type checking happy */
-seterr(p, e)
-register struct parse *p;
-int e;
+seterr(
+    struct parse *     p,
+    int                        e)
 {
        if (p->error == 0)      /* keep earliest error condition */
                p->error = e;
@@ -992,18 +1031,18 @@ int e;
 
 /*
  - allocset - allocate a set of characters for []
- == static cset *allocset(register struct parse *p);
+ == static cset *allocset(struct parse *p);
  */
 static cset *
-allocset(p)
-register struct parse *p;
+allocset(
+    struct parse *     p)
 {
-       register int no = p->g->ncsets++;
-       register size_t nc;
-       register size_t nbytes;
-       register cset *cs;
-       register size_t css = (size_t)p->g->csetsize;
-       register int i;
+       int no = p->g->ncsets++;
+       int nc;
+       size_t nbytes;
+       cset *cs;
+       size_t css = (size_t)p->g->csetsize;
+       int i;
 
        if (no >= p->ncsalloc) {        /* need another column of space */
                p->ncsalloc += CHAR_BIT;
@@ -1011,18 +1050,19 @@ register struct parse *p;
                assert(nc % CHAR_BIT == 0);
                nbytes = nc / CHAR_BIT * css;
                if (p->g->sets == NULL)
-                       p->g->sets = (cset *)malloc(nc * sizeof(cset));
+                       p->g->sets = (cset *)malloc(nc * SIZEOF(cset));
                else
                        p->g->sets = (cset *)realloc((char *)p->g->sets,
-                                                       nc * sizeof(cset));
+                                       (size_t)nc * SIZEOF(cset));
                if (p->g->setbits == NULL)
                        p->g->setbits = (uch *)malloc(nbytes);
                else {
                        p->g->setbits = (uch *)realloc((char *)p->g->setbits,
                                                                nbytes);
                        /* xxx this isn't right if setbits is now NULL */
-                       for (i = 0; i < no; i++)
-                               p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
+                       if (p->g->sets && p->g->setbits)
+                               for (i = 0; i < no; i++)
+                                       p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
                }
                if (p->g->sets != NULL && p->g->setbits != NULL)
                        (void) memset((char *)p->g->setbits + (nbytes - css),
@@ -1037,7 +1077,7 @@ register struct parse *p;
        assert(p->g->sets != NULL);     /* xxx */
        cs = &p->g->sets[no];
        cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
-       cs->mask = 1 << ((no) % CHAR_BIT);
+       cs->mask = (uch)(1 << ((no) % CHAR_BIT));
        cs->hash = 0;
        cs->smultis = 0;
        cs->multis = NULL;
@@ -1047,16 +1087,16 @@ register struct parse *p;
 
 /*
  - freeset - free a now-unused set
- == static void freeset(register struct parse *p, register cset *cs);
+ == static void freeset(struct parse *p, register cset *cs);
  */
 static void
-freeset(p, cs)
-register struct parse *p;
-register cset *cs;
+freeset(
+    struct parse *     p,
+    cset *             cs)
 {
-       register int i;
-       register cset *top = &p->g->sets[p->g->ncsets];
-       register size_t css = (size_t)p->g->csetsize;
+       int i;
+       cset *top = &p->g->sets[p->g->ncsets];
+       int css = p->g->csetsize;
 
        for (i = 0; i < css; i++)
                CHsub(cs, i);
@@ -1066,7 +1106,7 @@ register cset *cs;
 
 /*
  - freezeset - final processing on a set of characters
- == static int freezeset(register struct parse *p, register cset *cs);
+ == static int freezeset(struct parse *p, register cset *cs);
  *
  * The main task here is merging identical sets.  This is usually a waste
  * of time (although the hash code minimizes the overhead), but can win
@@ -1075,15 +1115,15 @@ register cset *cs;
  * the same value!
  */
 static int                     /* set number */
-freezeset(p, cs)
-register struct parse *p;
-register cset *cs;
+freezeset(
+    struct parse *     p,
+    cset *             cs)
 {
-       register uch h = cs->hash;
-       register int i;
-       register cset *top = &p->g->sets[p->g->ncsets];
-       register cset *cs2;
-       register size_t css = (size_t)p->g->csetsize;
+       uch h = cs->hash;
+       int i;
+       cset *top = &p->g->sets[p->g->ncsets];
+       cset *cs2;
+       int css = p->g->csetsize;
 
        /* look for an earlier one which is the same */
        for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
@@ -1106,15 +1146,15 @@ register cset *cs;
 
 /*
  - firstch - return first character in a set (which must have at least one)
- == static int firstch(register struct parse *p, register cset *cs);
+ == static int firstch(struct parse *p, register cset *cs);
  */
 static int                     /* character; there is no "none" value */
-firstch(p, cs)
-register struct parse *p;
-register cset *cs;
+firstch(
+    struct parse *     p,
+    cset *             cs)
 {
-       register int i;
-       register size_t css = (size_t)p->g->csetsize;
+       int i;
+       int css = p->g->csetsize;
 
        for (i = 0; i < css; i++)
                if (CHIN(cs, i))
@@ -1125,16 +1165,16 @@ register cset *cs;
 
 /*
  - nch - number of characters in a set
- == static int nch(register struct parse *p, register cset *cs);
+ == static int nch(struct parse *p, register cset *cs);
  */
 static int
-nch(p, cs)
-register struct parse *p;
-register cset *cs;
+nch(
+    struct parse *     p,
+    cset *             cs)
 {
-       register int i;
-       register size_t css = (size_t)p->g->csetsize;
-       register int n = 0;
+       int i;
+       int css = p->g->csetsize;
+       int n = 0;
 
        for (i = 0; i < css; i++)
                if (CHIN(cs, i))
@@ -1144,134 +1184,79 @@ register cset *cs;
 
 /*
  - mcadd - add a collating element to a cset
- == static void mcadd(register struct parse *p, register cset *cs, \
- ==    register char *cp);
+ == static void mcadd(struct parse *p, register cset *cs, \
+ ==    char *cp);
  */
 static void
-mcadd(p, cs, cp)
-register struct parse *p;
-register cset *cs;
-register char *cp;
+mcadd(
+    struct parse *     p,
+    cset *             cs,
+    char *             cp)
 {
-       register size_t oldend = cs->smultis;
+       size_t oldend = cs->smultis;
 
        cs->smultis += strlen(cp) + 1;
        if (cs->multis == NULL)
                cs->multis = malloc(cs->smultis);
        else
-               cs->multis = realloc(cs->multis, cs->smultis);
+               cs->multis = realloc(cs->multis, (size_t)cs->smultis);
        if (cs->multis == NULL) {
                SETERROR(REG_ESPACE);
                return;
        }
 
-       (void) strcpy(cs->multis + oldend - 1, cp);
+       (void) strncpy(cs->multis + oldend - 1, cp, cs->smultis - (oldend - 1));
        cs->multis[cs->smultis - 1] = '\0';
 }
 
-#if 0
-/*
- * - mcsub - subtract a collating element from a cset
- * == static void mcsub(register cset *cs, register char *cp);
- */
-static void
-mcsub(cs, cp)
-register cset *cs;
-register char *cp;
-{
-       register char *fp = mcfind(cs, cp);
-       register size_t len = strlen(fp);
-
-       assert(fp != NULL);
-       (void) memmove(fp, fp + len + 1,
-                               cs->smultis - (fp + len + 1 - cs->multis));
-       cs->smultis -= len;
-
-       if (cs->smultis == 0) {
-               free(cs->multis);
-               cs->multis = NULL;
-               return;
-       }
-
-       cs->multis = realloc(cs->multis, cs->smultis);
-       assert(cs->multis != NULL);
-}
-
-/*
- * - mcin - is a collating element in a cset?
- * == static int mcin(register cset *cs, register char *cp);
- */
-static int
-mcin(cs, cp)
-register cset *cs;
-register char *cp;
-{
-       return(mcfind(cs, cp) != NULL);
-}
-
-/*
- * - mcfind - find a collating element in a cset
- * == static char *mcfind(register cset *cs, register char *cp);
- */
-static char *
-mcfind(cs, cp)
-register cset *cs;
-register char *cp;
-{
-       register char *p;
-
-       if (cs->multis == NULL)
-               return(NULL);
-       for (p = cs->multis; *p != '\0'; p += strlen(p) + 1)
-               if (strcmp(cp, p) == 0)
-                       return(p);
-       return(NULL);
-}
-#endif /* 0 */
 
 /*
  - mcinvert - invert the list of collating elements in a cset
- == static void mcinvert(register struct parse *p, register cset *cs);
+ == static void mcinvert(struct parse *p, register cset *cs);
  *
  * This would have to know the set of possibilities.  Implementation
  * is deferred.
  */
 static void
-mcinvert(p, cs)
-register struct parse *p;
-register cset *cs;
+mcinvert(
+   struct parse *      p,
+   cset *              cs)
 {
+       (void)p;        /* Quiet unused parameter warning */
+       (void)cs;       /* Quiet unused parameter warning */
        assert(cs->multis == NULL);     /* xxx */
 }
 
 /*
  - mccase - add case counterparts of the list of collating elements in a cset
- == static void mccase(register struct parse *p, register cset *cs);
+ == static void mccase(struct parse *p, register cset *cs);
  *
  * This would have to know the set of possibilities.  Implementation
  * is deferred.
  */
 static void
-mccase(p, cs)
-register struct parse *p;
-register cset *cs;
+mccase(
+    struct parse *     p,
+    cset *             cs)
 {
+       (void)p;        /* Quiet unused parameter warning */
+       (void)cs;       /* Quiet unused parameter warning */
        assert(cs->multis == NULL);     /* xxx */
 }
 
 /*
  - isinsets - is this character in any sets?
- == static int isinsets(register struct re_guts *g, int c);
+ == static int isinsets(struct re_guts *g, int c);
  */
 static int                     /* predicate */
-isinsets(g, c)
-register struct re_guts *g;
-int c;
+isinsets(
+    struct re_guts *   g,
+    int                        c)
 {
-       register uch *col;
-       register int i;
-       register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
-       register unsigned uc = (unsigned char)c;
+       uch *col;
+       int i;
+       int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+       unsigned uc = (unsigned char)c;
 
        for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
                if (col[uc] != 0)
@@ -1281,19 +1266,19 @@ int c;
 
 /*
  - samesets - are these two characters in exactly the same sets?
- == static int samesets(register struct re_guts *g, int c1, int c2);
+ == static int samesets(struct re_guts *g, int c1, int c2);
  */
 static int                     /* predicate */
-samesets(g, c1, c2)
-register struct re_guts *g;
-int c1;
-int c2;
+samesets(
+    struct re_guts *   g,
+    int                        c1,
+    int                        c2)
 {
-       register uch *col;
-       register int i;
-       register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
-       register unsigned uc1 = (unsigned char)c1;
-       register unsigned uc2 = (unsigned char)c2;
+       uch *col;
+       int i;
+       int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+       unsigned uc1 = (unsigned char)c1;
+       unsigned uc2 = (unsigned char)c2;
 
        for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
                if (col[uc1] != col[uc2])
@@ -1303,17 +1288,17 @@ int c2;
 
 /*
  - categorize - sort out character categories
- == static void categorize(struct parse *p, register struct re_guts *g);
+ == static void categorize(struct parse *p, struct re_guts *g);
  */
 static void
-categorize(p, g)
-struct parse *p;
-register struct re_guts *g;
+categorize(
+    struct parse *     p,
+    struct re_guts *   g)
 {
-       register cat_t *cats = g->categories;
-       register int c;
-       register int c2;
-       register cat_t cat;
+       cat_t *cats = g->categories;
+       int c;
+       int c2;
+       cat_t cat;
 
        /* avoid making error situations worse */
        if (p->error != 0)
@@ -1321,7 +1306,7 @@ register struct re_guts *g;
 
        for (c = CHAR_MIN; c <= CHAR_MAX; c++)
                if (cats[c] == 0 && isinsets(g, c)) {
-                       cat = g->ncategories++;
+                       cat = (cat_t)g->ncategories++;
                        cats[c] = cat;
                        for (c2 = c+1; c2 <= CHAR_MAX; c2++)
                                if (cats[c2] == 0 && samesets(g, c, c2))
@@ -1331,48 +1316,48 @@ register struct re_guts *g;
 
 /*
  - dupl - emit a duplicate of a bunch of sops
- == static sopno dupl(register struct parse *p, sopno start, sopno finish);
+ == static sopno dupl(struct parse *p, sopno start, sopno finish);
  */
 static sopno                   /* start of duplicate */
-dupl(p, start, finish)
-register struct parse *p;
-sopno start;                   /* from here */
-sopno finish;                  /* to this less one */
+dupl(
+   struct parse *      p,
+   sopno               start,  /* from here */
+   sopno               finish) /* to this less one */
 {
-       register sopno ret = HERE();
-       register sopno len = finish - start;
+       sopno ret = HERE();
+       size_t len = (size_t)(finish - start);
 
        assert(finish >= start);
        if (len == 0)
                return(ret);
        enlarge(p, p->ssize + len);     /* this many unexpected additions */
-       assert(p->ssize >= p->slen + len);
+       assert(p->ssize >= (p->slen + len));
        (void) memcpy((char *)(p->strip + p->slen),
-               (char *)(p->strip + start), (size_t)len*sizeof(sop));
+               (char *)(p->strip + start), ((size_t)len * SIZEOF(sop)));
        p->slen += len;
        return(ret);
 }
 
 /*
  - doemit - emit a strip operator
- == static void doemit(register struct parse *p, sop op, size_t opnd);
+ == static void doemit(struct parse *p, sop op, size_t opnd);
  *
  * It might seem better to implement this as a macro with a function as
  * hard-case backup, but it's just too big and messy unless there are
  * some changes to the data structures.  Maybe later.
  */
 static void
-doemit(p, op, opnd)
-register struct parse *p;
-sop op;
-size_t opnd;
+doemit(
+    struct parse *     p,
+    sop                        op,
+    size_t             opnd)
 {
        /* avoid making error situations worse */
        if (p->error != 0)
                return;
 
        /* deal with oversize operands ("can't happen", more or less) */
-       assert(opnd < 1<<OPSHIFT);
+       assert(opnd < (1 << OPSHIFT));
 
        /* deal with undersized strip */
        if (p->slen >= p->ssize)
@@ -1385,18 +1370,18 @@ size_t opnd;
 
 /*
  - doinsert - insert a sop into the strip
- == static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos);
+ == static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos);
  */
 static void
-doinsert(p, op, opnd, pos)
-register struct parse *p;
-sop op;
-size_t opnd;
-sopno pos;
+doinsert(
+    struct parse *     p,
+    sop                        op,
+    size_t             opnd,
+    sopno              pos)
 {
-       register sopno sn;
-       register sop s;
-       register int i;
+       sopno sn;
+       sop s;
+       int i;
 
        /* avoid making error situations worse */
        if (p->error != 0)
@@ -1419,19 +1404,19 @@ sopno pos;
        }
 
        memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
-                                               (HERE()-pos-1)*sizeof(sop));
+               (HERE() - (size_t)pos - 1) * SIZEOF(sop));
        p->strip[pos] = s;
 }
 
 /*
  - dofwd - complete a forward reference
- == static void dofwd(register struct parse *p, sopno pos, sop value);
+ == static void dofwd(struct parse *p, sopno pos, sop value);
  */
 static void
-dofwd(p, pos, value)
-register struct parse *p;
-register sopno pos;
-sop value;
+dofwd(
+    struct parse *     p,
+    sopno              pos,
+    sop                        value)
 {
        /* avoid making error situations worse */
        if (p->error != 0)
@@ -1439,42 +1424,43 @@ sop value;
 
        assert(value < 1<<OPSHIFT);
        p->strip[pos] = OP(p->strip[pos]) | value;
-}
-
+} 
 /*
  - enlarge - enlarge the strip
- == static void enlarge(register struct parse *p, sopno size);
+ == static void enlarge(struct parse *p, sopno size);
  */
 static void
-enlarge(p, size)
-register struct parse *p;
-register sopno size;
+enlarge(
+    struct parse *     p,
+    sopno              size)
 {
-       register sop *sp;
+       sop *sp;
 
-       if (p->ssize >= size)
+       assert(size <= (sopno)SSIZE_MAX);
+       if (p->ssize >= (size_t)size)
                return;
 
-       sp = (sop *)realloc(p->strip, size*sizeof(sop));
+       sp = (sop *)realloc(p->strip, (size_t)size * SIZEOF(sop));
        if (sp == NULL) {
                SETERROR(REG_ESPACE);
                return;
        }
        p->strip = sp;
-       p->ssize = size;
+       p->ssize = (size_t)size;
 }
 
 /*
  - stripsnug - compact the strip
- == static void stripsnug(register struct parse *p, register struct re_guts *g);
+ == static void stripsnug(struct parse *p, register struct re_guts *g);
  */
 static void
-stripsnug(p, g)
-register struct parse *p;
-register struct re_guts *g;
+stripsnug(
+    /*@keep@*/ struct parse *  p,
+    /*@keep@*/ struct re_guts *g)
 {
        g->nstates = p->slen;
-       g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
+       g->strip = (sop *)realloc((char *)p->strip,
+                               (size_t)p->slen * SIZEOF(sop));
        if (g->strip == NULL) {
                SETERROR(REG_ESPACE);
                g->strip = p->strip;
@@ -1483,7 +1469,7 @@ register struct re_guts *g;
 
 /*
  - findmust - fill in must and mlen with longest mandatory literal string
- == static void findmust(register struct parse *p, register struct re_guts *g);
+ == static void findmust(struct parse *p, register struct re_guts *g);
  *
  * This algorithm could do fancy things like analyzing the operands of |
  * for common subsequences.  Someday.  This code is simple and finds most
@@ -1492,17 +1478,17 @@ register struct re_guts *g;
  * Note that must and mlen got initialized during setup.
  */
 static void
-findmust(p, g)
-struct parse *p;
-register struct re_guts *g;
+findmust(
+    struct parse *     p,
+    struct re_guts *   g)
 {
-       register sop *scan;
+       sop *scan;
        sop *start;
-       register sop *newstart = NULL;
-       register sopno newlen;
-       register sop s;
-       register char *cp;
-       register sopno i;
+       sop *newstart = NULL;
+       sopno newlen;
+       sop s;
+       char *cp;
+       sopno i;
 
        /* avoid making error situations worse */
        if (p->error != 0)
@@ -1559,8 +1545,9 @@ register struct re_guts *g;
        cp = g->must;
        scan = start;
        for (i = g->mlen; i > 0; i--) {
-               while (OP(s = *scan++) != OCHAR)
-                       continue;
+               s = *scan++;
+               while (OP(s) != OCHAR)
+                       s = *scan++;
                assert(cp < g->must + g->mlen);
                *cp++ = (char)OPND(s);
        }
@@ -1570,17 +1557,17 @@ register struct re_guts *g;
 
 /*
  - pluscount - count + nesting
- == static sopno pluscount(register struct parse *p, register struct re_guts *g);
+ == static sopno pluscount(struct parse *p, register struct re_guts *g);
  */
 static sopno                   /* nesting depth */
-pluscount(p, g)
-struct parse *p;
-register struct re_guts *g;
+pluscount(
+    struct parse *     p,
+    struct re_guts *   g)
 {
-       register sop *scan;
-       register sop s;
-       register sopno plusnest = 0;
-       register sopno maxnest = 0;
+       sop *scan;
+       sop s;
+       sopno plusnest = 0;
+       sopno maxnest = 0;
 
        if (p->error != 0)
                return(0);      /* there may not be an OEND */
index 35cc1eba131a24c827725b5599d23e32eebf05be..1eab5cad84195b24312ed82a150ef1e92d65ad4d 100644 (file)
@@ -1,11 +1,5 @@
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
+#include "amanda.h"
 #include <regex.h>
-
 #include "utils.h"
 #include "regerror.ih"
 
@@ -61,11 +55,11 @@ static struct rerr {
  */
 /* ARGSUSED */
 size_t
-regerror(errcode, preg, errbuf, errbuf_size)
-int errcode;
-const regex_t *preg;
-char *errbuf;
-size_t errbuf_size;
+regerror(
+    int                   errcode,
+    const regex_t *preg,
+    char *        errbuf,
+    size_t        errbuf_size)
 {
        register struct rerr *r;
        register size_t len;
@@ -74,7 +68,7 @@ size_t errbuf_size;
        char convbuf[50];
 
        if (errcode == REG_ATOI)
-               s = regatoi(preg, convbuf, sizeof(convbuf));
+               s = regatoi(preg, convbuf, SIZEOF(convbuf));
        else {
                for (r = rerrs; r->code >= 0; r++)
                        if (r->code == target)
@@ -82,13 +76,13 @@ size_t errbuf_size;
 
                if (errcode&REG_ITOA) {
                        if (r->code >= 0) {
-                               strncpy(convbuf, r->name, sizeof(convbuf)-1);
-                               convbuf[sizeof(convbuf)-1] = '\0';
+                               strncpy(convbuf, r->name, SIZEOF(convbuf)-1);
+                               convbuf[SIZEOF(convbuf)-1] = '\0';
                        } else {
-                               snprintf(convbuf, sizeof(convbuf),
-                                           "REG_0x%x", target);
+                               snprintf(convbuf, SIZEOF(convbuf),
+                                           "REG_0x%x", (unsigned)target);
                        }
-                       assert(strlen(convbuf) < sizeof(convbuf));
+                       assert(strlen(convbuf) < SIZEOF(convbuf));
                        s = convbuf;
                } else
                        s = r->explain;
@@ -96,12 +90,8 @@ size_t errbuf_size;
 
        len = strlen(s) + 1;
        if (errbuf_size > 0) {
-               if (errbuf_size > len)
-                       (void) strcpy(errbuf, s);
-               else {
-                       (void) strncpy(errbuf, s, errbuf_size-1);
-                       errbuf[errbuf_size-1] = '\0';
-               }
+               (void) strncpy(errbuf, s, errbuf_size-1);
+               errbuf[errbuf_size-1] = '\0';
        }
 
        return(len);
@@ -109,19 +99,22 @@ size_t errbuf_size;
 
 /*
  - regatoi - internal routine to implement REG_ATOI
- == static char *regatoi(const regex_t *preg, char *localbuf, int buflen);
+ == static char *regatoi(const regex_t *preg, char *localbuf, size_t buflen);
  */
 static char *
-regatoi(preg, localbuf, buflen)
-const regex_t *preg;
-char *localbuf;
-int buflen;
+regatoi(
+    const regex_t *    preg,
+    char *             localbuf,
+    size_t             buflen)
 {
        register struct rerr *r;
 
-       for (r = rerrs; r->code >= 0; r++)
+       for (r = rerrs; r->code >= 0; r++) {
+               /*@ignore@*/
                if (strcmp(r->name, preg->re_endp) == 0)
                        break;
+               /*@end@*/
+       }
        if (r->code < 0)
                return("0");
 
index 56bb1f953341c41e9ad536e290c54f17b5c71463..52aa9df42a7a98eab2537e918e5bfdb7036bde9a 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef REGEX2_H
+#define REGEX2_H
+
 /*
  * First, the stuff that ends up in the outside-world include file
  = typedef off_t regoff_t;
@@ -37,7 +40,7 @@
  * immediately *preceding* "execution" of that operator.
  */
 typedef unsigned long sop;     /* strip operator */
-typedef long sopno;
+typedef unsigned long sopno;
 #define        OPRMASK 0xf8000000
 #define        OPDMASK 0x07ffffff
 #define        OPSHIFT ((unsigned)27)
@@ -99,8 +102,16 @@ typedef struct {
        char *multis;           /* -> char[smulti]  ab\0cd\0ef\0\0 */
 } cset;
 /* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
-#define        CHadd(cs, c)    ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
-#define        CHsub(cs, c)    ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
+#define        CHadd(cs, c)    do {                                            \
+    (cs)->ptr[(uch)(c)] = (uch)((cs)->ptr[(uch)(c)] | (cs)->mask);     \
+    (cs)->hash = (uch)((cs)->hash + (c));                              \
+} while (0)
+
+#define        CHsub(cs, c)    do {                                            \
+    (cs)->ptr[(uch)(c)] = (uch)((cs)->ptr[(uch)(c)] & ~(cs)->mask);    \
+    (cs)->hash = (uch)((cs)->hash - (c));                              \
+} while (0)
+
 #define        CHIN(cs, c)     ((cs)->ptr[(uch)(c)] & (cs)->mask)
 #define        MCadd(p, cs, cp)        mcadd(p, cs, cp)        /* regcomp() internal fns */
 #define        MCsub(p, cs, cp)        mcsub(p, cs, cp)
@@ -133,7 +144,7 @@ struct re_guts {
        int ncategories;        /* how many character categories */
        cat_t *categories;      /* ->catspace[-CHAR_MIN] */
        char *must;             /* match must contain this string */
-       int mlen;               /* length of must */
+       sopno mlen;             /* length of must */
        size_t nsub;            /* copy of re_nsub */
        int backrefs;           /* does it use back references? */
        sopno nplus;            /* how deep does it nest +s? */
@@ -144,3 +155,5 @@ struct re_guts {
 /* misc utilities */
 #define        OUT     (CHAR_MAX+1)    /* a non-character value */
 #define        ISWORD(c)       (isalnum(c) || (c) == '_')
+
+#endif /* !REGEX2_H */
index 0e86b37312c6c779ae8bdb6bbe2ed839096b984f..4213cdd312ee2b886e0f0f0713c97186aad8bd81 100644 (file)
@@ -5,43 +5,35 @@
  * macros that code uses.  This lets the same code operate on two different
  * representations for state sets.
  */
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <ctype.h>
+#include "amanda.h"
 #include <regex.h>
-
 #include "utils.h"
 #include "regex2.h"
 
-#ifndef NDEBUG
-static int nope = 0;           /* for use in asserts; shuts lint up */
-#endif
+#undef ISSET
 
 /* macros for manipulating states, small version */
-#define        states  long
+#define        states  unsigned long
 #define        states1 states          /* for later use in regexec() decision */
-#define        CLEAR(v)        ((v) = 0)
+#define        CLEAR(v)        (((v) = 0), (void)(v))
 #define        SET0(v, n)      ((v) &= ~(MAKE_UNSIGNED_LONG(1) << (n)))
 #define        SET1(v, n)      ((v) |= (MAKE_UNSIGNED_LONG(1)) << (n))
 #define        ISSET(v, n)     ((v) & ((MAKE_UNSIGNED_LONG(1)) << (n)))
-#define        ASSIGN(d, s)    ((d) = (s))
+#define        ASSIGN(d, s)    ((d) = (s), (void)(d))
 #define        EQ(a, b)        ((a) == (b))
 #define        STATEVARS       int dummy       /* dummy version */
 #define        STATESETUP(m, n)        /* nothing */
 #define        STATETEARDOWN(m)        /* nothing */
 #define        SETUP(v)        ((v) = 0)
-#define        onestate        long
-#define        INIT(o, n)      ((o) = (unsigned long)1 << (n))
+#define        onestate        sopno
+#define        INIT(o, n)      ((o) = (sopno)1 << (n))
 #define        INC(o)  ((o) <<= 1)
 #define        ISSTATEIN(v, o) ((v) & (o))
 /* some abbreviations; note that some of these know variable names! */
 /* do "if I'm here, I can also be there" etc without branches */
 #define        FWD(dst, src, n)        ((dst) |= ((unsigned long)(src)&(here)) << (n))
 #define        BACK(dst, src, n)       ((dst) |= ((unsigned long)(src)&(here)) >> (n))
-#define        ISSETBACK(v, n) ((v) & ((unsigned long)here >> (n)))
+#define        ISSETBACK(v, n) ((v) & ((long)here >> (n)))
 /* function names */
 #define SNAMES                 /* engine.c looks after details */
 
@@ -70,16 +62,20 @@ static int nope = 0;                /* for use in asserts; shuts lint up */
 
 /* macros for manipulating states, large version */
 #define        states  char *
-#define        CLEAR(v)        memset(v, 0, m->g->nstates)
+#define        CLEAR(v)        memset((v), 0, (size_t)m->g->nstates)
 #define        SET0(v, n)      ((v)[n] = 0)
 #define        SET1(v, n)      ((v)[n] = 1)
 #define        ISSET(v, n)     ((v)[n])
-#define        ASSIGN(d, s)    memcpy(d, s, m->g->nstates)
-#define        EQ(a, b)        (memcmp(a, b, m->g->nstates) == 0)
+#define        ASSIGN(d, s)    memcpy((d), (s), (size_t)m->g->nstates)
+#define        EQ(a, b)        (memcmp((a), (b), (size_t)m->g->nstates) == 0)
 #define        STATEVARS       int vn; char *space
-#define        STATESETUP(m, nv)       { (m)->space = malloc((nv)*(m)->g->nstates); \
-                               if ((m)->space == NULL) return(REG_ESPACE); \
-                               (m)->vn = 0; }
+#define        STATESETUP(m, nv) do {                                          \
+           (m)->space = malloc((size_t)(nv)*(size_t)(m)->g->nstates);  \
+           if ((m)->space == NULL)                                     \
+               return(REG_ESPACE);                                     \
+           (m)->vn = 0;                                                \
+} while (0);
+
 #define        STATETEARDOWN(m)        { free((m)->space); }
 #define        SETUP(v)        ((v) = &m->space[m->vn++ * m->g->nstates])
 #define        onestate        int
@@ -98,8 +94,7 @@ static int nope = 0;          /* for use in asserts; shuts lint up */
 
 /*
  - regexec - interface for matching
- = extern int regexec(const regex_t *, const char *, size_t, \
- =                                     regmatch_t [], int);
+ = int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
  = #define     REG_NOTBOL      00001
  = #define     REG_NOTEOL      00002
  = #define     REG_STARTEND    00004
@@ -112,13 +107,14 @@ static int nope = 0;              /* for use in asserts; shuts lint up */
  * have been prototyped.
  */
 int                            /* 0 success, REG_NOMATCH failure */
-regexec(preg, string, nmatch, pmatch, eflags)
-const regex_t *preg;
-const char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
+regexec(
+    regex_t *preg,
+    const char *string,
+    size_t nmatch,
+    regmatch_t pmatch[],
+    int eflags)
 {
+       /*@ignore@*/
        register struct re_guts *g = preg->re_g;
 #ifdef REDEBUG
 #      define  GOODFLAGS(f)    (f)
@@ -128,13 +124,14 @@ int eflags;
 
        if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
                return(REG_BADPAT);
+       /*@end@*/
        assert(!(g->iflags&BAD));
        if (g->iflags&BAD)              /* backstop for no-debug case */
                return(REG_BADPAT);
        eflags = GOODFLAGS(eflags);
 
-       if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags&REG_LARGE))
+       if ((g->nstates <= ((sopno)(CHAR_BIT * SIZEOF(states1))) &&
+           !(eflags & REG_LARGE)))
                return(smatcher(g, string, nmatch, pmatch, eflags));
-       else
-               return(lmatcher(g, string, nmatch, pmatch, eflags));
+       return(lmatcher(g, string, nmatch, pmatch, eflags));
 }
index 9a6acf1733ab0fed70814c2528410b15d804e3ac..be3983125ab0b24183d0476752ba7ec7dba14dd1 100644 (file)
@@ -1,8 +1,5 @@
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "amanda.h"
 #include <regex.h>
-
 #include "utils.h"
 #include "regex2.h"
 
  = extern void regfree(regex_t *);
  */
 void
-regfree(preg)
-regex_t *preg;
+regfree(
+    regex_t *preg)
 {
        register struct re_guts *g;
 
+       /*@ignore@*/
        if (preg->re_magic != MAGIC1)   /* oops */
                return;                 /* nice to complain, but hard */
 
@@ -23,6 +21,7 @@ regex_t *preg;
        if (g == NULL || g->magic != MAGIC2)    /* oops again */
                return;
        preg->re_magic = 0;             /* mark it invalid */
+       /*@end@*/
        g->magic = 0;                   /* mark it invalid */
 
        if (g->strip != NULL)
index 9e3e11acdf1e534919c61586f4c6652385714451..415f8abfbc3c6e5919d55daed303652358ecd813 100644 (file)
@@ -1,3 +1,4 @@
+#include <amanda.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -6,11 +7,11 @@
  = int split(char *string, char *fields[], int nfields, char *sep);
  */
 int                            /* number of fields, including overflow */
-split(string, fields, nfields, sep)
-char *string;
-char *fields[];                        /* list is not NULL-terminated */
-int nfields;                   /* number of entries available in fields[] */
-char *sep;                     /* "" white, "c" single char, "ab" [ab]+ */
+split(
+    char *     string,
+    char *     fields[],       /* list is not NULL-terminated */
+    int                nfields,        /* number of entries available in fields[] */
+    char *     sep)            /* "" white, "c" single char, "ab" [ab]+ */
 {
        register char *p = string;
        register char c;                        /* latest character */
@@ -148,9 +149,9 @@ char *sep;                  /* "" white, "c" single char, "ab" [ab]+ */
  * pgm str sep n       splits str by sep n times
  */
 int
-main(argc, argv)
-int argc;
-char *argv[];
+main(
+    int                argc,
+    char *     argv[])
 {
        char buf[512];
        register int n;
@@ -159,19 +160,19 @@ char *argv[];
 
        if (argc > 4)
                for (n = atoi(argv[3]); n > 0; n--) {
-                       strncpy(buf, argv[1], sizeof(buf)-1);
-                       buf[sizeof(buf)-1] = '\0';
+                       strncpy(buf, argv[1], SIZEOF(buf)-1);
+                       buf[SIZEOF(buf)-1] = '\0';
                }
        else if (argc > 3)
                for (n = atoi(argv[3]); n > 0; n--) {
-                       strncpy(buf, argv[1], sizeof(buf)-1);
-                       buf[sizeof(buf)-1] = '\0';
+                       strncpy(buf, argv[1], SIZEOF(buf)-1);
+                       buf[SIZEOF(buf)-1] = '\0';
                        (void) split(buf, fields, MNF, argv[2]);
                }
        else if (argc > 2)
                dosplit(argv[1], argv[2]);
        else if (argc > 1)
-               while (fgets(buf, sizeof(buf), stdin) != NULL) {
+               while (fgets(buf, (int)sizeof(buf), stdin) != NULL) {
                        buf[strlen(buf)-1] = '\0';      /* stomp newline */
                        dosplit(buf, argv[1]);
                }
@@ -181,9 +182,10 @@ char *argv[];
        exit(0);
 }
 
-dosplit(string, seps)
-char *string;
-char *seps;
+int
+dosplit(
+    char *     string,
+    char *     seps)
 {
 #      define  NF      5
        char *fields[NF];
@@ -193,10 +195,11 @@ char *seps;
        print(nf, NF, fields);
 }
 
-print(nf, nfp, fields)
-int nf;
-int nfp;
-char *fields[];
+int
+print(
+    int nf,
+    int nfp,
+    char *fields[])
 {
        register int fn;
        register int bound;
@@ -276,7 +279,8 @@ struct {
        NULL,           NULL,   0,      { NULL },
 };
 
-regress()
+int
+regress(void)
 {
        char buf[512];
        register int n;
@@ -287,8 +291,8 @@ regress()
        register char *f;
 
        for (n = 0; tests[n].str != NULL; n++) {
-               strncpy(buf, tests[n].str, sizeof(buf)-1);
-               buf[sizeof(buf)-1] = '\0';
+               strncpy(buf, tests[n].str, SIZEOF(buf)-1);
+               buf[SIZEOF(buf)-1] = '\0';
                fields[RNF] = NULL;
                nf = split(buf, fields, RNF, tests[n].seps);
                printit = 0;
index 1a997ac8fc166de4ce162938b67c10464982a489..539d64544781b28b5880db7aa4b740d32322d148 100644 (file)
@@ -1,10 +1,13 @@
+#ifndef REGEX_UTILS_H
+#define REGEX_UTILS_H
+
 /* utility definitions */
 #ifdef _POSIX2_RE_DUP_MAX
 #define        DUPMAX  _POSIX2_RE_DUP_MAX
 #else
 #define        DUPMAX  255
 #endif
-#define        INFINITY        (DUPMAX + 1)
+#define        REINFINITY      (DUPMAX + 1)
 #define        NC              (CHAR_MAX - CHAR_MIN + 1)
 typedef unsigned char uch;
 
@@ -15,8 +18,9 @@ typedef unsigned char uch;
 #endif
 #endif
 #include <assert.h>
-
 /* for old systems with bcopy() but no memmove() */
 #ifdef USEBCOPY
 #define        memmove(d, s, c)        bcopy(s, d, c)
 #endif
+
+#endif /* !REGEX_UTILS_H */
index ac4ee903decb687a7ee16a60874c2011a8c3c2ad..3ca04e7b26467f5ee14b1034cdac49e38e4cec42 100644 (file)
@@ -3,7 +3,11 @@
 INCLUDES =     -I$(top_builddir)/common-src \
                -I$(top_srcdir)/common-src   \
                -I$(top_srcdir)/tape-src     \
-               -I$(top_srcdir)/server-src
+               -I$(top_srcdir)/server-src   \
+               -I$(top_srcdir)/amandad-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
 
 lib_LTLIBRARIES =      librestore.la
 LIB_EXTENSION = la
@@ -19,9 +23,11 @@ libexec_PROGRAMS =   amidxtaped
 # routines, and second to pick up any references in the other libraries.
 ###
 
-LDADD = librestore.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+LDADD = librestore.$(LIB_EXTENSION)              \
+      ../common-src/libamanda.$(LIB_EXTENSION) \
+      $(READLINE_LIBS)
 
+amidxtaped_LDADD = $(LDADD) ../amandad-src/libamandad.$(LIB_EXTENSION)
 amidxtaped_SOURCES =   amidxtaped.c
 
 amfetchdump_SOURCES =  amfetchdump.c
@@ -51,3 +57,22 @@ install-exec-hook:
                echo chgrp $(SETUID_GROUP) $$pa; \
                chgrp $(SETUID_GROUP) $$pa; \
        done
+
+lint:
+       @ for p in $(libexec_PROGRAMS) $(sbin_PROGRAMS); do                     \
+               f="$$p.c $(librestore_la_SOURCES)";                             \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               (cd ../server-src; make listlibsrc);                            \
+               f="$$f "`cat ../server-src/listlibsrc.output`;                  \
+               (cd ../tape-src; make listlibsrc);                              \
+               f="$$f "`cat ../tape-src/listlibsrc.output`;                    \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+
index 8d04e90cf00fb65758a841f371f87dfdf0ddb6ac..6d4fb301b2a37a4e71b912d597bf93f9b8770fbd 100644 (file)
@@ -75,18 +75,20 @@ PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS)
 am_amfetchdump_OBJECTS = amfetchdump.$(OBJEXT)
 amfetchdump_OBJECTS = $(am_amfetchdump_OBJECTS)
 amfetchdump_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
 amfetchdump_DEPENDENCIES = librestore.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 am_amidxtaped_OBJECTS = amidxtaped.$(OBJEXT)
 amidxtaped_OBJECTS = $(am_amidxtaped_OBJECTS)
-amidxtaped_LDADD = $(LDADD)
-amidxtaped_DEPENDENCIES = librestore.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+am__DEPENDENCIES_2 = librestore.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
+amidxtaped_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION)
 amrestore_SOURCES = amrestore.c
 amrestore_OBJECTS = amrestore.$(OBJEXT)
 amrestore_LDADD = $(LDADD)
 amrestore_DEPENDENCIES = librestore.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
 am__depfiles_maybe = depfiles
@@ -113,11 +115,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -125,6 +130,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -308,8 +315,11 @@ target_vendor = @target_vendor@
 INCLUDES = -I$(top_builddir)/common-src \
                -I$(top_srcdir)/common-src   \
                -I$(top_srcdir)/tape-src     \
-               -I$(top_srcdir)/server-src
+               -I$(top_srcdir)/server-src   \
+               -I$(top_srcdir)/amandad-src
 
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
 lib_LTLIBRARIES = librestore.la
 LIB_EXTENSION = la
 
@@ -319,9 +329,11 @@ LIB_EXTENSION = la
 # need to list libamanda twice here, first to override the system library
 # routines, and second to pick up any references in the other libraries.
 ###
-LDADD = librestore.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+LDADD = librestore.$(LIB_EXTENSION)              \
+      ../common-src/libamanda.$(LIB_EXTENSION) \
+      $(READLINE_LIBS)
 
+amidxtaped_LDADD = $(LDADD) ../amandad-src/libamandad.$(LIB_EXTENSION)
 amidxtaped_SOURCES = amidxtaped.c
 amfetchdump_SOURCES = amfetchdump.c
 librestore_la_SOURCES = restore.c
@@ -696,6 +708,24 @@ install-exec-hook:
                echo chgrp $(SETUID_GROUP) $$pa; \
                chgrp $(SETUID_GROUP) $$pa; \
        done
+
+lint:
+       @ for p in $(libexec_PROGRAMS) $(sbin_PROGRAMS); do                     \
+               f="$$p.c $(librestore_la_SOURCES)";                             \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               (cd ../server-src; make listlibsrc);                            \
+               f="$$f "`cat ../server-src/listlibsrc.output`;                  \
+               (cd ../tape-src; make listlibsrc);                              \
+               f="$$f "`cat ../tape-src/listlibsrc.output`;                    \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
index e94ce290f1c843b4965d8a296204552686b04fce..f3b282f0c2617860740d845101bd737ca1e3e8ce 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amfetchdump.c,v 1.7 2006/03/14 13:12:01 martinea Exp $
+ * $Id: amfetchdump.c,v 1.16 2006/08/24 01:57:15 paddy_s Exp $
  *
  * retrieves specific dumps from a set of amanda tapes
  */
@@ -42,7 +42,6 @@
 
 #define CREAT_MODE     0640
 
-extern char *rst_conf_logdir;
 extern char *rst_conf_logfile;
 extern char *config_dir;
 int get_lock = 0;
@@ -57,35 +56,39 @@ typedef struct needed_tapes_s {
 
 /* local functions */
 
-void errexit P((void));
-void handle_sigpipe P((int sig));
-tapelist_t *list_needed_tapes P((match_list_t *match_list));
-void usage P((void));
-int main P((int argc, char **argv));
+void errexit(void);
+tapelist_t *list_needed_tapes(match_list_t *match_list);
+void usage(void);
+int main(int argc, char **argv);
 
 /* exit routine */
-static int parent_pid = -1;
-static void cleanup P((void));
+static pid_t parent_pid = -1;
+static void cleanup(void);
+
 
-void errexit()
 /*
  * Do exit(2) after an error, rather than exit(1).
  */
+
+void
+errexit(void)
 {
     exit(2);
 }
 
 
-void usage()
 /*
  * Print usage message and terminate.
  */
+
+void
+usage(void)
 {
-    fprintf(stderr, "Usage: amfetchdump [options] config hostname [diskname [datestamp [level [hostname [diskname [datestamp [level ... ]]]]]]]\n\n");
+    fprintf(stderr, "Usage: amfetchdump [options] config hostname [diskname [datestamp [level [hostname [diskname [datestamp [level ... ]]]]]]] [-o configoption]*\n\n");
     fprintf(stderr, "Goes and grabs a dump from tape, moving tapes around and assembling parts as\n");
     fprintf(stderr, "necessary.  Files are restored to the current directory, unless otherwise\nspecified.\n\n");
     fprintf(stderr, "  -p Pipe exactly *one* complete dumpfile to stdout, instead of to disk.\n");
-    fprintf(stderr, "  -o <output dir> Restore files to this directory.\n");
+    fprintf(stderr, "  -O <output dir> Restore files to this directory.\n");
     fprintf(stderr, "  -d <device> Force restoration from a particular tape device.\n");
     fprintf(stderr, "  -c Compress output, fastest method available.\n");
     fprintf(stderr, "  -C Compress output, best filesize method available.\n");
@@ -105,8 +108,9 @@ void usage()
  * files we want from said tapes while we're at it (the whole find_result
  * should do fine)
  */
-tapelist_t *list_needed_tapes(match_list)
-match_list_t *match_list;
+tapelist_t *
+list_needed_tapes(
+    match_list_t *     match_list)
 {
     needed_tape_t *needed_tapes = NULL, *curtape = NULL;
     disklist_t diskqp;
@@ -126,6 +130,7 @@ match_list_t *match_list;
     }
     if(read_diskfile(conf_diskfile, &diskqp) != 0) {
         error("could not load disklist \"%s\"", conf_diskfile);
+       /*NOTREACHED*/
     }
     if (*conf_tapelist == '/') {
         conf_tapelist = stralloc(conf_tapelist);
@@ -134,18 +139,19 @@ match_list_t *match_list;
     }
     if(read_tapelist(conf_tapelist)) {
         error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
     }
     amfree(conf_diskfile);
     amfree(conf_tapelist);
 
     /* Grab a find_output_t of all logged dumps */
-    alldumps = find_dump(1, &diskqp); 
+    alldumps = find_dump(1, &diskqp);
     free_disklist(&diskqp);
     if(alldumps == NULL){
         fprintf(stderr, "No dump records found\n");
         exit(1);
     }
+
     /* Compare all known dumps to our match list, note what we'll need */
     for(me = match_list; me; me = me->next) {
        find_result_t *curmatch = NULL; 
@@ -157,8 +163,8 @@ match_list_t *match_list;
        for(curmatch = matches; curmatch; curmatch = curmatch->next){
            int havetape = 0;
            if(strcmp("OK", curmatch->status)){
-               fprintf(stderr,"Dump %d %s %s %d had status '%s', skipping\n",
-                                curmatch->datestamp, curmatch->hostname,
+               fprintf(stderr,"Dump %s %s %s %d had status '%s', skipping\n",
+                                curmatch->timestamp, curmatch->hostname,
                                 curmatch->diskname, curmatch->level,
                                 curmatch->status);
                continue;
@@ -166,10 +172,10 @@ match_list_t *match_list;
            for(curtape = needed_tapes; curtape; curtape = curtape->next) {
                if(!strcmp(curtape->label, curmatch->label)){
                    find_result_t *rsttemp = NULL;
-                   find_result_t *rstfile = alloc(sizeof(find_result_t));
+                   find_result_t *rstfile = alloc(SIZEOF(find_result_t));
                    int keep = 1;
 
-                   memcpy(rstfile, curmatch, sizeof(find_result_t));
+                   memcpy(rstfile, curmatch, SIZEOF(find_result_t));
 
                    havetape = 1;
 
@@ -177,7 +183,10 @@ match_list_t *match_list;
                            rsttemp;
                            rsttemp=rsttemp->next){
                        if(rstfile->filenum == rsttemp->filenum){
-                           fprintf(stderr, "Seeing multiple entries for tape %s file %d, using most recent\n", curtape->label, rstfile->filenum);
+                           fprintf(stderr, "Seeing multiple entries for tape "
+                                  "%s file " OFF_T_FMT ", using most recent\n",
+                                   curtape->label,
+                                   (OFF_T_FMT_TYPE)rstfile->filenum);
                            keep = 0;
                        }
                    }
@@ -194,10 +203,10 @@ match_list_t *match_list;
                }
            }
            if(!havetape){
-               find_result_t *rstfile = alloc(sizeof(find_result_t));
+               find_result_t *rstfile = alloc(SIZEOF(find_result_t));
                needed_tape_t *newtape =
-                                         alloc(sizeof(needed_tape_t));
-               memcpy(rstfile, curmatch, sizeof(find_result_t));
+                                         alloc(SIZEOF(needed_tape_t));
+               memcpy(rstfile, curmatch, SIZEOF(find_result_t));
                rstfile->next = NULL;
                newtape->files = rstfile;
                if(curmatch->filenum < 1) newtape->isafile = 1;
@@ -225,6 +234,7 @@ match_list_t *match_list;
     if(numtapes == 0){
       fprintf(stderr, "No matching dumps found\n");
       exit(1);
+      /* NOTREACHED */
     }
 
     /* stick that list in a structure that librestore will understand */
@@ -240,13 +250,16 @@ match_list_t *match_list;
     return(tapes);
 }
 
-int main(argc, argv)
-int argc;
-char **argv;
+
 /*
  * Parses command line, then loops through all files on tape, restoring
  * files that match the command line criteria.
  */
+
+int
+main(
+    int                argc,
+    char **    argv)
 {
     extern int optind;
     int opt;
@@ -261,8 +274,10 @@ char **argv;
     int arg_state;
     rst_flags_t *rst_flags;
     struct passwd *pwent;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
-    for(fd = 3; fd < FD_SETSIZE; fd++) {
+    for(fd = 3; fd < (int)FD_SETSIZE; fd++) {
        /*
         * Make sure nobody spoofs us with a lot of extra open files
         * that would cause an open we do to get a very high file
@@ -274,6 +289,8 @@ char **argv;
 
     set_pname("amfetchdump");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
 #ifdef FORCE_USERID
 
     /* we'd rather not run as root */
@@ -286,9 +303,12 @@ char **argv;
     if(geteuid() == 0) {
        if(client_uid == (uid_t) -1) {
            error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+           /*NOTREACHED*/
        }
 
+       /*@ignore@*/
        initgroups(CLIENT_LOGIN, client_gid);
+       /*@end@*/
        setgid(client_gid);
        setuid(client_uid);
     }
@@ -302,36 +322,45 @@ char **argv;
 
     onerror(errexit);
 
-    if(argc <= 1) usage();
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if(my_argc <= 1) {
+       usage();
+       /*NOTREACHED*/
+    }
 
     rst_flags = new_rst_flags();
     rst_flags->wait_tape_prompt = 1;
-    
+
     /* handle options */
-    while( (opt = getopt(argc, argv, "alht:scCpb:nwi:d:o:")) != -1) {
+    while( (opt = getopt(my_argc, my_argv, "alht:scCpb:nwi:d:O:")) != -1) {
        switch(opt) {
-       case 'b': rst_flags->compress = 1; break;
-            rst_flags->blocksize = strtol(optarg, &e, 10);
+       case 'b':
+            rst_flags->blocksize = (ssize_t)strtol(optarg, &e, 10);
             if(*e == 'k' || *e == 'K') {
                rst_flags->blocksize *= 1024;
            } else if(*e == 'm' || *e == 'M') {
                rst_flags->blocksize *= 1024 * 1024;
            } else if(*e != '\0') {
                error("invalid blocksize value \"%s\"", optarg);
+               /*NOTREACHED*/
            }
            if(rst_flags->blocksize < DISK_BLOCK_BYTES) {
                error("minimum block size is %dk", DISK_BLOCK_BYTES / 1024);
+               /*NOTREACHED*/
            }
            break;
        case 'c': rst_flags->compress = 1; break;
-       case 'o': rst_flags->restore_dir = stralloc(optarg) ; break;
+       case 'O': rst_flags->restore_dir = stralloc(optarg) ; break;
        case 'd': rst_flags->alt_tapedev = stralloc(optarg) ; break;
        case 'C':
            rst_flags->compress = 1;
            rst_flags->comp_type = COMPRESS_BEST_OPT;
            break;
        case 'p': rst_flags->pipe_to_fd = fileno(stdout); break;
-       case 's': rst_flags->fsf = 0; break;
+       case 's': rst_flags->fsf = (off_t)0; break;
        case 'l': rst_flags->leave_comp = 1; break;
        case 'i': rst_flags->inventory_log = stralloc(optarg); break;
        case 'n': rst_flags->inline_assemble = 0; break;
@@ -340,6 +369,7 @@ char **argv;
        case 'h': rst_flags->headers = 1; break;
        default:
            usage();
+           /*NOTREACHED*/
        }
     }
 
@@ -350,6 +380,7 @@ char **argv;
        rst_flags->leave_comp = 1;
        if(rst_flags->compress){
            error("Cannot force compression when doing inventory/search");
+           /*NOTREACHED*/
        }
        fprintf(stderr, "Doing inventory/search, dumps will not be uncompressed or assembled on-the-fly.\n");
     }
@@ -360,20 +391,26 @@ char **argv;
     }
 
     /* make sure our options all make sense otherwise */
-    if(check_rst_flags(rst_flags) == -1) usage();
+    if(check_rst_flags(rst_flags) == -1) {
+       usage();
+       /*NOTREACHED*/
+    }
 
-    config_name = argv[optind++];
+    config_name = my_argv[optind++];
     config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if (read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
 
-    if((argc - optind) < 1 && !rst_flags->inventory_log){
+    if((my_argc - optind) < 1 && !rst_flags->inventory_log){
        fprintf(stderr, "Not enough arguments\n\n");
        usage();
+       /*NOTREACHED*/
     }
 
 #define ARG_GET_HOST 0
@@ -382,14 +419,14 @@ char **argv;
 #define ARG_GET_LEVL 3
 
     arg_state = ARG_GET_HOST;
-    while(optind < argc) {
+    while(optind < my_argc) {
         switch(arg_state) {
         case ARG_GET_HOST:
             /*
              * New host/disk/date/level set, so allocate a match_list.
              */
-            me = alloc(sizeof(*me));
-            me->hostname = argv[optind++];
+            me = alloc(SIZEOF(*me));
+            me->hostname = my_argv[optind++];
             me->diskname = "";
             me->datestamp = "";
             me->level = "";
@@ -400,43 +437,47 @@ char **argv;
                 fprintf(stderr, "%s: bad hostname regex \"%s\": %s\n",
                         get_pname(), me->hostname, errstr);
                 usage();
+               /*NOTREACHED*/
             }
             arg_state = ARG_GET_DISK;
             break;
         case ARG_GET_DISK:
-            me->diskname = argv[optind++];
+            me->diskname = my_argv[optind++];
             if(me->diskname[0] != '\0'
                && (errstr=validate_regexp(me->diskname)) != NULL) {
                 fprintf(stderr, "%s: bad diskname regex \"%s\": %s\n",
                         get_pname(), me->diskname, errstr);
                 usage();
+               /*NOTREACHED*/
             }
             arg_state = ARG_GET_DATE;
             break;
         case ARG_GET_DATE:
-            me->datestamp = argv[optind++];
+            me->datestamp = my_argv[optind++];
             if(me->datestamp[0] != '\0'
                && (errstr=validate_regexp(me->datestamp)) != NULL) {
                 fprintf(stderr, "%s: bad datestamp regex \"%s\": %s\n",
                         get_pname(), me->datestamp, errstr);
                 usage();
+               /*NOTREACHED*/
             }
             arg_state = ARG_GET_LEVL;
             break;
         case ARG_GET_LEVL:
-            me->level = argv[optind++];
+            me->level = my_argv[optind++];
             if(me->level[0] != '\0'
                && (errstr=validate_regexp(me->level)) != NULL) {
                 fprintf(stderr, "%s: bad level regex \"%s\": %s\n",
                         get_pname(), me->level, errstr);
                 usage();
+               /*NOTREACHED*/
             }
         }
     }
 
     /* XXX I don't think this can happen */
     if(match_list == NULL && !rst_flags->inventory_log) {
-        match_list = alloc(sizeof(*match_list));
+        match_list = alloc(SIZEOF(*match_list));
         match_list->hostname = "";
         match_list->diskname = "";
         match_list->datestamp = "";
@@ -457,10 +498,13 @@ char **argv;
 
     /* Decide what tapes we'll need */
     needed_tapes = list_needed_tapes(match_list);
-    
+
     parent_pid = getpid();
     atexit(cleanup);
     get_lock = lock_logfile(); /* config is loaded, should be ok here */
+    if(get_lock == 0) {
+       error("%s exists: amdump or amflush is already running, or you must run amcleanup", rst_conf_logfile);
+    }
     search_tapes(NULL, 1, needed_tapes, match_list, rst_flags, NULL);
     cleanup();
 
@@ -471,6 +515,7 @@ char **argv;
     else flush_open_outputs(0, NULL);
 
     free_rst_flags(rst_flags);
+    free_new_argv(new_argc, new_argv);
 
     return(0);
 }
@@ -482,4 +527,3 @@ cleanup(void)
        if(get_lock) unlink(rst_conf_logfile);
     }
 }
-
index a3a27f8057a12a1c5c3b87e64d2a58b1882cf014..54dcfa1bab4a131c67bd0d3053195fffb475b230 100644 (file)
@@ -23,7 +23,7 @@
  * Authors: the Amanda Development Team.  Its members are listed in a
  * file named AUTHORS, in the root directory of this distribution.
  */
-/* $Id: amidxtaped.c,v 1.58 2006/03/14 13:12:01 martinea Exp $
+/* $Id: amidxtaped.c,v 1.73 2006/07/25 19:06:46 martinea Exp $
  *
  * This daemon extracts a dump image off a tape for amrecover and
  * returns it over the network. It basically, reads a number of
 #include "logfile.h"
 #include "amfeatures.h"
 #include "stream.h"
+#include "amandad.h"
 
 #define TIMEOUT 30
 
 static char *pgm = "amidxtaped";       /* in case argv[0] is not set */
 
-extern char *rst_conf_logdir;
 extern char *rst_conf_logfile;
 extern char *config_dir;
 
 static int get_lock = 0;
+static int from_amandad;
 
 static am_feature_t *our_features = NULL;
 static am_feature_t *their_features = NULL;
+static g_option_t *g_options = NULL;
+static int ctlfdin, ctlfdout, datafdout;
+static char *amandad_auth = NULL;
 
-static char *get_client_line P((void));
-static char *get_client_line_fd P((int));
-static void check_security_buffer P((char*));
+static char *get_client_line(void);
+static void check_security_buffer(char *);
+static char *get_client_line_fd(int);
 
 /* exit routine */
-static int parent_pid = -1;
-static void cleanup P((void));
+static pid_t parent_pid = -1;
+static void cleanup(void);
+
+int main(int argc, char **argv);
 
 /* get a line from client - line terminated by \r\n */
 static char *
-get_client_line()
+get_client_line(void)
 {
     static char *line = NULL;
     char *part = NULL;
-    int len;
+    size_t len;
 
     amfree(line);
     while(1) {
@@ -92,7 +98,7 @@ get_client_line()
            amfree(part);
            dbclose();
            exit(1);
-           /* NOTREACHED */
+           /*NOTREACHED*/
        }
        if(line) {
            strappend(line, part);
@@ -118,18 +124,18 @@ get_client_line()
 
 /* get a line from client - line terminated by \r\n */
 static char *
-get_client_line_fd(fd)
-int fd;
+get_client_line_fd(
+    int                fd)
 {
     static char *line = NULL;
-    static int line_size = 0;
+    static size_t line_size = 0;
     char *s = line;
-    int len = 0;
+    size_t len = 0;
     char c;
-    int nb;
+    ssize_t nb;
 
     if(line == NULL) { /* first time only, allocate initial buffer */
-       s = line = malloc(128);
+       s = line = alloc(128);
        line_size = 128;
     }
     while(1) {
@@ -141,7 +147,7 @@ int fd;
                continue;
            }
            dbprintf(("%s: Control pipe read error - %s\n",
-               pgm, strerror(errno)));
+                     pgm, strerror(errno)));
            break;
        }
 
@@ -150,7 +156,7 @@ int fd;
            line = realloc(line, line_size);
            if (line == NULL) {
                error("Memory reallocation failure");
-               /* NOTREACHED */
+               /*NOTREACHED*/
            }
            s = &line[len];
        }
@@ -171,48 +177,61 @@ int fd;
 }
 
 
-void check_security_buffer(buffer)
-     char *buffer;
+void
+check_security_buffer(
+    char *     buffer)
 {
     socklen_t i;
     struct sockaddr_in addr;
     char *s, *fp, ch;
     char *errstr = NULL;
-    
-     i = sizeof (addr);
-     if (getpeername(0, (struct sockaddr *)&addr, &i) == -1)
-        error("getpeername: %s", strerror(errno));
-     if (addr.sin_family != AF_INET || ntohs(addr.sin_port) == 20) {
-       error("connection rejected from %s family %d port %d",
+
+    dbprintf(("%s: check_security_buffer(buffer='%s')\n",
+               debug_prefix(NULL), buffer));
+
+    i = SIZEOF(addr);
+    if (getpeername(0, (struct sockaddr *)&addr, &i) == -1) {
+       error("getpeername: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+    if ((addr.sin_family != (sa_family_t)AF_INET)
+               || (ntohs(addr.sin_port) == 20)) {
+       error("connection rejected from %s family %d port %d",
              inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port));
-     }
-     
-     /* do the security thing */
-     s = buffer;
-     ch = *s++;
-
-     skip_whitespace(s, ch);
-     if (ch == '\0') {
-            error("cannot parse SECURITY line");
-     }
-     fp = s-1;
-     skip_non_whitespace(s, ch);
-     s[-1] = '\0';
-     if (strcmp(fp, "SECURITY") != 0) {
-        error("cannot parse SECURITY line");
-     }
-     skip_whitespace(s, ch);
-     if (!check_security(&addr, s-1, 0, &errstr)) {
-        error("security check failed: %s", errstr);
-     }
+       /*NOTREACHED*/
+    }
+
+    /* do the security thing */
+    s = buffer;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if (ch == '\0') {
+       error("cannot parse SECURITY line");
+       /*NOTREACHED*/
+    }
+    fp = s-1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    if (strcmp(fp, "SECURITY") != 0) {
+       error("cannot parse SECURITY line");
+       /*NOTREACHED*/
+    }
+    skip_whitespace(s, ch);
+    if (!check_security(&addr, s-1, 0, &errstr)) {
+       error("security check failed: %s", errstr);
+       /*NOTREACHED*/
+    }
 }
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     char *buf = NULL;
-    int data_sock = -1, data_port = -1;
+    int data_sock = -1;
+    in_port_t data_port = (in_port_t)-1;
     socklen_t socklen;
     struct sockaddr_in addr;
     match_list_t *match_list;
@@ -221,12 +240,13 @@ char **argv;
     rst_flags_t *rst_flags;
     int use_changer = 0;
     FILE *prompt_stream = NULL;
-    int re_end = 0;
+    int re_end;
     char *re_config = NULL;
     char *conf_tapetype;
     tapetype_t *tape;
+    char *line;
 
-    safe_fd(-1, 0);
+    safe_fd(DATA_FD_OFFSET, 4);
     safe_cd();
 
     /* Don't die when child closes pipe */
@@ -254,6 +274,16 @@ char **argv;
 
     set_pname(pgm);
 
+    if(argv && argv[1] && strcmp(argv[1], "amandad") == 0) {
+       from_amandad = 1;
+       if(argv[2])
+           amandad_auth = argv[2];
+    }
+    else {
+       from_amandad = 0;
+       safe_fd(-1, 0);
+    }
+
 #ifdef FORCE_USERID
 
     /* we'd rather not run as root */
@@ -261,9 +291,12 @@ char **argv;
     if(geteuid() == 0) {
        if(client_uid == (uid_t) -1) {
            error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+           /*NOTREACHED*/
        }
 
+       /*@ignore@*/
        initgroups(CLIENT_LOGIN, client_gid);
+       /*@end@*/
        setgid(client_gid);
        setuid(client_uid);
     }
@@ -275,7 +308,7 @@ char **argv;
        chats to stderr, which we don't want going to client */
     /* if no debug file, ship to bit bucket */
     (void)close(STDERR_FILENO);
-    dbopen();
+    dbopen(DBG_SUBDIR_SERVER);
     startclock();
     dbprintf(("%s: version %s\n", pgm, version()));
 #ifdef DEBUG_CODE
@@ -304,35 +337,83 @@ char **argv;
                  debug_prefix_time(NULL)));
     }
 
-    socklen = sizeof (addr);
-    if (getpeername(0, (struct sockaddr *)&addr, &socklen) == -1)
-       error("getpeername: %s", strerror(errno));
-    if (addr.sin_family != AF_INET || ntohs(addr.sin_port) == 20) {
-       error("connection rejected from %s family %d port %d",
-             inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port));
-    }
+    if(from_amandad == 0) {
+       socklen = SIZEOF(addr);
+       if (getpeername(0, (struct sockaddr *)&addr, &socklen) == -1) {
+           error("getpeername: %s", strerror(errno));
+           /*NOTREACHED*/
+       }
+       if ((addr.sin_family != (sa_family_t)AF_INET)
+               || (ntohs(addr.sin_port) == 20)) {
+           error("connection rejected from %s family %d port %d",
+                 inet_ntoa(addr.sin_addr), addr.sin_family,
+                 htons(addr.sin_port));
+           /*NOTREACHED*/
+       }
 
-    /* do the security thing */
-    amfree(buf);
-    buf = stralloc(get_client_line());
-    check_security_buffer(buf);
+       /* do the security thing */
+       amfree(buf);
+       buf = stralloc(get_client_line());
+       check_security_buffer(buf);
+    }
+    else {
+       ctlfdout  = DATA_FD_OFFSET + 0;
+       ctlfdin   = DATA_FD_OFFSET + 1;
+       datafdout = DATA_FD_OFFSET + 2;
+       close(DATA_FD_OFFSET +3);
+
+       /* read the REQ packet */
+       for(; (line = agets(stdin)) != NULL; free(line)) {
+#define sc "OPTIONS "
+           if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+#undef sc
+               g_options = parse_g_options(line+8, 1);
+               if(!g_options->hostname) {
+                   g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1);
+                   gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH);
+                   g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0';
+               }
+           }
+       }
+       amfree(line);
+
+       if(amandad_auth && g_options->auth) {
+           if(strcasecmp(amandad_auth, g_options->auth) != 0) {
+               printf("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'\n",
+                      g_options->auth, amandad_auth);
+               error("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'",
+                     g_options->auth, amandad_auth);
+               /*NOTREACHED*/
+           }
+       }
+       /* send the REP packet */
+       printf("CONNECT CTL %d DATA %d\n", DATA_FD_OFFSET, DATA_FD_OFFSET+1);
+       printf("\n");
+       fflush(stdout);
+       fflush(stdin);
+       if ((dup2(ctlfdout, fileno(stdout)) < 0)
+                || (dup2(ctlfdin, fileno(stdin)) < 0)) {
+           error("amandad: Failed to setup stdin or stdout");
+           /*NOTREACHED*/
+       }
+    }
 
     /* get the number of arguments */
-    match_list = alloc(sizeof(match_list_t));
+    match_list = alloc(SIZEOF(match_list_t));
     match_list->next = NULL;
     match_list->hostname = "";
     match_list->datestamp = "";
     match_list->level = "";
     match_list->diskname = "";
 
-   do {
+    for (re_end = 0; re_end == 0; ) {
        amfree(buf);
        buf = stralloc(get_client_line());
        if(strncmp(buf, "LABEL=", 6) == 0) {
            tapes = unmarshal_tapelist_str(buf+6);
        }
        else if(strncmp(buf, "FSF=", 4) == 0) {
-           rst_flags->fsf = atoi(buf + 4);
+           rst_flags->fsf = OFF_T_ATOI(buf + 4);
        }
        else if(strncmp(buf, "HEADER", 6) == 0) {
            rst_flags->headers = 1;
@@ -344,7 +425,10 @@ char **argv;
            their_features = am_string_to_feature(their_feature_string);
            amfree(their_feature_string);
            our_feature_string = am_feature_to_string(our_features);
-           printf("%s", our_feature_string);
+           if(from_amandad == 1) 
+               printf("FEATURES=%s\r\n", our_feature_string);
+           else
+               printf("%s", our_feature_string);
            fflush(stdout);
            amfree(our_feature_string);
        }
@@ -370,9 +454,7 @@ char **argv;
 /* XXX does nothing?     amrestore_nargs = atoi(buf); */
            re_end = 1;
        }
-       else {
-       }
-    } while (re_end == 0);
+    }
     amfree(buf);
 
     if(!tapes && rst_flags->alt_tapedev){
@@ -394,9 +476,11 @@ char **argv;
            re_config = NULL;
        }
        amfree(conffile);
+
+       dbrename(config_name, DBG_SUBDIR_SERVER);
     }
 
-    if(tapes && 
+    if(tapes &&
        (!rst_flags->alt_tapedev  ||
         (re_config && ( strcmp(rst_flags->alt_tapedev,
                                getconf_str(CNF_AMRECOVER_CHANGER)) == 0 ||
@@ -405,7 +489,7 @@ char **argv;
        /* We need certain options, if restoring from more than one tape */
         if(tapes->next && !am_has_feature(their_features, fe_recover_splits)) {
             error("%s: Client must support split dumps to restore requested data.",  get_pname());
-            /* NOTREACHED */
+            /*NOTREACHED*/
         }
        dbprintf(("%s: Restoring from changer, checking labels\n", get_pname()));
        rst_flags->check_labels = 1;
@@ -413,7 +497,7 @@ char **argv;
     }
 
     /* If we'll be stepping on the tape server's devices, lock them. */
-    if(re_config  &&
+    if(re_config &&
        (use_changer || (rst_flags->alt_tapedev &&
                         strcmp(rst_flags->alt_tapedev,
                                getconf_str(CNF_TAPEDEV)) == 0) ) ) {
@@ -431,45 +515,56 @@ char **argv;
     /* Read the default block size from the tape type */
     if(re_config && (conf_tapetype = getconf_str(CNF_TAPETYPE)) != NULL) {
        tape = lookup_tapetype(conf_tapetype);
-       rst_flags->blocksize = tape->blocksize * 1024;
+       rst_flags->blocksize = tapetype_get_blocksize(tape) * 1024;
     }
 
-    if(rst_flags->fsf && re_config && 
-       getconf_int(CNF_AMRECOVER_DO_FSF) == 0) {
-       rst_flags->fsf = 0;
+    if(rst_flags->fsf && re_config &&
+       getconf_boolean(CNF_AMRECOVER_DO_FSF) == 0) {
+       rst_flags->fsf = (off_t)0;
     }
 
-    if(re_config && getconf_int(CNF_AMRECOVER_CHECK_LABEL) == 0) {
+    if (!use_changer && re_config &&
+       getconf_boolean(CNF_AMRECOVER_CHECK_LABEL) == 0) {
        rst_flags->check_labels = 0;
     }
 
     /* establish a distinct data connection for dumpfile data */
-    if(am_has_feature(their_features, fe_recover_splits)){
-       int data_fd;
-       char *buf;
-       
-       dbprintf(("%s: Client understands split dumpfiles\n", get_pname()));
-       
-       if((data_sock = stream_server(&data_port, STREAM_BUFSIZE, -1)) < 0){
-           error("%s: could not create data socket: %s", get_pname(),
-                 strerror(errno));
-       }
-       dbprintf(("%s: Local port %d set aside for data\n", get_pname(),
-                 data_port));
-       
-       printf("CONNECT %d\n", data_port); /* tell client where to connect */
-       fflush(stdout);
-       
-       if((data_fd = stream_accept(data_sock, TIMEOUT, -1, -1)) < 0){
-           error("stream_accept failed for client data connection: %s\n",
-                 strerror(errno));
+    if(am_has_feature(their_features, fe_recover_splits)) {
+       if(from_amandad == 1) {
+           rst_flags->pipe_to_fd = datafdout;
+            prompt_stream = stdout;
        }
+       else {
+           int data_fd;
+           char *buf;
 
-       buf = get_client_line_fd(data_fd);
+           dbprintf(("%s: Client understands split dumpfiles\n",get_pname()));
 
-       check_security_buffer(buf);
-       rst_flags->pipe_to_fd = data_fd;
-        prompt_stream = stdout;
+           if((data_sock = stream_server(&data_port, STREAM_BUFSIZE, 
+                STREAM_BUFSIZE, 0)) < 0){
+               error("%s: could not create data socket: %s", get_pname(),
+                     strerror(errno));
+               /*NOTREACHED*/
+           }
+           dbprintf(("%s: Local port %d set aside for data\n", get_pname(),                         data_port));
+
+           /* tell client where to connect */
+           printf("CONNECT %hu\n", (unsigned short)data_port);
+           fflush(stdout);
+
+           if((data_fd = stream_accept(data_sock, TIMEOUT, STREAM_BUFSIZE, 
+                 STREAM_BUFSIZE)) < 0){
+               error("stream_accept failed for client data connection: %s\n",
+                     strerror(errno));
+               /*NOTREACHED*/
+           }
+
+           buf = get_client_line_fd(data_fd);
+
+           check_security_buffer(buf);
+           rst_flags->pipe_to_fd = data_fd;
+           prompt_stream = stdout;
+       }
     }
     else {
        rst_flags->pipe_to_fd = fileno(stdout);
@@ -477,23 +572,40 @@ char **argv;
     }
     dbprintf(("%s: Sending output to file descriptor %d\n",
              get_pname(), rst_flags->pipe_to_fd));
-    
-    
+
+
+    if(get_lock == 0 &&
+       re_config && 
+       (use_changer || (rst_flags->alt_tapedev &&
+                        strcmp(rst_flags->alt_tapedev,
+                               getconf_str(CNF_TAPEDEV)) == 0) ) ) {
+       send_message(prompt_stream, rst_flags, their_features,
+                    "%s exists: amdump or amflush is already running, "
+                    "or you must run amcleanup", 
+                    rst_conf_logfile);
+       error("%s exists: amdump or amflush is already running, "
+             "or you must run amcleanup",
+             rst_conf_logfile);
+    }
+
     /* make sure our restore flags aren't crazy */
-    if(check_rst_flags(rst_flags) == -1){
-       if(rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd);
+    if (check_rst_flags(rst_flags) == -1) {
+       if (rst_flags->pipe_to_fd != -1)
+           aclose(rst_flags->pipe_to_fd);
+       send_message(prompt_stream, rst_flags, their_features,
+                    "restore flags are crazy");
        exit(1);
     }
-    
+
     /* actual restoration */
     search_tapes(prompt_stream, use_changer, tapes, match_list, rst_flags,
                 their_features);
     dbprintf(("%s: Restoration finished\n", debug_prefix_time(NULL)));
-    
+
     /* cleanup */
     if(rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd);
     free_tapelist(tapes);
-    
+
     am_release_feature_set(their_features);
 
     amfree(rst_flags->alt_tapedev);
@@ -515,4 +627,3 @@ cleanup(void)
        if(get_lock) unlink(rst_conf_logfile);
     }
 }
-
index 535e4a6068c5b9528460ba3c0413359d15e77393..1410b9dccff09c2cb43f5487968c5a9bca14a82a 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amrestore.c,v 1.56.2.1 2006/04/07 10:52:17 martinea Exp $
+ * $Id: amrestore.c,v 1.63 2006/07/25 18:58:10 martinea Exp $
  *
  * retrieves files from an amanda tape
  */
 
 #define CREAT_MODE     0640
 
-static int file_number;
+static off_t file_number;
 static pid_t comp_enc_pid = -1;
 static int tapedev;
-static long filefsf = -1;
+static off_t filefsf = (off_t)-1;
 
 /* local functions */
 
-static void errexit P((void));
-static void usage P((void));
-int main P((int argc, char **argv));
+static void errexit(void);
+static void usage(void);
+int main(int argc, char **argv);
 
-static void errexit()
 /*
  * Do exit(2) after an error, rather than exit(1).
  */
+
+static void
+errexit(void)
 {
     exit(2);
 }
 
 
-static void usage()
 /*
  * Print usage message and terminate.
  */
+
+static void
+usage(void)
 {
-    error("Usage: amrestore [-b blocksize] [-r|-c] [-p] [-h] [-f fileno] [-l label] tape-device|holdingfile [hostname [diskname [datestamp [hostname [diskname [datestamp ... ]]]]]]");
+    error("Usage: amrestore [-b blocksize] [-r|-c] [-p] [-h] [-f fileno] "
+         "[-l label] tape-device|holdingfile [hostname [diskname [datestamp "
+         "[hostname [diskname [datestamp ... ]]]]]]");
+    /*NOTREACHED*/
 }
 
-int main(argc, argv)
-int argc;
-char **argv;
+
 /*
  * Parses command line, then loops through all files on tape, restoring
  * files that match the command line criteria.
  */
+
+int
+main(
+    int                argc,
+    char **    argv)
 {
     extern int optind;
     int opt;
@@ -105,12 +115,15 @@ char **argv;
     char *label = NULL;
     rst_flags_t *rst_flags;
     int count_error;
-    size_t read_result;
+    long tmplong;
+    ssize_t read_result;
 
     safe_fd(-1, 0);
 
     set_pname("amrestore");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -125,16 +138,25 @@ char **argv;
     while( (opt = getopt(argc, argv, "b:cCd:rphf:l:")) != -1) {
        switch(opt) {
        case 'b':
-           rst_flags->blocksize = strtol(optarg, &e, 10);
+           tmplong = strtol(optarg, &e, 10);
+           rst_flags->blocksize = (ssize_t)tmplong;
            if(*e == 'k' || *e == 'K') {
                rst_flags->blocksize *= 1024;
            } else if(*e == 'm' || *e == 'M') {
                rst_flags->blocksize *= 1024 * 1024;
            } else if(*e != '\0') {
                error("invalid rst_flags->blocksize value \"%s\"", optarg);
+               /*NOTREACHED*/
            }
            if(rst_flags->blocksize < DISK_BLOCK_BYTES) {
                error("minimum block size is %dk", DISK_BLOCK_BYTES / 1024);
+               /*NOTREACHED*/
+           }
+           if(rst_flags->blocksize > MAX_TAPE_BLOCK_KB * 1024) {
+               fprintf(stderr,"maximum block size is %dk, using it\n",
+                       MAX_TAPE_BLOCK_KB);
+               rst_flags->blocksize = MAX_TAPE_BLOCK_KB * 1024;
+               /*NOTREACHED*/
            }
            break;
        case 'c': rst_flags->compress = 1; break;
@@ -146,10 +168,13 @@ char **argv;
        case 'p': rst_flags->pipe_to_fd = fileno(stdout); break;
        case 'h': rst_flags->headers = 1; break;
        case 'f':
-           filefsf = strtol(optarg, &e, 10);
+           filefsf = (off_t)strtoll(optarg, &e, 10);
+           /*@ignore@*/
            if(*e != '\0') {
                error("invalid fileno value \"%s\"", optarg);
+               /*NOTREACHED*/
            }
+           /*@end@*/
            break;
        case 'l':
            label = stralloc(optarg);
@@ -160,7 +185,7 @@ char **argv;
     }
 
     if(rst_flags->compress && rst_flags->raw) {
-       fprintf(stderr, 
+       fprintf(stderr,
                "Cannot specify both -r (raw) and -c (compressed) output.\n");
        usage();
     }
@@ -184,7 +209,7 @@ char **argv;
            /*
             * This is a new host/disk/date triple, so allocate a match_list.
             */
-           me = alloc(sizeof(*me));
+           me = alloc(SIZEOF(*me));
            me->hostname = argv[optind++];
            me->diskname = "";
            me->datestamp = "";
@@ -221,7 +246,7 @@ char **argv;
        }
     }
     if(match_list == NULL) {
-       match_list = alloc(sizeof(*match_list));
+       match_list = alloc(SIZEOF(*match_list));
        match_list->hostname = "";
        match_list->diskname = "";
        match_list->datestamp = "";
@@ -230,6 +255,7 @@ char **argv;
 
     if(tape_stat(tapename,&stat_tape)!=0) {
        error("could not stat %s: %s", tapename, strerror(errno));
+       /*NOTREACHED*/
     }
     isafile=S_ISREG((stat_tape.st_mode));
 
@@ -241,9 +267,11 @@ char **argv;
        else {
            if((err = tape_rewind(tapename)) != NULL) {
                error("Could not rewind device '%s': %s", tapename, err);
+               /*NOTREACHED*/
            }
            if ((tapedev = tape_open(tapename, 0)) == -1) {;
                error("Could not open device '%s': %s", tapename, err);
+               /*NOTREACHED*/
            }
            read_file_header(&file, tapedev, isafile, rst_flags);
            if(file.type != F_TAPESTART) {
@@ -257,11 +285,12 @@ char **argv;
            tapefd_close(tapedev);
            if((err = tape_rewind(tapename)) != NULL) {
                error("Could not rewind device '%s': %s", tapename, err);
+               /*NOTREACHED*/
            }
        }
     }
-    file_number = 0;
-    if(filefsf != -1) {
+    file_number = (off_t)0;
+    if(filefsf != (off_t)-1) {
        if(isafile) {
            fprintf(stderr,"%s: ignoring -f flag when restoring from a file.\n",
                    get_pname());
@@ -269,9 +298,11 @@ char **argv;
        else {
            if((err = tape_rewind(tapename)) != NULL) {
                error("Could not rewind device '%s': %s", tapename, err);
+               /*NOTREACHED*/
            }
-           if((err = tape_fsf(tapename,filefsf)) != NULL) {
+           if((err = tape_fsf(tapename, filefsf)) != NULL) {
                error("Could not fsf device '%s': %s", tapename, err);
+               /*NOTREACHED*/
            }
            file_number = filefsf;
        }
@@ -284,17 +315,16 @@ char **argv;
     }
     if(tapedev < 0) {
        error("could not open %s: %s", tapename, strerror(errno));
+       /*NOTREACHED*/
     }
 
-    read_file_header(&file, tapedev, isafile, rst_flags);
-
-    if(file.type != F_TAPESTART && !isafile && filefsf == -1) {
+    read_result = read_file_header(&file, tapedev, isafile, rst_flags);
+    if(file.type != F_TAPESTART && !isafile && filefsf == (off_t)-1) {
        fprintf(stderr, "%s: WARNING: not at start of tape, file numbers will be offset\n",
                        get_pname());
     }
 
-    count_error=0;
-    read_result = 0;
+    count_error = 0;
     while(count_error < 10) {
        if(file.type == F_TAPEEND) break;
        found_match = 0;
@@ -307,9 +337,9 @@ char **argv;
                    break;
                }
            }
-           fprintf(stderr, "%s: %3d: %s ",
+           fprintf(stderr, "%s: " OFF_T_FMT ": %s ",
                            get_pname(),
-                           file_number,
+                           (OFF_T_FMT_TYPE)file_number,
                            found_match ? "restoring" : "skipping");
            if(file.type != F_DUMPFILE  && file.type != F_SPLIT_DUMPFILE) {
                print_header(stderr, &file);
@@ -350,6 +380,7 @@ char **argv;
            tapefd_close(tapedev);
            if((tapedev = tape_open(tapename, 0)) < 0) {
                error("could not open %s: %s", tapename, strerror(errno));
+               /*NOTREACHED*/
            }
            count_error++;
        } else {
@@ -357,13 +388,14 @@ char **argv;
             * If the last read got something (even an error), we can
             * do an fsf to get to the next file.
             */
-           if(tapefd_fsf(tapedev, 1) < 0) {
+           if(tapefd_fsf(tapedev, (off_t)1) < 0) {
                error("could not fsf %s: %s", tapename, strerror(errno));
+               /*NOTREACHED*/
            }
            count_error=0;
        }
        file_number++;
-       read_file_header(&file, tapedev, isafile, rst_flags);
+       read_result = read_file_header(&file, tapedev, isafile, rst_flags);
     }
     if(isafile) {
        close(tapedev);
@@ -375,17 +407,20 @@ char **argv;
            tapefd_close(tapedev);
            if((tapedev = tape_open(tapename, 0)) < 0) {
                error("could not open %s: %s", tapename, strerror(errno));
+               /*NOTREACHED*/
            }
        } else {
-           if(tapefd_fsf(tapedev, 1) < 0) {
+           if(tapefd_fsf(tapedev, (off_t)1) < 0) {
                error("could not fsf %s: %s", tapename, strerror(errno));
+               /*NOTREACHED*/
            }
        }
        tapefd_close(tapedev);
     }
 
     if((read_result <= 0 || file.type == F_TAPEEND) && !isafile) {
-       fprintf(stderr, "%s: %3d: reached ", get_pname(), file_number);
+       fprintf(stderr, "%s: " OFF_T_FMT ": reached ",
+               get_pname(), (OFF_T_FMT_TYPE)file_number);
        if(read_result <= 0) {
            fprintf(stderr, "end of information\n");
        } else {
index 35818efec636aefba7ef59b310191248bf9009ac..da4e5f7aef50ca616b779d541a1510e5d8c5d641 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: restore.c,v 1.28 2006/03/14 13:12:01 martinea Exp $
+ * $Id: restore.c,v 1.52 2006/08/23 11:41:54 martinea Exp $
  *
  * retrieves files from an amanda tape
  */
 #include "changer.h"
 #include "logfile.h"
 #include "fileheader.h"
+#include "arglist.h"
 #include <signal.h>
 
+#define LOAD_STOP    -1
+#define LOAD_CHANGER -2
+
 int file_number;
 
 /* stuff we're stuck having global */
-static long blocksize = -1;
+static size_t blocksize = (size_t)SSIZE_MAX;
 static char *cur_tapedev = NULL;
 static char *searchlabel = NULL;
 static int backwards;
 static int exitassemble = 0;
-static int tapefd, nslots;
+static int tapefd;
 
 char *rst_conf_logdir = NULL;
 char *rst_conf_logfile = NULL;
@@ -61,35 +65,66 @@ typedef struct open_output_s {
     int outfd;
 } open_output_t;
 
-
 typedef struct dumplist_s {
     struct dumplist_s *next;
     dumpfile_t *file;
 } dumplist_t;
 
+typedef struct seentapes_s {
+    struct seentapes_s *next;
+    char *slotstr;
+    char *label;
+    dumplist_t *files;
+} seentapes_t;
+
 static open_output_t *open_outputs = NULL;
 static dumplist_t *alldumps_list = NULL;
 
-static ssize_t get_block P((int tapefd, char *buffer, int isafile));
-static void append_file_to_fd P((char *filename, int fd));
-static int headers_equal P((dumpfile_t *file1, dumpfile_t *file2, int ignore_partnums));
-static int already_have_dump P((dumpfile_t *file));
-
 /* local functions */
 
-static void handle_sigint(sig)
-int sig;
+static ssize_t get_block(int tapefd, char *buffer, int isafile);
+static void append_file_to_fd(char *filename, int fd);
+static int headers_equal(dumpfile_t *file1, dumpfile_t *file2, int ignore_partnums);
+static int already_have_dump(dumpfile_t *file);
+static void handle_sigint(int sig);
+static int scan_init(void *ud, int rc, int ns, int bk, int s);
+int loadlabel_slot(void *ud, int rc, char *slotstr, char *device);
+void drain_file(int tapefd, rst_flags_t *flags);
+char *label_of_current_slot(char *cur_tapedev, FILE *prompt_out,
+                           int *tapefd, dumpfile_t *file, rst_flags_t *flags,
+                           am_feature_t *their_features,
+                           ssize_t *read_result, tapelist_t *desired_tape);
+
+int load_next_tape(char **cur_tapedev, FILE *prompt_out, int backwards,
+                  rst_flags_t *flags, am_feature_t *their_features,
+                  tapelist_t *desired_tape);
+int load_manual_tape(char **cur_tapedev, FILE *prompt_out,
+                    rst_flags_t *flags, am_feature_t *their_features,
+                    tapelist_t *desired_tape);
+void search_a_tape(char *cur_tapedev, FILE *prompt_out, rst_flags_t *flags,
+                  am_feature_t *their_features, tapelist_t *desired_tape,
+                  int isafile, match_list_t *match_list,
+                  seentapes_t *tape_seen, dumpfile_t *file,
+                  dumpfile_t *prev_rst_file, dumpfile_t *tapestart,
+                  int slot_num, ssize_t *read_result);
+
 /*
  * We might want to flush any open dumps and unmerged splits before exiting
  * on SIGINT, so do so.
  */
+static void
+handle_sigint(
+    int                sig)
 {
+    (void)sig; /* Quiet unused parameter warning */
+
     flush_open_outputs(exitassemble, NULL);
     if(rst_conf_logfile) unlink(rst_conf_logfile);
     exit(0);
 }
 
-int lock_logfile()
+int
+lock_logfile(void)
 {
     rst_conf_logdir = getconf_str(CNF_LOGDIR);
     if (*rst_conf_logdir == '/') {
@@ -99,7 +134,9 @@ int lock_logfile()
     }
     rst_conf_logfile = vstralloc(rst_conf_logdir, "/log", NULL);
     if (access(rst_conf_logfile, F_OK) == 0) {
-       error("%s exists: amdump or amflush is already running, or you must run amcleanup", rst_conf_logfile);
+       dbprintf(("%s exists: amdump or amflush is already running, "
+                 "or you must run amcleanup\n", rst_conf_logfile));
+       return 0;
     }
     log_add(L_INFO, get_pname());
     return 1;
@@ -110,9 +147,11 @@ int lock_logfile()
  * number, and datestamp, and 0 if not.  The part number can be optionally
  * ignored.
  */
-int headers_equal (file1, file2, ignore_partnums)
-dumpfile_t *file1, *file2;
-int ignore_partnums;
+int
+headers_equal(
+    dumpfile_t *file1,
+    dumpfile_t *file2,
+    int                ignore_partnums)
 {
     if(!file1 || !file2) return(0);
     
@@ -132,8 +171,9 @@ int ignore_partnums;
  * See whether we're already pulled an exact copy of the given file (chunk
  * number and all).  Returns 0 if not, 1 if so.
  */
-int already_have_dump(file)
-dumpfile_t *file;
+int
+already_have_dump(
+    dumpfile_t *file)
 {
     dumplist_t *fileentry = NULL;
 
@@ -148,51 +188,53 @@ dumpfile_t *file;
  * Open the named file and append its contents to the (hopefully open) file
  * descriptor supplies.
  */
-static void append_file_to_fd(filename, fd)
-char *filename;
-int fd;
+static void
+append_file_to_fd(
+    char *     filename,
+    int                fd)
 {
     ssize_t bytes_read;
     ssize_t s;
-    off_t wc = 0;
+    off_t wc = (off_t)0;
     char *buffer;
 
-    if(blocksize == -1)
+    if(blocksize == SIZE_MAX)
        blocksize = DISK_BLOCK_BYTES;
     buffer = alloc(blocksize);
 
     if((tapefd = open(filename, O_RDONLY)) == -1) {
        error("can't open %s: %s", filename, strerror(errno));
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     for (;;) {
        bytes_read = get_block(tapefd, buffer, 1); /* same as isafile = 1 */
        if(bytes_read < 0) {
            error("read error: %s", strerror(errno));
-           /* NOTREACHED */
+           /*NOTREACHED*/
        }
 
        if (bytes_read == 0)
                break;
 
-       s = fullwrite(fd, buffer, bytes_read);
+       s = fullwrite(fd, buffer, (size_t)bytes_read);
        if (s < bytes_read) {
-           fprintf(stderr,"Error %d (%s) offset " OFF_T_FMT "+" AM64_FMT ", wrote " AM64_FMT "\n",
-                       errno, strerror(errno), wc, (am64_t)bytes_read, (am64_t)s);
+           fprintf(stderr,"Error (%s) offset " OFF_T_FMT "+" OFF_T_FMT ", wrote " OFF_T_FMT "\n",
+                   strerror(errno), (OFF_T_FMT_TYPE)wc,
+                   (OFF_T_FMT_TYPE)bytes_read, (OFF_T_FMT_TYPE)s);
            if (s < 0) {
                if((errno == EPIPE) || (errno == ECONNRESET)) {
-                   error("%s: pipe reader has quit in middle of file.\n",
+                   error("%s: pipe reader has quit in middle of file.",
                        get_pname());
-                   /* NOTREACHED */
+                   /*NOTREACHED*/
                }
                error("restore: write error = %s", strerror(errno));
-               /* NOTREACHED */
+               /*NOTREACHED*/
            }
-           error("Short write: wrote %d bytes expected %d\n", s, bytes_read);
-           /* NOTREACHCED */
+           error("Short write: wrote %d bytes expected %d.", s, bytes_read);
+           /*NOTREACHCED*/
        }
-       wc += bytes_read;
+       wc += (off_t)bytes_read;
     }
 
     amfree(buffer);
@@ -203,39 +245,54 @@ int fd;
  * Tape changer support routines, stolen brazenly from amtape
  */
 static int 
-scan_init(ud, rc, ns, bk, s)
-     void * ud;
-     int rc, ns, bk, s;
+scan_init(
+     void *    ud,
+     int       rc,
+     int       ns,
+     int       bk,
+     int       s)
 {
-    if(rc)
-        error("could not get changer info: %s", changer_resultstr);
+    (void)ud;  /* Quiet unused parameter warning */
+    (void)ns;  /* Quiet unused parameter warning */
+    (void)s;   /* Quiet unused parameter warning */
 
-    nslots = ns;
+    if(rc) {
+        error("could not get changer info: %s", changer_resultstr);
+       /*NOTREACHED*/
+    }
     backwards = bk;
 
     return 0;
 }
-int loadlabel_slot(ud, rc, slotstr, device)
-     void *ud;
-int rc;
-char *slotstr;
-char *device;
+
+int
+loadlabel_slot(
+     void *    ud,
+     int       rc,
+     char *    slotstr,
+     char *    device)
 {
     char *errstr;
     char *datestamp = NULL;
     char *label = NULL;
 
+    (void)ud;  /* Quiet unused parameter warning */
 
-    if(rc > 1)
+    if(rc > 1) {
         error("could not load slot %s: %s", slotstr, changer_resultstr);
-    else if(rc == 1)
+       /*NOTREACHED*/
+    } else if(rc == 1) {
         fprintf(stderr, "%s: slot %s: %s\n",
                 get_pname(), slotstr, changer_resultstr);
-    else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
+    } else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL) {
         fprintf(stderr, "%s: slot %s: %s\n", get_pname(), slotstr, errstr);
-    else {
-        fprintf(stderr, "%s: slot %s: date %-8s label %s",
-                get_pname(), slotstr, datestamp, label);
+    } else {
+       if(strlen(datestamp)>8)
+            fprintf(stderr, "%s: slot %s: date %-14s label %s",
+                   get_pname(), slotstr, datestamp, label);
+       else
+            fprintf(stderr, "%s: slot %s: date %-8s label %s",
+                   get_pname(), slotstr, datestamp, label);
         if(strcmp(label, FAKE_LABEL) != 0
            && strcmp(label, searchlabel) != 0)
             fprintf(stderr, " (wrong tape)\n");
@@ -248,7 +305,7 @@ char *device;
                 amfree(errstr);
             }
            amfree(cur_tapedev);
-           curslot = stralloc(slotstr);
+           curslot = newstralloc(curslot, slotstr);
             amfree(datestamp);
             amfree(label);
            if(device)
@@ -259,8 +316,8 @@ char *device;
     amfree(datestamp);
     amfree(label);
 
-    if(cur_tapedev) amfree(cur_tapedev);
-    curslot = stralloc(slotstr);
+    amfree(cur_tapedev);
+    curslot = newstralloc(curslot, slotstr);
     if(!device) return(1);
     cur_tapedev = stralloc(device);
 
@@ -276,9 +333,10 @@ char *device;
  * Check whether we've read all of the preceding parts of a given split dump,
  * generally used to see if we're done and can close the thing.
  */
-int have_all_parts (file, upto)
-dumpfile_t *file;
-int upto;
+int
+have_all_parts (
+    dumpfile_t *file,
+    int                upto)
 {
     int c;
     int *foundparts = NULL;
@@ -288,7 +346,7 @@ int upto;
 
     if(upto < 1) upto = file->totalparts;
 
-    foundparts = alloc(sizeof(int) * upto); 
+    foundparts = alloc(SIZEOF(*foundparts) * upto); 
     for(c = 0 ; c< upto; c++) foundparts[c] = 0;
     
     for(fileentry=alldumps_list;fileentry; fileentry=fileentry->next){
@@ -321,9 +379,10 @@ int upto;
  * string them together.  If given an optional file header argument, flush
  * only that dump and do not flush/free any others.
  */
-void flush_open_outputs(reassemble, only_file)
-int reassemble;
-dumpfile_t *only_file;
+void
+flush_open_outputs(
+    int                reassemble,
+    dumpfile_t *only_file)
 {
     open_output_t *cur_out = NULL, *prev = NULL;
     find_result_t *sorted_files = NULL;
@@ -353,16 +412,16 @@ dumpfile_t *only_file;
            if(only_file && !headers_equal(cur_file, only_file, 1)){
                continue;
            }
-           cur_find_res = alloc(sizeof(find_result_t));
-           memset(cur_find_res, '\0', sizeof(find_result_t));
-           cur_find_res->datestamp = atoi(cur_file->datestamp);
+           cur_find_res = alloc(SIZEOF(find_result_t));
+           memset(cur_find_res, '\0', SIZEOF(find_result_t));
+           cur_find_res->timestamp = stralloc(cur_file->datestamp);
            cur_find_res->hostname = stralloc(cur_file->name);
            cur_find_res->diskname = stralloc(cur_file->disk);
            cur_find_res->level = cur_file->dumplevel;
            if(cur_file->partnum < 1) cur_find_res->partnum = stralloc("--");
            else{
                char part_str[NUM_STR_SIZE];
-               snprintf(part_str, sizeof(part_str), "%d", cur_file->partnum);
+               snprintf(part_str, SIZEOF(part_str), "%d", cur_file->partnum);
                cur_find_res->partnum = stralloc(part_str);
            }
            cur_find_res->user_ptr = (void*)cur_out;
@@ -390,31 +449,41 @@ dumpfile_t *only_file;
                /* is it a continuation of one we've been writing? */
                if(main_file && cur_file->partnum > lastpartnum &&
                        headers_equal(cur_file, main_file, 1)){
+                   char *cur_filename;
+                   char *main_filename;
 
                    /* effectively changing filehandles */
                    aclose(cur_out->outfd);
                    cur_out->outfd = outfd;
 
+                   cur_filename  = make_filename(cur_file);
+                   main_filename = make_filename(main_file);
                    fprintf(stderr, "Merging %s with %s\n",
-                           make_filename(cur_file), make_filename(main_file));
-                   append_file_to_fd(make_filename(cur_file), outfd);
-                   if(unlink(make_filename(cur_file)) < 0){
+                           cur_filename, main_filename);
+                   append_file_to_fd(cur_filename, outfd);
+                   if(unlink(cur_filename) < 0){
                        fprintf(stderr, "Failed to unlink %s: %s\n",
-                                    make_filename(cur_file), strerror(errno));
+                                    cur_filename, strerror(errno));
                    }
+                   amfree(cur_filename);
+                   amfree(main_filename);
                }
                /* or a new file? */
-               else{
+               else {
                    if(outfd >= 0) aclose(outfd);
-                   if(main_file) amfree(main_file);
-                   main_file = alloc(sizeof(dumpfile_t));
-                   memcpy(main_file, cur_file, sizeof(dumpfile_t));
+                   amfree(main_file);
+                   main_file = alloc(SIZEOF(dumpfile_t));
+                   memcpy(main_file, cur_file, SIZEOF(dumpfile_t));
                    outfd = cur_out->outfd;
-                   if(outfd < 0){
-                       if((outfd = open(make_filename(cur_file), O_RDWR|O_APPEND)) < 0){
-                         error("Couldn't open %s for appending: %s\n",
-                               make_filename(cur_file), strerror(errno));
+                   if(outfd < 0) {
+                       char *cur_filename = make_filename(cur_file);
+                       open(cur_filename, O_RDWR|O_APPEND);
+                       if (outfd < 0) {
+                         error("Couldn't open %s for appending: %s",
+                               cur_filename, strerror(errno));
+                         /*NOTREACHED*/
                        }
+                       amfree(cur_filename);
                    }
                }
                lastpartnum = cur_file->partnum;
@@ -437,7 +506,7 @@ dumpfile_t *only_file;
      */
     for(cur_out=open_outputs; cur_out; cur_out=cur_out->next){
        dumpfile_t *cur_file = NULL;
-       if(prev) amfree(prev);
+       amfree(prev);
        cur_file = cur_out->file;
        /* if we requested a particular file, do only that one */
        if(only_file && !headers_equal(cur_file, only_file, 1)){
@@ -460,8 +529,9 @@ dumpfile_t *only_file;
 /*
  * Turn a fileheader into a string suited for use on the filesystem.
  */
-char *make_filename(file)
-dumpfile_t *file;
+char *
+make_filename(
+    dumpfile_t *file)
 {
     char number[NUM_STR_SIZE];
     char part[NUM_STR_SIZE];
@@ -469,23 +539,23 @@ dumpfile_t *file;
     char *sfn = NULL;
     char *fn = NULL;
     char *pad = NULL;
-    int padlen = 0;
+    size_t padlen = 0;
 
-    snprintf(number, sizeof(number), "%d", file->dumplevel);
-    snprintf(part, sizeof(part), "%d", file->partnum);
+    snprintf(number, SIZEOF(number), "%d", file->dumplevel);
+    snprintf(part, SIZEOF(part), "%d", file->partnum);
 
-    if(file->totalparts < 0){
-       snprintf(totalparts, sizeof(totalparts), "UNKNOWN");
+    if(file->totalparts < 0) {
+       snprintf(totalparts, SIZEOF(totalparts), "UNKNOWN");
     }
-    else{
-       snprintf(totalparts, sizeof(totalparts), "%d", file->totalparts);
+    else {
+       snprintf(totalparts, SIZEOF(totalparts), "%d", file->totalparts);
     }
     padlen = strlen(totalparts) + 1 - strlen(part);
     pad = alloc(padlen);
     memset(pad, '0', padlen);
     pad[padlen - 1] = '\0';
 
-    snprintf(part, sizeof(part), "%s%d", pad, file->partnum);
+    snprintf(part, SIZEOF(part), "%s%d", pad, file->partnum);
 
     sfn = sanitise_filename(file->disk);
     fn = vstralloc(file->name,
@@ -496,8 +566,8 @@ dumpfile_t *file;
                   ".",
                   number,
                   NULL);
-    if(file->partnum > 0){
-       fn = vstralloc(fn, ".", part, NULL);
+    if (file->partnum > 0) {
+       vstrextend(&fn, ".", part, NULL);
     }
     amfree(sfn);
     amfree(pad);
@@ -506,12 +576,15 @@ dumpfile_t *file;
 
 
 /*
-XXX Making this thing a lib functiong broke a lot of assumptions everywhere,
-but I think I've found them all.  Maybe.  Damn globals all over the place.
-*/
-static ssize_t get_block(tapefd, buffer, isafile)
-int tapefd, isafile;
-char *buffer;
+ * XXX Making this thing a lib functiong broke a lot of assumptions everywhere,
+ * but I think I've found them all.  Maybe.  Damn globals all over the place.
+ */
+
+static ssize_t
+get_block(
+    int                tapefd,
+    char *     buffer,
+    int        isafile)
 {
     if(isafile)
        return (fullread(tapefd, buffer, blocksize));
@@ -519,18 +592,23 @@ char *buffer;
     return(tapefd_read(tapefd, buffer, blocksize));
 }
 
-int disk_match(file, datestamp, hostname, diskname, level)
-dumpfile_t *file;
-char *datestamp, *hostname, *diskname, *level;
 /*
  * Returns 1 if the current dump file matches the hostname and diskname
  * regular expressions given on the command line, 0 otherwise.  As a 
  * special case, empty regexs are considered equivalent to ".*": they 
  * match everything.
  */
+
+int
+disk_match(
+    dumpfile_t *file,
+    char *     datestamp,
+    char *     hostname,
+    char *     diskname,
+    char *     level)
 {
     char level_str[NUM_STR_SIZE];
-    snprintf(level_str, sizeof(level_str), "%d", file->dumplevel);
+    snprintf(level_str, SIZEOF(level_str), "%d", file->dumplevel);
 
     if(file->type != F_DUMPFILE && file->type != F_SPLIT_DUMPFILE) return 0;
 
@@ -544,55 +622,58 @@ char *datestamp, *hostname, *diskname, *level;
 }
 
 
-void read_file_header(file, tapefd, isafile, flags)
-dumpfile_t *file;
-int tapefd;
-int isafile;
-rst_flags_t *flags;
 /*
  * Reads the first block of a tape file.
  */
+
+ssize_t
+read_file_header(
+    dumpfile_t *       file,
+    int                        tapefd,
+    int                        isafile,
+    rst_flags_t *      flags)
 {
     ssize_t bytes_read;
     char *buffer;
   
     if(flags->blocksize > 0)
-       blocksize = flags->blocksize;
-    else if(blocksize == -1)
+       blocksize = (size_t)flags->blocksize;
+    else if(blocksize == (size_t)SSIZE_MAX)
        blocksize = DISK_BLOCK_BYTES;
     buffer = alloc(blocksize);
 
     bytes_read = get_block(tapefd, buffer, isafile);
     if(bytes_read < 0) {
-       error("error reading file header: %s", strerror(errno));
-       /* NOTREACHED */
-    }
-
-    if(bytes_read < blocksize) {
+       fprintf(stderr, "%s: error reading file header: %s\n",
+               get_pname(), strerror(errno));
+       file->type = F_UNKNOWN;
+    } else if((size_t)bytes_read < blocksize) {
        if(bytes_read == 0) {
            fprintf(stderr, "%s: missing file header block\n", get_pname());
        } else {
-           fprintf(stderr, "%s: short file header block: " AM64_FMT " byte%s\n",
-                   get_pname(), (am64_t)bytes_read, (bytes_read == 1) ? "" : "s");
+           fprintf(stderr, "%s: short file header block: " OFF_T_FMT " byte%s\n",
+                   get_pname(), (OFF_T_FMT_TYPE)bytes_read, (bytes_read == 1) ? "" : "s");
        }
        file->type = F_UNKNOWN;
     } else {
-       parse_file_header(buffer, file, bytes_read);
+       parse_file_header(buffer, file, (size_t)bytes_read);
     }
     amfree(buffer);
+    return bytes_read;
 }
 
 
-void drain_file(tapefd, flags)
-int tapefd;
-rst_flags_t *flags;
+void
+drain_file(
+    int                        tapefd,
+    rst_flags_t *      flags)
 {
     ssize_t bytes_read;
     char *buffer;
 
     if(flags->blocksize)
-       blocksize = flags->blocksize;
-    else if(blocksize == -1)
+       blocksize = (size_t)flags->blocksize;
+    else if(blocksize == (size_t)SSIZE_MAX)
        blocksize = DISK_BLOCK_BYTES;
     buffer = alloc(blocksize);
 
@@ -600,18 +681,13 @@ rst_flags_t *flags;
        bytes_read = get_block(tapefd, buffer, 0);
        if(bytes_read < 0) {
            error("drain read error: %s", strerror(errno));
+          /*NOTREACHED*/
        }
     } while (bytes_read > 0);
 
     amfree(buffer);
 }
 
-ssize_t restore(file, filename, tapefd, isafile, flags)
-dumpfile_t *file;
-char *filename;
-int tapefd;
-int isafile;
-rst_flags_t *flags;
 /*
  * Restore the current file from tape.  Depending on the settings of
  * the command line flags, the file might need to be compressed or
@@ -620,6 +696,14 @@ rst_flags_t *flags;
  * but with the -p flag the output goes to stdout (and presumably is
  * piped to restore).
  */
+
+ssize_t
+restore(
+    dumpfile_t *       file,
+    char *             filename,
+    int                        tapefd,
+    int                        isafile,
+    rst_flags_t *      flags)
 {
     int dest = -1, out;
     ssize_t s;
@@ -638,21 +722,24 @@ rst_flags_t *flags;
         int    pipe[2];
     } pipes[3];
 
+    memset(pipes, -1, SIZEOF(pipes));
     if(flags->blocksize)
-       blocksize = flags->blocksize;
-    else if(blocksize == -1)
+       blocksize = (size_t)flags->blocksize;
+    else if(blocksize == (size_t)SSIZE_MAX)
        blocksize = DISK_BLOCK_BYTES;
 
     if(already_have_dump(file)){
-       fprintf(stderr, " *** Duplicate file %s, one is probably an aborted write\n", make_filename(file));
+       char *filename = make_filename(file);
+       fprintf(stderr, " *** Duplicate file %s, one is probably an aborted write\n", filename);
+       amfree(filename);
        check_for_aborted = 1;
     }
 
     /* store a shorthand record of this dump */
-    tempdump = alloc(sizeof(dumplist_t));
-    tempdump->file = alloc(sizeof(dumpfile_t));
+    tempdump = alloc(SIZEOF(dumplist_t));
+    tempdump->file = alloc(SIZEOF(dumpfile_t));
     tempdump->next = NULL;
-    memcpy(tempdump->file, file, sizeof(dumpfile_t));
+    memcpy(tempdump->file, file, SIZEOF(dumpfile_t));
 
     /*
      * If we're appending chunked files to one another, and if this is a
@@ -679,19 +766,22 @@ rst_flags_t *flags;
            flags->leave_comp = 1;
        }
        if(myout == NULL){
-           myout = alloc(sizeof(open_output_t));
-           memset(myout, 0, sizeof(open_output_t));
+           myout = alloc(SIZEOF(open_output_t));
+           memset(myout, 0, SIZEOF(open_output_t));
        }
     }
     else{
-      myout = alloc(sizeof(open_output_t));
-      memset(myout, 0, sizeof(open_output_t));
+      myout = alloc(SIZEOF(open_output_t));
+      memset(myout, 0, SIZEOF(open_output_t));
     }
 
 
     if(is_continuation && flags->pipe_to_fd == -1){
+       char *filename;
+       filename = make_filename(myout->file);
        fprintf(stderr, "%s:      appending to %s\n", get_pname(),
-                   make_filename(myout->file));
+               filename);
+       amfree(filename);
     }
 
     /* adjust compression flag */
@@ -731,10 +821,11 @@ rst_flags_t *flags;
          } 
          final_filename = stralloc(tmp_filename); 
          tmp_filename = newvstralloc(tmp_filename, ".tmp", NULL);
-         if((dest = creat(tmp_filename, CREAT_MODE)) < 0) {
+         if((dest = open(tmp_filename, (O_CREAT | O_RDWR | O_TRUNC),
+                         CREAT_MODE)) < 0) {
              error("could not create output file %s: %s",
-                                              tmp_filename, strerror(errno));
-             /*NOTREACHED*/
+                   tmp_filename, strerror(errno));
+              /*NOTREACHED*/
          }
          amfree(filename_ext);
       }
@@ -750,13 +841,12 @@ rst_flags_t *flags;
      * it has a fixed size.
      */
     if(flags->raw || (flags->headers && !is_continuation)) {
-       int w;
-       char *cont_filename;
+       ssize_t w;
        dumpfile_t tmp_hdr;
 
        if(flags->compress && !file_is_compressed) {
            file->compressed = 1;
-           snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+           snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd),
                        " %s %s |", UNCOMPRESS_PATH,
 #ifdef UNCOMPRESS_OPT
                        UNCOMPRESS_OPT
@@ -766,15 +856,14 @@ rst_flags_t *flags;
                        );
            strncpy(file->comp_suffix,
                    COMPRESS_SUFFIX,
-                   sizeof(file->comp_suffix)-1);
-           file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+                   SIZEOF(file->comp_suffix)-1);
+           file->comp_suffix[SIZEOF(file->comp_suffix)-1] = '\0';
        }
 
-       memcpy(&tmp_hdr, file, sizeof(dumpfile_t));
+       memcpy(&tmp_hdr, file, SIZEOF(dumpfile_t));
 
        /* remove CONT_FILENAME from header */
-       cont_filename = stralloc(file->cont_filename);
-       memset(file->cont_filename,'\0',sizeof(file->cont_filename));
+       memset(file->cont_filename,'\0',SIZEOF(file->cont_filename));
        file->blocksize = DISK_BLOCK_BYTES;
 
        /*
@@ -791,17 +880,15 @@ rst_flags_t *flags;
        if((w = fullwrite(out, buffer, DISK_BLOCK_BYTES)) != DISK_BLOCK_BYTES) {
            if(w < 0) {
                error("write error: %s", strerror(errno));
+               /*NOTREACHED*/
            } else {
                error("write error: %d instead of %d", w, DISK_BLOCK_BYTES);
+               /*NOTREACHED*/
            }
        }
        amfree(buffer);
-       /* add CONT_FILENAME to header */
-#if 0
-//     strncpy(file->cont_filename, cont_filename, sizeof(file->cont_filename));
-#endif
-       amfree(cont_filename);
-       memcpy(file, &tmp_hdr, sizeof(dumpfile_t));
+
+       memcpy(file, &tmp_hdr, SIZEOF(dumpfile_t));
     }
  
     /* find out if compression or uncompression is needed here */
@@ -821,14 +908,18 @@ rst_flags_t *flags;
     /* Setup pipes for decryption / compression / uncompression  */
     stage = 0;
     if (need_decrypt) {
-      if (pipe(&pipes[stage].pipe[0]) < 0) 
+      if (pipe(&pipes[stage].pipe[0]) < 0) {
         error("error [pipe[%d]: %s]", stage, strerror(errno));
+       /*NOTREACHED*/
+      }
       stage++;
     }
 
     if (need_compress || need_uncompress) {
-      if (pipe(&pipes[stage].pipe[0]) < 0) 
+      if (pipe(&pipes[stage].pipe[0]) < 0) {
         error("error [pipe[%d]: %s]", stage, strerror(errno));
+       /*NOTREACHED*/
+      }
       stage++;
     }
     pipes[stage].pipe[0] = -1; 
@@ -841,29 +932,38 @@ rst_flags_t *flags;
       switch(myout->comp_enc_pid = fork()) {
       case -1:
        error("could not fork for decrypt: %s", strerror(errno));
+       /*NOTREACHED*/
+
       default:
        aclose(pipes[stage].pipe[0]);
        aclose(pipes[stage+1].pipe[1]);
         stage++;
        break;
+
       case 0:
-       if(dup2(pipes[stage].pipe[0], 0) == -1)
+       if(dup2(pipes[stage].pipe[0], 0) == -1) {
            error("error decrypt stdin [dup2 %d %d: %s]", stage,
                pipes[stage].pipe[0], strerror(errno));
+               /*NOTREACHED*/
+       }
 
-       if(dup2(pipes[stage+1].pipe[1], 1) == -1)
+       if(dup2(pipes[stage+1].pipe[1], 1) == -1) {
            error("error decrypt stdout [dup2 %d %d: %s]", stage + 1,
                pipes[stage+1].pipe[1], strerror(errno));
+               /*NOTREACHED*/
+       }
 
        safe_fd(-1, 0);
        if (*file->srv_encrypt) {
          (void) execlp(file->srv_encrypt, file->srv_encrypt,
-                       file->srv_decrypt_opt, NULL);
+                       file->srv_decrypt_opt, (char *)NULL);
          error("could not exec %s: %s", file->srv_encrypt, strerror(errno));
+         /*NOTREACHED*/
        }  else if (*file->clnt_encrypt) {
          (void) execlp(file->clnt_encrypt, file->clnt_encrypt,
-                       file->clnt_decrypt_opt, NULL);
+                       file->clnt_decrypt_opt, (char *)NULL);
          error("could not exec %s: %s", file->clnt_encrypt, strerror(errno));
+         /*NOTREACHED*/
        }
       }
     }
@@ -873,22 +973,28 @@ rst_flags_t *flags;
          * Insert a compress pipe
          */
        switch(myout->comp_enc_pid = fork()) {
-       case -1: error("could not fork for %s: %s",
-                      COMPRESS_PATH, strerror(errno));
+       case -1:
+           error("could not fork for %s: %s", COMPRESS_PATH, strerror(errno));
+           /*NOTREACHED*/
+
        default:
            aclose(pipes[stage].pipe[0]);
            aclose(pipes[stage+1].pipe[1]);
             stage++;
            break;
+
        case 0:
-           if(dup2(pipes[stage].pipe[0], 0) == -1)
+           if(dup2(pipes[stage].pipe[0], 0) == -1) {
                error("error compress stdin [dup2 %d %d: %s]", stage,
                  pipes[stage].pipe[0], strerror(errno));
+               /*NOTREACHED*/
+           }
 
-           if(dup2(pipes[stage+1].pipe[1], 1) == -1)
+           if(dup2(pipes[stage+1].pipe[1], 1) == -1) {
                error("error compress stdout [dup2 %d %d: %s]", stage + 1,
                  pipes[stage+1].pipe[1], strerror(errno));
-
+                 /*NOTREACHED*/
+           }
            if (*flags->comp_type == '\0') {
                flags->comp_type = NULL;
            }
@@ -896,6 +1002,7 @@ rst_flags_t *flags;
            safe_fd(-1, 0);
            (void) execlp(COMPRESS_PATH, COMPRESS_PATH, flags->comp_type, (char *)0);
            error("could not exec %s: %s", COMPRESS_PATH, strerror(errno));
+           /*NOTREACHED*/
        }
     } else if(need_uncompress) {
         /*
@@ -913,42 +1020,56 @@ rst_flags_t *flags;
        case -1: 
            error("could not fork for %s: %s",
                  UNCOMPRESS_PATH, strerror(errno));
+           /*NOTREACHED*/
+
        default:
            aclose(pipes[stage].pipe[0]);
            aclose(pipes[stage+1].pipe[1]);
             stage++;
            break;
+
        case 0:
-           if(dup2(pipes[stage].pipe[0], 0) == -1)
+           if(dup2(pipes[stage].pipe[0], 0) == -1) {
                error("error uncompress stdin [dup2 %d %d: %s]", stage,
                  pipes[stage].pipe[0], strerror(errno));
+               /*NOTREACHED*/
+           }
 
-           if(dup2(pipes[stage+1].pipe[1], 1) == -1)
+           if(dup2(pipes[stage+1].pipe[1], 1) == -1) {
                error("error uncompress stdout [dup2 %d %d: %s]", stage + 1,
                  pipes[stage+1].pipe[1], strerror(errno));
+               /*NOTREACHED*/
+           }
 
            safe_fd(-1, 0);
            if (*file->srvcompprog) {
-             (void) execlp(file->srvcompprog, file->srvcompprog, "-d", NULL);
-             error("could not exec %s: %s", file->srvcompprog, strerror(errno));
+             (void) execlp(file->srvcompprog, file->srvcompprog, "-d",
+                           (char *)NULL);
+             error("could not exec %s: %s", file->srvcompprog,
+                   strerror(errno));
+             /*NOTREACHED*/
            } else if (*file->clntcompprog) {
-             (void) execlp(file->clntcompprog, file->clntcompprog, "-d", NULL);
-             error("could not exec %s: %s", file->clntcompprog, strerror(errno));
+             (void) execlp(file->clntcompprog, file->clntcompprog, "-d",
+                           (char *)NULL);
+             error("could not exec %s: %s", file->clntcompprog,
+                   strerror(errno));
+             /*NOTREACHED*/
            } else {
              (void) execlp(UNCOMPRESS_PATH, UNCOMPRESS_PATH,
 #ifdef UNCOMPRESS_OPT
                          UNCOMPRESS_OPT,
 #endif
-                         (char *)0);
+                         (char *)NULL);
              error("could not exec %s: %s", UNCOMPRESS_PATH, strerror(errno));
+             /*NOTREACHED*/
            }
        }
     }
 
     /* copy the rest of the file from tape to the output */
     if(flags->blocksize > 0)
-       blocksize = flags->blocksize;
-    else if(blocksize == -1)
+       blocksize = (size_t)flags->blocksize;
+    else if(blocksize == SIZE_MAX)
        blocksize = DISK_BLOCK_BYTES;
     buffer = alloc(blocksize);
 
@@ -956,11 +1077,11 @@ rst_flags_t *flags;
        bytes_read = get_block(tapefd, buffer, isafile);
        if(bytes_read < 0) {
            error("restore read error: %s", strerror(errno));
-           /* NOTREACHED */
+           /*NOTREACHED*/
        }
 
        if(bytes_read > 0) {
-           if((s = fullwrite(pipes[0].pipe[1], buffer, bytes_read)) < 0) {
+           if((s = fullwrite(pipes[0].pipe[1], buffer, (size_t)bytes_read)) < 0) {
                if ((errno == EPIPE) || (errno == ECONNRESET)) {
                    /*
                     * reading program has ended early
@@ -969,8 +1090,12 @@ rst_flags_t *flags;
                     */
                    break;
                }
-               perror("restore: write error");
-               exit(2);
+               error("restore: write error: %s", strerror(errno));
+               /* NOTREACHED */
+           } else if (s < bytes_read) {
+               error("restore: wrote %d of %d bytes: %s",
+                   s, bytes_read, strerror(errno));
+               /* NOTREACHED */
            }
        }
        else if(isafile) {
@@ -988,6 +1113,7 @@ rst_flags_t *flags;
                    if((tapefd = open(cont_filename,O_RDONLY)) == -1) {
                        error("can't open %s: %s", file->cont_filename,
                              strerror(errno));
+                       /*NOTREACHED*/
                    }
                    else {
                        fprintf(stderr, "cannot open %s: %s\n",
@@ -999,9 +1125,10 @@ rst_flags_t *flags;
                else {
                    error("can't open %s: %s", file->cont_filename,
                          strerror(errno));
+                   /*NOTREACHED*/
                }
            }
-           read_file_header(file, tapefd, isafile, flags);
+           bytes_read = read_file_header(file, tapefd, isafile, flags);
            if(file->type != F_DUMPFILE && file->type != F_CONT_DUMPFILE
                    && file->type != F_SPLIT_DUMPFILE) {
                fprintf(stderr, "unexpected header type: ");
@@ -1019,9 +1146,12 @@ rst_flags_t *flags;
     }
     if(!is_continuation){
        if(tmp_filename && stat(tmp_filename, &statinfo) < 0){
-           error("Can't stat the file I just created (%s)!\n", tmp_filename);
+           error("Can't stat the file I just created (%s)!", tmp_filename);
+           /*NOTREACHED*/
+       } else {
+           statinfo.st_size = (off_t)0;
        }
-       if(check_for_aborted){
+       if (check_for_aborted && final_filename) {
            char *old_dump = final_filename;
            struct stat oldstat;
            if(stat(old_dump, &oldstat) >= 0){
@@ -1063,7 +1193,8 @@ rst_flags_t *flags;
                }
                else{
                    fprintf(stderr, "Older restore is larger, using that\n");
-                   unlink(tmp_filename);
+                   if (tmp_filename)
+                       unlink(tmp_filename);
                    amfree(tempdump->file);
                    amfree(tempdump);
                    amfree(tmp_filename);
@@ -1073,13 +1204,14 @@ rst_flags_t *flags;
            }
        }
        if(tmp_filename && final_filename &&
-               rename(tmp_filename, final_filename) < 0){
-           error("Can't rename %s to %s: %s\n", tmp_filename, final_filename,
-                                            strerror(errno));
+               rename(tmp_filename, final_filename) < 0) {
+           error("Can't rename %s to %s: %s",
+                  tmp_filename, final_filename, strerror(errno));
+           /*NOTREACHED*/
        }
     }
-    if(tmp_filename) amfree(tmp_filename);
-    if(final_filename) amfree(final_filename);
+    amfree(tmp_filename);
+    amfree(final_filename);
 
 
     /*
@@ -1087,9 +1219,9 @@ rst_flags_t *flags;
      * structures (we waited in case we needed to give up)
      */
     if(!is_continuation){
-        oldout = alloc(sizeof(open_output_t));
-        oldout->file = alloc(sizeof(dumpfile_t));
-        memcpy(oldout->file, file, sizeof(dumpfile_t));
+        oldout = alloc(SIZEOF(open_output_t));
+        oldout->file = alloc(SIZEOF(dumpfile_t));
+        memcpy(oldout->file, file, SIZEOF(dumpfile_t));
         if(flags->inline_assemble) oldout->outfd = pipes[0].pipe[1];
        else oldout->outfd = -1;
         oldout->comp_enc_pid = -1;
@@ -1098,7 +1230,9 @@ rst_flags_t *flags;
         open_outputs = oldout;
     }
     if(alldumps_list){
-       for(fileentry=alldumps_list;fileentry->next;fileentry=fileentry->next);
+       fileentry = alldumps_list;
+       while (fileentry->next != NULL)
+           fileentry=fileentry->next;
        fileentry->next = tempdump;
     }
     else {
@@ -1108,7 +1242,424 @@ rst_flags_t *flags;
     return (bytes_read);
 }
 
+/* return NULL if the label is not the expected one                     */
+/* return the label if it is the expected one, and set *tapefd to a     */
+/* file descriptor to the tapedev                                       */
+char *
+label_of_current_slot(
+    char         *cur_tapedev,
+    FILE         *prompt_out,
+    int          *tapefd,
+    dumpfile_t   *file,
+    rst_flags_t  *flags,
+    am_feature_t *their_features,
+    ssize_t      *read_result,
+    tapelist_t   *desired_tape)
+{
+    struct stat stat_tape;
+    char *label = NULL;
+    int wrongtape = 0;
+    char *err;
 
+    if (!cur_tapedev) {
+       send_message(prompt_out, flags, their_features,
+                    "no tapedev specified");
+    } else if (tape_stat(cur_tapedev, &stat_tape) !=0 ) {
+       send_message(prompt_out, flags, their_features, 
+                    "could not stat '%s': %s",
+                    cur_tapedev, strerror(errno));
+       wrongtape = 1;
+    } else if((err = tape_rewind(cur_tapedev)) != NULL) {
+       send_message(prompt_out, flags, their_features, 
+                        "Could not rewind device '%s': %s",
+                        cur_tapedev, err);
+       wrongtape = 1;
+       /* err should not be freed */
+    } else if((*tapefd = tape_open(cur_tapedev, 0)) < 0){
+       send_message(prompt_out, flags, their_features,
+                        "could not open tape device %s: %s",
+                        cur_tapedev, strerror(errno));
+       wrongtape = 1;
+    }
+
+    if (!wrongtape) {
+       *read_result = read_file_header(file, *tapefd, 0, flags);
+       if (file->type != F_TAPESTART) {
+           send_message(prompt_out, flags, their_features,
+                            "Not an amanda tape");
+           tapefd_close(*tapefd);
+       } else {
+           if (flags->check_labels && desired_tape &&
+                        strcmp(file->name, desired_tape->label) != 0) {
+               send_message(prompt_out, flags, their_features,
+                                "Label mismatch, got %s and expected %s",
+                                file->name, desired_tape->label);
+               tapefd_close(*tapefd);
+           }
+           else {
+               label = stralloc(file->name);
+           }
+       }
+    }
+    return label;
+}
+
+/* return >0            the number of slot move            */
+/* return LOAD_STOP     if the search must be stopped      */
+/* return LOAD_CHANGER  if the changer search the library  */
+int
+load_next_tape(
+    char         **cur_tapedev,
+    FILE          *prompt_out,
+    int            backwards,
+    rst_flags_t   *flags,
+    am_feature_t  *their_features,
+    tapelist_t    *desired_tape)
+{
+    int ret = -1;
+
+    if (desired_tape) {
+       send_message(prompt_out, flags, their_features,
+                    "Looking for tape %s...",
+                    desired_tape->label);
+       if (backwards) {
+           searchlabel = desired_tape->label; 
+           changer_find(NULL, scan_init, loadlabel_slot,
+                        desired_tape->label);
+           ret = LOAD_CHANGER;
+       } else {
+           amfree(curslot);
+           changer_loadslot("next", &curslot,
+                            cur_tapedev);
+           ret = 1;
+       }
+    } else {
+       assert(!flags->amidxtaped);
+       amfree(curslot);
+       changer_loadslot("next", &curslot, cur_tapedev);
+       ret = 1;
+    }
+    return ret;
+}
+
+
+/* return  0     a new tape is loaded       */
+/* return -1     no new tape                */
+int
+load_manual_tape(
+    char         **cur_tapedev,
+    FILE          *prompt_out,
+    rst_flags_t   *flags,
+    am_feature_t  *their_features,
+    tapelist_t    *desired_tape)
+{
+    int ret = 0;
+    char *input = NULL;
+
+    if (flags->amidxtaped) {
+       if (their_features &&
+           am_has_feature(their_features,
+                          fe_amrecover_FEEDME)) {
+           fprintf(prompt_out, "FEEDME %s\r\n",
+                   desired_tape->label);
+           fflush(prompt_out);
+           input = agets(stdin);/* Strips \n but not \r */
+           if(!input) {
+               error("Connection lost with amrecover");
+               /*NOTREACHED*/
+           } else if (strcmp("OK\r", input) == 0) {
+           } else if (strncmp("TAPE ", input, 5) == 0) {
+               amfree(*cur_tapedev);
+               *cur_tapedev = alloc(1025);
+               if (sscanf(input, "TAPE %1024s\r", *cur_tapedev) != 1) {
+                   error("Got bad response from amrecover: %s", input);
+                   /*NOTREACHED*/
+               }
+           } else {
+               send_message(prompt_out, flags, their_features,
+                            "Got bad response from amrecover: %s", input);
+               error("Got bad response from amrecover: %s", input);
+               /*NOTREACHED*/
+           }
+       } else {
+           send_message(prompt_out, flags, their_features,
+                        "Client doesn't support fe_amrecover_FEEDME");
+           error("Client doesn't support fe_amrecover_FEEDME");
+           /*NOTREACHED*/
+       }
+    }
+    else {
+       if (desired_tape) {
+           fprintf(prompt_out,
+                   "Insert tape labeled %s in device %s \n"
+                   "and press enter, ^D to finish reading tapes\n",
+                   desired_tape->label, *cur_tapedev);
+       } else {
+           fprintf(prompt_out,"Insert a tape to search and press "
+                   "enter, ^D to finish reading tapes\n");
+       }
+       fflush(prompt_out);
+       if((input = agets(stdin)) == NULL)
+           ret = -1;
+    }
+
+    amfree(input);
+    return ret;
+}
+
+
+void 
+search_a_tape(
+    char         *cur_tapedev,
+    FILE         *prompt_out,
+    rst_flags_t  *flags,
+    am_feature_t *their_features,
+    tapelist_t   *desired_tape,
+    int           isafile,
+    match_list_t *match_list,
+    seentapes_t  *tape_seen,
+    dumpfile_t   *file,
+    dumpfile_t   *prev_rst_file,
+    dumpfile_t   *tapestart,
+    int           slot_num,
+    ssize_t      *read_result)
+{
+    off_t       filenum;
+    dumplist_t *fileentry = NULL;
+    int         tapefile_idx = -1;
+    int         i;
+    char       *logline = NULL;
+    FILE       *logstream = NULL;
+    off_t       fsf_by;
+
+    filenum = (off_t)0;
+    if(desired_tape && desired_tape->numfiles > 0)
+       tapefile_idx = 0;
+
+    if (desired_tape) {
+       dbprintf(("search_a_tape: desired_tape=%p label=%s\n",
+                 desired_tape, desired_tape->label));
+       dbprintf(("tape:   numfiles = %d\n", desired_tape->numfiles));
+       for (i=0; i < desired_tape->numfiles; i++) {
+           dbprintf(("tape:   files[%d] = " OFF_T_FMT "\n",
+                     i, (OFF_T_FMT_TYPE)desired_tape->files[i]));
+       }
+    } else {
+       dbprintf(("search_a_tape: no desired_tape\n"));
+    }
+    dbprintf(("current tapefile_idx = %d\n", tapefile_idx));
+       
+    /* if we know where we're going, fastforward there */
+    if(flags->fsf && !isafile){
+       /* If we have a tapelist entry, filenums will be store there */
+       if(tapefile_idx >= 0) {
+           fsf_by = desired_tape->files[tapefile_idx]; 
+       } else {
+           /*
+            * older semantics assume we're restoring one file, with the fsf
+            * flag being the filenum on tape for said file
+            */
+           fsf_by = (flags->fsf == 0) ? (off_t)0 : (off_t)1;
+       }
+       if(fsf_by > (off_t)0){
+           if(tapefd_rewind(tapefd) < 0) {
+               send_message(prompt_out, flags, their_features,
+                            "Could not rewind device %s: %s",
+                            cur_tapedev, strerror(errno));
+               error("Could not rewind device %s: %s",
+                     cur_tapedev, strerror(errno));
+               /*NOTREACHED*/
+           }
+
+           if(tapefd_fsf(tapefd, fsf_by) < 0) {
+               send_message(prompt_out, flags, their_features,
+                            "Could not fsf device %s by " OFF_T_FMT ": %s",
+                            cur_tapedev, (OFF_T_FMT_TYPE)fsf_by,
+                            strerror(errno));
+               error("Could not fsf device %s by " OFF_T_FMT ": %s",
+                     cur_tapedev, (OFF_T_FMT_TYPE)fsf_by,
+                     strerror(errno));
+               /*NOTREACHED*/
+           }
+           else {
+               filenum = fsf_by;
+           }
+           *read_result = read_file_header(file, tapefd, isafile, flags);
+       }
+    }
+
+    while((file->type == F_TAPESTART || file->type == F_DUMPFILE ||
+          file->type == F_SPLIT_DUMPFILE) &&
+         (tapefile_idx < 0 || tapefile_idx < desired_tape->numfiles)) {
+       int found_match = 0;
+       match_list_t *me;
+       dumplist_t *tempdump = NULL;
+
+       /* store record of this dump for inventorying purposes */
+       tempdump = alloc(SIZEOF(dumplist_t));
+       tempdump->file = alloc(SIZEOF(dumpfile_t));
+       tempdump->next = NULL;
+       memcpy(tempdump->file, &file, SIZEOF(dumpfile_t));
+       if(tape_seen->files){
+           fileentry = tape_seen->files;
+           while (fileentry->next != NULL)
+                  fileentry = fileentry->next;
+           fileentry->next = tempdump;
+       }
+       else {
+           tape_seen->files = tempdump;
+       }
+
+       /* see if we need to restore the thing */
+       if(isafile)
+           found_match = 1;
+       else if(tapefile_idx >= 0){ /* do it by explicit file #s */
+           if(filenum == desired_tape->files[tapefile_idx]){
+               found_match = 1;
+               tapefile_idx++;
+           }
+       }
+       else{ /* search and match headers */
+           for(me = match_list; me; me = me->next) {
+               if(disk_match(file, me->datestamp, me->hostname,
+                             me->diskname, me->level) != 0){
+                   found_match = 1;
+                   break;
+               }
+           }
+       }
+
+       if(found_match){
+           char *filename = make_filename(file);
+
+           fprintf(stderr, "%s: " OFF_T_FMT ": restoring ",
+                   get_pname(), (OFF_T_FMT_TYPE)filenum);
+           print_header(stderr, file);
+           *read_result = restore(file, filename, tapefd, isafile, flags);
+           filenum++;
+           amfree(filename);
+       }
+
+       /* advance to the next file, fast-forwarding where reasonable */
+       if (!isafile) {
+           if (*read_result == 0) {
+               tapefd_close(tapefd);
+               if((tapefd = tape_open(cur_tapedev, 0)) < 0) {
+                   send_message(prompt_out, flags, their_features,
+                                "could not open %s: %s",
+                                cur_tapedev, strerror(errno));
+                   error("could not open %s: %s",
+                         cur_tapedev, strerror(errno));
+                   /*NOTREACHED*/
+               }
+           /* if the file is not what we're looking for fsf to next one */
+           }
+           else if (!found_match) {
+               if (tapefd_fsf(tapefd, (off_t)1) < 0) {
+                   send_message(prompt_out, flags, their_features,
+                                "Could not fsf device %s: %s",
+                                cur_tapedev, strerror(errno));
+                   error("Could not fsf device %s: %s",
+                         cur_tapedev, strerror(errno));
+                   /*NOTREACHED*/
+               }
+               filenum ++;
+           }
+           else if (flags->fsf && (tapefile_idx >= 0) && 
+                    (tapefile_idx < desired_tape->numfiles)) {
+               fsf_by = desired_tape->files[tapefile_idx] - filenum;
+               if (fsf_by > (off_t)0) {
+                   if(tapefd_fsf(tapefd, fsf_by) < 0) {
+                       send_message(prompt_out, flags, their_features,
+                                    "Could not fsf device %s by "
+                                    OFF_T_FMT ": %s",
+                                    cur_tapedev, (OFF_T_FMT_TYPE)fsf_by,
+                                    strerror(errno));
+                       error("Could not fsf device %s by " OFF_T_FMT ": %s",
+                             cur_tapedev, (OFF_T_FMT_TYPE)fsf_by,
+                             strerror(errno));
+                       /*NOTREACHED*/
+                   }
+                   filenum = desired_tape->files[tapefile_idx];
+               }
+           }
+       } /* !isafile */
+
+       memcpy(prev_rst_file, file, SIZEOF(dumpfile_t));
+             
+       if(isafile)
+           break;
+        *read_result = read_file_header(file, tapefd, isafile, flags);
+
+       /* only restore a single dump, if piping to stdout */
+       if (!headers_equal(prev_rst_file, file, 1) &&
+           (flags->pipe_to_fd == fileno(stdout)) && found_match) {
+           break;
+       }
+    } /* while we keep seeing headers */
+
+    if (!isafile) {
+       if (file->type == F_EMPTY) {
+           aclose(tapefd);
+           if((tapefd = tape_open(cur_tapedev, 0)) < 0) {
+               send_message(prompt_out, flags, their_features,
+                            "could not open %s: %s",
+                            cur_tapedev, strerror(errno));
+               error("could not open %s: %s",
+                     cur_tapedev, strerror(errno));
+               /*NOTREACHED*/
+           }
+       } else {
+           if (tapefd_fsf(tapefd, (off_t)1) < 0) {
+               send_message(prompt_out, flags, their_features,
+                            "could not fsf %s: %s",
+                            cur_tapedev, strerror(errno));;
+               error("could not fsf %s: %s",
+                     cur_tapedev, strerror(errno));
+               /*NOTREACHED*/
+           }
+       }
+    }
+    tapefd_close(tapefd);
+
+    /* spit out our accumulated list of dumps, if we're inventorying */
+    if (logstream) {
+       logline = log_genstring(L_START, "taper",
+                                   "datestamp %s label %s tape %d",
+                                   tapestart->datestamp, tapestart->name,
+                                   slot_num);
+       fprintf(logstream, "%s", logline);
+       for(fileentry=tape_seen->files; fileentry; fileentry=fileentry->next){
+           logline = NULL;
+           switch (fileentry->file->type) {
+               case F_DUMPFILE:
+                   logline = log_genstring(L_SUCCESS, "taper",
+                                      "%s %s %s %d [faked log entry]",
+                                      fileentry->file->name,
+                                      fileentry->file->disk,
+                                      fileentry->file->datestamp,
+                                      fileentry->file->dumplevel);
+                   break;
+               case F_SPLIT_DUMPFILE:
+                   logline = log_genstring(L_CHUNK, "taper", 
+                                      "%s %s %s %d %d [faked log entry]",
+                                      fileentry->file->name,
+                                      fileentry->file->disk,
+                                      fileentry->file->datestamp,
+                                      fileentry->file->partnum,
+                                      fileentry->file->dumplevel);
+                   break;
+               default:
+                   break;
+            }
+           if(logline){
+               fprintf(logstream, "%s", logline);
+               amfree(logline);
+               fflush(logstream);
+           }
+        }
+    }
+}
 
 /* 
  * Take a pattern of dumps and restore it blind, a la amrestore.  In addition,
@@ -1118,38 +1669,38 @@ rst_flags_t *flags;
  * tapes to search (rather than "everything I can find"), which in turn can
  * optionally list specific files to restore.
  */
-void search_tapes(prompt_out, use_changer, tapelist, match_list, flags, their_features)
-FILE *prompt_out;
-int use_changer;
-tapelist_t *tapelist;
-match_list_t *match_list;
-rst_flags_t *flags;
-am_feature_t *their_features;
+void
+search_tapes(
+    FILE *             prompt_out,
+    int                        use_changer,
+    tapelist_t *       tapelist,
+    match_list_t *     match_list,
+    rst_flags_t *      flags,
+    am_feature_t *     their_features)
 {
-    struct stat stat_tape;
-    char *err;
     int have_changer = 1;
     int slot_num = -1;
     int slots = -1;
-    int filenum;
     FILE *logstream = NULL;
-    dumplist_t *fileentry = NULL;
     tapelist_t *desired_tape = NULL;
     struct sigaction act, oact;
-    int newtape = 1;
-    ssize_t bytes_read = 0;
+    ssize_t read_result;
+    int slot;
+    char *label = NULL;
+    seentapes_t *seentapes = NULL;
+    int ret;
 
-    struct seentapes{
-       struct seentapes *next;
-       char *slotstr;
-       char *label;
-       dumplist_t *files;
-    } *seentapes = NULL;
+    dbprintf(("search_tapes(prompt=%p, use_changer=%d, tapelist=%p, "
+             "match_list=%p, flags=%p, features=%p)\n",
+             prompt_out, use_changer, tapelist, match_list,
+             flags, their_features));
 
     if(!prompt_out) prompt_out = stderr;
 
-    if(flags->blocksize) blocksize = flags->blocksize;
-    else if(blocksize == -1) blocksize = DISK_BLOCK_BYTES;
+    if(flags->blocksize)
+       blocksize = (size_t)flags->blocksize;
+    else if(blocksize == (size_t)SSIZE_MAX)
+       blocksize = DISK_BLOCK_BYTES;
 
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
@@ -1160,16 +1711,18 @@ am_feature_t *their_features;
     act.sa_flags = 0;
     if(sigaction(SIGINT, &act, &oact) != 0){
        error("error setting SIGINT handler: %s", strerror(errno));
+       /*NOTREACHED*/
     }
     if(flags->delay_assemble || flags->inline_assemble) exitassemble = 1;
     else exitassemble = 0;
 
     /* if given a log file, print an inventory of stuff found */
-    if(flags->inventory_log){
+    if(flags->inventory_log) {
        if(!strcmp(flags->inventory_log, "-")) logstream = stdout;
-       else if((logstream = fopen(flags->inventory_log, "w+")) == NULL){
-           error("Couldn't open log file %s for writing: %s\n",
+       else if((logstream = fopen(flags->inventory_log, "w+")) == NULL) {
+           error("Couldn't open log file %s for writing: %s",
                  flags->inventory_log, strerror(errno));
+           /*NOTREACHED*/
        }
     }
 
@@ -1182,8 +1735,10 @@ am_feature_t *their_features;
        have_changer = 0;
     } else if (have_changer != 1) {
        error("changer initialization failed: %s", strerror(errno));
+       /*NOTREACHED*/
     }
     else{ /* good, the changer works, see what it can do */
+       amfree(curslot);
        changer_info(&slots, &curslot, &backwards);
     }
 
@@ -1194,8 +1749,7 @@ am_feature_t *their_features;
        what to load
       */
       fprintf(prompt_out, "The following tapes are needed:");
-      for(desired_tape = tapelist;
-          desired_tape != NULL;
+      for(desired_tape = tapelist; desired_tape != NULL;
          desired_tape = desired_tape->next){
        fprintf(prompt_out, " %s", desired_tape->label);
       }
@@ -1213,6 +1767,11 @@ am_feature_t *their_features;
     }
     desired_tape = tapelist;
 
+    if(use_changer && !cur_tapedev) { /* load current slot */
+       amfree(curslot);
+       changer_loadslot("current", &curslot, &cur_tapedev);
+    }
+
     /*
      * If we're not given a tapelist, iterate over everything our changer can
      * find.  If there's no changer, we'll prompt to be handfed tapes.
@@ -1224,187 +1783,114 @@ am_feature_t *their_features;
      *
      * (obnoxious, isn't this?)
      */
-    slot_num = 0;
-    curslot = stralloc("<none>");
-    while(desired_tape || ((slot_num < slots || !have_changer) && !tapelist)){
-       char *label = NULL;
-       struct seentapes *tape_seen = NULL;
+
+    do { /* all desired tape */
+       seentapes_t *tape_seen = NULL;
        dumpfile_t file, tapestart, prev_rst_file;
-       char *logline = NULL;
-       int tapefile_idx = -1;
-       int wrongtape = 0;
        int isafile = 0;
+       read_result = 0;
 
-       /*
-        * Deal with instances where we're being asked to restore from a file
-        */
-       if(desired_tape && desired_tape->isafile){
+       slot_num = 0;
+
+       memset(&file, 0, SIZEOF(file));
+
+       if (desired_tape && desired_tape->isafile) {
            isafile = 1;
-           if ((tapefd = open(desired_tape->label, 0)) == -1){
-               fprintf(stderr, "could not open %s: %s\n",
-                     desired_tape->label, strerror(errno));
-               continue;
+           if ((tapefd = open(desired_tape->label, 0)) == -1) {
+               send_message(prompt_out, flags, their_features, 
+                            "could not open %s: %s",
+                            desired_tape->label, strerror(errno));
+               continue;
            }
-           fprintf(stderr, "Reading %s to fd %d\n", desired_tape->label, tapefd);
+           fprintf(stderr, "Reading %s to fd %d\n",
+                           desired_tape->label, tapefd);
 
-           read_file_header(&file, tapefd, 1, flags);
+           read_result = read_file_header(&file, tapefd, 1, flags);
            label = stralloc(desired_tape->label);
-       }
-       /*
-        * Make sure we can read whatever tape is loaded, then grab the label.
-        */
-       else if(cur_tapedev && newtape){
-           if(tape_stat(cur_tapedev,&stat_tape)!=0) {
-               error("could not stat %s: %s", cur_tapedev, strerror(errno));
+       } else {
+           /* check current_slot */
+           label = label_of_current_slot(cur_tapedev, prompt_out,
+                                         &tapefd, &file, flags,
+                                         their_features, &read_result,
+                                         desired_tape);
+           while (label==NULL && slot_num < slots &&
+                  use_changer) {
+               /*
+                * If we have an incorrect tape loaded, go try to find
+                * the right one
+                * (or just see what the next available one is).
+                */
+               slot = load_next_tape(&cur_tapedev, prompt_out,
+                                     backwards, flags,
+                                     their_features, desired_tape);
+               if(slot == LOAD_STOP) {
+                   slot_num = slots;
+                   amfree(label);
+               } else {
+                   if (slot == LOAD_CHANGER)
+                       slot_num = slots;
+                   else /* slot > 0 */
+                       slot_num += slot;
+
+                   /* check current_slot */
+                   label = label_of_current_slot(cur_tapedev, prompt_out,
+                                                 &tapefd, &file, flags,
+                                                 their_features, &read_result,
+                                                 desired_tape);
+               }
            }
 
-           if((err = tape_rewind(cur_tapedev)) != NULL) {
-               fprintf(stderr, "Could not rewind device '%s': %s\n",
-                        cur_tapedev, err);
-               wrongtape = 1;
-           }
-           if((tapefd = tape_open(cur_tapedev, 0)) < 0){
-               fprintf(stderr, "could not open tape device %s: %s\n",
-                        cur_tapedev, strerror(errno));
-               wrongtape = 1;
+           if (label == NULL) {
+               ret = load_manual_tape(&cur_tapedev, prompt_out,
+                                      flags,
+                                      their_features, desired_tape);
+               if (ret == 0) {
+                   label = label_of_current_slot(cur_tapedev, prompt_out,
+                                                 &tapefd, &file, flags,
+                                                 their_features, &read_result,
+                                                 desired_tape);
+               }
            }
 
-           if (!wrongtape) {
-               read_file_header(&file, tapefd, 0, flags);
-               if (file.type != F_TAPESTART) {
-                   fprintf(stderr, "Not an amanda tape\n");
-                   tapefd_close(tapefd);
-                   wrongtape = 1;
-               } else {
-                   memcpy(&tapestart, &file, sizeof(dumpfile_t));
-                   label = stralloc(file.name);
-               }
-           }
-       } else if(newtape) {
-         wrongtape = 1; /* nothing loaded */
-         bytes_read = -1;
+           if (label)
+               memcpy(&tapestart, &file, SIZEOF(dumpfile_t));
        }
+       
+       if (!label)
+           continue;
 
        /*
         * Skip this tape if we did it already.  Note that this would let
         * duplicate labels through, so long as they were in the same slot.
         * I'm over it, are you?
         */
-       if(label && newtape && !isafile && !wrongtape){
-           for(tape_seen = seentapes; tape_seen; tape_seen = tape_seen->next){
-               if(!strcmp(tape_seen->label, label) &&
-                       !strcmp(tape_seen->slotstr, curslot)){
-                   fprintf(stderr, "Saw repeat tape %s in slot %s\n", label, curslot);
-                   wrongtape = 1;
+       if (!isafile) {
+           for (tape_seen = seentapes; tape_seen;
+                tape_seen = tape_seen->next) {
+               if (!strcmp(tape_seen->label, label) &&
+                   !strcmp(tape_seen->slotstr, curslot)){
+                   send_message(prompt_out, flags, their_features,
+                                "Saw repeat tape %s in slot %s",
+                                label, curslot);
                    amfree(label);
                    break;
                }
            }
        }
 
-       /*
-        * See if we've got the tape we were looking for, if we were looking
-        * for something specific.
-        */
-       if((desired_tape || !cur_tapedev) && newtape && !isafile && !wrongtape){
-           if(!label || (flags->check_labels &&
-                   desired_tape && strcmp(label, desired_tape->label) != 0)){
-               if(label){
-                   fprintf(stderr, "Label mismatch, got %s and expected %s\n", label, desired_tape->label);
-                   if(have_changer && !backwards){
-                       fprintf(stderr, "Changer can't go backwards, restoring anyway\n");
-                   }
-                   else wrongtape = 1;
-               }
-               else fprintf(stderr, "No tape device initialized yet\n");
-           }
-       }
-           
-
-       /*
-        * If we have an incorrect tape loaded, go try to find the right one
-        * (or just see what the next available one is).
-        */
-       if((wrongtape || !newtape) && !isafile){
-           if(desired_tape){
-               tapefd_close(tapefd);
-               if(have_changer){
-                   fprintf(stderr,"Looking for tape %s...\n", desired_tape->label);
-                   if(backwards){
-                       searchlabel = desired_tape->label; 
-                       changer_find(NULL, scan_init, loadlabel_slot, desired_tape->label);
-                   }
-                   else{
-                       changer_loadslot("next", &curslot, &cur_tapedev);
-                   }
-                   while(have_changer && !cur_tapedev){
-                       fprintf(stderr, "Changer did not set the tape device (slot empty or changer misconfigured?)\n");
-                       changer_loadslot("next", &curslot, &cur_tapedev);
-                   }
-               }
-               else {
-                   char *input = NULL;
-
-                    if (!flags->amidxtaped) {
-                        fprintf(prompt_out,
-                                "Insert tape labeled %s in device %s "
-                                "and press return\n", 
-                                desired_tape->label, cur_tapedev);
-                        fflush(prompt_out);
-                        input = agets(stdin);
-                        amfree(input);
-                    } else if (their_features &&
-                              am_has_feature(their_features,
-                                             fe_amrecover_FEEDME)) {
-                        fprintf(prompt_out, "FEEDME %s\n",
-                                desired_tape->label);
-                        fflush(prompt_out);
-                        input = agets(stdin); /* Strips \n but not \r */
-                        if (strcmp("OK\r", input) != 0) {
-                            error("Got bad response from amrecover: %s",
-                                  input);
-                        }
-                        amfree(input);
-                    } else {
-                        error("Client doesn't support fe_amrecover_FEEDME");
-                   }
-                }
-            }
-           else{
-                assert(!flags->amidxtaped);
-               if(have_changer){
-                   if(slot_num == 0)
-                       changer_loadslot("first", &curslot, &cur_tapedev);
-                   else
-                       changer_loadslot("next", &curslot, &cur_tapedev);
-                   if(have_changer && !cur_tapedev)
-                       error("Changer did not set the tape device, probably misconfigured");
-               }
-               else {
-                   /* XXX need a condition for ending processing? */
-                   char *input = NULL;
-                    fprintf(prompt_out,"Insert a tape to search and press enter, ^D to finish reading tapes\n");
-                   fflush(prompt_out);
-                    if((input = agets(stdin)) == NULL) break;
-                   amfree(input);
-               }
-           }
-           newtape = 1;
-           amfree(label);
+       if(!label)
            continue;
-       }
 
-       newtape = 0;
-
-       slot_num++;
+       if(!curslot)
+           curslot = stralloc("<none>");
 
        if(!isafile){
            fprintf(stderr, "Scanning %s (slot %s)\n", label, curslot);
            fflush(stderr);
        }
 
-       tape_seen = alloc(sizeof(struct seentapes));
-       memset(tape_seen, '\0', sizeof(struct seentapes));
+       tape_seen = alloc(SIZEOF(seentapes_t));
+       memset(tape_seen, '\0', SIZEOF(seentapes_t));
 
        tape_seen->label = label;
        tape_seen->slotstr = stralloc(curslot);
@@ -1417,197 +1903,25 @@ am_feature_t *their_features;
         * have one) contains a list of files to restore, obey that instead
         * of checking for matching headers on all files.
         */
-       filenum = 0;
-       if(desired_tape && desired_tape->numfiles > 0) tapefile_idx = 0;
-
-       /* if we know where we're going, fastforward there */
-       if(flags->fsf && !isafile){
-           int fsf_by = 0;
 
-           /* If we have a tapelist entry, filenums will be store there */
-           if(tapefile_idx >= 0)
-               fsf_by = desired_tape->files[tapefile_idx]; 
-           /*
-            * older semantics assume we're restoring one file, with the fsf
-            * flag being the filenum on tape for said file
-            */
-           else fsf_by = flags->fsf;
-
-           if(fsf_by > 0){
-               if(tapefd_rewind(tapefd) < 0) {
-                   error("Could not rewind device %s: %s", cur_tapedev,
-                                                         strerror(errno));
-               }
-
-               if(tapefd_fsf(tapefd, fsf_by) < 0) {
-                   error("Could not fsf device %s by %d: %s", cur_tapedev, fsf_by,
-                                                          strerror(errno));
-               }
-               else {
-                       filenum = fsf_by;
-               }
-               read_file_header(&file, tapefd, isafile, flags);
-           }
-       }
+       search_a_tape(cur_tapedev, prompt_out, flags, their_features,
+                     desired_tape, isafile, match_list, tape_seen,
+                     &file, &prev_rst_file, &tapestart, slot_num,
+                     &read_result);
 
-       while((file.type == F_TAPESTART || file.type == F_DUMPFILE ||
-             file.type == F_SPLIT_DUMPFILE) &&
-             (tapefile_idx < 0 || tapefile_idx < desired_tape->numfiles)) {
-           int found_match = 0;
-           match_list_t *me;
-           dumplist_t *tempdump = NULL;
-
-           /* store record of this dump for inventorying purposes */
-           tempdump = alloc(sizeof(dumplist_t));
-           tempdump->file = alloc(sizeof(dumpfile_t));
-           tempdump->next = NULL;
-           memcpy(tempdump->file, &file, sizeof(dumpfile_t));
-           if(tape_seen->files){
-               for(fileentry=tape_seen->files;
-                       fileentry->next;
-                       fileentry=fileentry->next);
-               fileentry->next = tempdump;
-           }
-           else tape_seen->files = tempdump;
-
-           /* see if we need to restore the thing */
-           if(isafile) found_match = 1;
-           else if(tapefile_idx >= 0){ /* do it by explicit file #s */
-               if(filenum == desired_tape->files[tapefile_idx]){
-                   found_match = 1;
-                   tapefile_idx++;
-               }
-           }
-           else{ /* search and match headers */
-               for(me = match_list; me; me = me->next) {
-                   if(disk_match(&file, me->datestamp, me->hostname,
-                               me->diskname, me->level) != 0){
-                       found_match = 1;
-                       break;
-                   }
-               }
-           }
-
-           if(found_match){
-               char *filename = make_filename(&file);
-               fprintf(stderr, "%s: %3d: restoring ", get_pname(), filenum);
-               print_header(stderr, &file);
-               bytes_read = restore(&file, filename, tapefd, isafile, flags);
-               filenum ++;
-               amfree(filename);
-           }
-
-           /* advance to the next file, fast-forwarding where reasonable */
-           if(bytes_read == 0 && !isafile) {
-               tapefd_close(tapefd);
-               if((tapefd = tape_open(cur_tapedev, 0)) < 0) {
-                   error("could not open %s: %s",
-                         cur_tapedev, strerror(errno));
-               }
-           } else if(!isafile){
-               /* cheat and jump ahead to where we're going if we can */
-               if (!found_match && flags->fsf) {
-                   drain_file(tapefd, flags);
-                   filenum ++;
-               } else if(tapefile_idx >= 0 && 
-                         tapefile_idx < desired_tape->numfiles &&
-                         flags->fsf){
-                   int fsf_by = desired_tape->files[tapefile_idx] - filenum;
-                   if(fsf_by > 0){
-                       if(tapefd_fsf(tapefd, fsf_by) < 0) {
-                           error("Could not fsf device %s by %d: %s", cur_tapedev, fsf_by,
-                                 strerror(errno));
-                       }
-                       else filenum = desired_tape->files[tapefile_idx];
-                   }
-               } else if (!found_match && flags->fsf) {
-                   /* ... or fsf by 1, whatever */
-                   if(tapefd_fsf(tapefd, 1) < 0) {
-                       error("could not fsf device %s: %s",
-                             cur_tapedev, strerror(errno));
-                   } else {
-                       filenum ++;
-                   }
-               }
-           }
-
-
-           memcpy(&prev_rst_file, &file, sizeof(dumpfile_t));
-
-             
-           if(isafile)
-                break;
-            read_file_header(&file, tapefd, isafile, flags);
-
-           /* only restore a single dump, if piping to stdout */
-           if(!headers_equal(&prev_rst_file, &file, 1) &&
-              flags->pipe_to_fd == fileno(stdout)) break;
-       } /* while we keep seeing headers */
-
-       if(!isafile){
-           if(bytes_read == 0) {
-               /* XXX is this dain-bramaged? */
-               aclose(tapefd);
-               if((tapefd = tape_open(cur_tapedev, 0)) < 0) {
-                   error("could not open %s: %s",
-                       cur_tapedev, strerror(errno));
-               }
-           } else{
-               if(tapefd_fsf(tapefd, 1) < 0) {
-                   error("could not fsf %s: %s",
-                       cur_tapedev, strerror(errno));
-               }
-           }
-       }
-        tapefd_close(tapefd);
-
-       /* spit out our accumulated list of dumps, if we're inventorying */
-       if(logstream){
-            logline = log_genstring(L_START, "taper",
-                                   "datestamp %s label %s tape %d",
-                              tapestart.datestamp, tapestart.name, slot_num);
-            fprintf(logstream, logline);
-            for(fileentry=tape_seen->files; fileentry; fileentry=fileentry->next){
-                logline = NULL;
-                switch(fileentry->file->type){
-                   case F_DUMPFILE:
-                       logline = log_genstring(L_SUCCESS, "taper",
-                                      "%s %s %s %d [faked log entry]",
-                                      fileentry->file->name,
-                                      fileentry->file->disk,
-                                      fileentry->file->datestamp,
-                                      fileentry->file->dumplevel);
-                   break;
-               case F_SPLIT_DUMPFILE:
-                   logline = log_genstring(L_CHUNK, "taper", 
-                                      "%s %s %s %d %d [faked log entry]",
-                                      fileentry->file->name,
-                                      fileentry->file->disk,
-                                      fileentry->file->datestamp,
-                                      fileentry->file->partnum,
-                                      fileentry->file->dumplevel);
-                   break;
-               default:
-                   break;
-                }
-                if(logline){
-                   fprintf(logstream, logline);
-                   amfree(logline);
-                   fflush(logstream);
-                }
-            }
-       }
        fprintf(stderr, "%s: Search of %s complete\n",
                        get_pname(), tape_seen->label);
-       if(desired_tape) desired_tape = desired_tape->next;
+       if (desired_tape) desired_tape = desired_tape->next;
 
        /* only restore a single dump, if piping to stdout */
-       if(!headers_equal(&prev_rst_file, &file, 1) &&
-         flags->pipe_to_fd == fileno(stdout)) break;
-    }
+       if (!headers_equal(&prev_rst_file, &file, 1) &&
+           flags->pipe_to_fd == fileno(stdout))
+               break;
+
+    } while (desired_tape);
 
-    while(seentapes != NULL) {
-       struct seentapes *tape_seen = seentapes;
+    while (seentapes != NULL) {
+       seentapes_t *tape_seen = seentapes;
        seentapes = seentapes->next;
        while(tape_seen->files != NULL) {
            dumplist_t *temp_dump = tape_seen->files;
@@ -1633,11 +1947,12 @@ am_feature_t *their_features;
 /*
  * Create a new, clean set of restore flags with some sane default values.
  */
-rst_flags_t *new_rst_flags()
+rst_flags_t *
+new_rst_flags(void)
 {
-    rst_flags_t *flags = alloc(sizeof(rst_flags_t));
+    rst_flags_t *flags = alloc(SIZEOF(rst_flags_t));
 
-    memset(flags, 0, sizeof(rst_flags_t));
+    memset(flags, 0, SIZEOF(rst_flags_t));
 
     flags->fsf = 1;
     flags->comp_type = COMPRESS_FAST_OPT;
@@ -1652,7 +1967,9 @@ rst_flags_t *new_rst_flags()
  * Make sure the set of restore options given is sane.  Print errors for
  * things that're odd, and return -1 for fatal errors.
  */
-int check_rst_flags(rst_flags_t *flags)
+int
+check_rst_flags(
+    rst_flags_t *      flags)
 {
     int ret = 0;       
     
@@ -1698,14 +2015,15 @@ int check_rst_flags(rst_flags_t *flags)
 /*
  * Clean up after a rst_flags_t
  */
-void free_rst_flags(flags)
-rst_flags_t *flags;
+void
+free_rst_flags(
+    rst_flags_t *      flags)
 {
     if(!flags) return;
 
-    if(flags->restore_dir) amfree(flags->restore_dir);
-    if(flags->alt_tapedev) amfree(flags->alt_tapedev);
-    if(flags->inventory_log) amfree(flags->inventory_log);
+    amfree(flags->restore_dir);
+    amfree(flags->alt_tapedev);
+    amfree(flags->inventory_log);
 
     amfree(flags);
 }
@@ -1714,20 +2032,45 @@ rst_flags_t *flags;
 /*
  * Clean up after a match_list_t
  */
-void free_match_list(match_list)
-match_list_t *match_list;
+void
+free_match_list(
+    match_list_t *     match_list)
 {
     match_list_t *me;
     match_list_t *prev = NULL;
   
     for(me = match_list; me; me = me->next){
        /* XXX freeing these is broken? can't work out why */
-/*     if(me->hostname) amfree(me->hostname);
-       if(me->diskname) amfree(me->diskname);
-       if(me->datestamp) amfree(me->datestamp);
-       if(me->level) amfree(me->level); */
-       if(prev) amfree(prev);
+/*     amfree(me->hostname);
+       amfree(me->diskname);
+       amfree(me->datestamp);
+       amfree(me->level); */
+       amfree(prev);
        prev = me;
     }
-    if(prev) amfree(prev);
+    amfree(prev);
 }
+
+
+printf_arglist_function3(
+    void send_message,
+    FILE *, prompt_out,
+    rst_flags_t *, flags,
+    am_feature_t *, their_features,
+    char *, format)
+{
+    va_list argp;
+    char linebuf[STR_SIZE];
+
+    arglist_start(argp, format);
+    vsnprintf(linebuf, SIZEOF(linebuf)-1, format, argp);
+    arglist_end(argp);
+
+    fprintf(stderr,"%s\n", linebuf);
+    if (flags->amidxtaped && their_features &&
+       am_has_feature(their_features, fe_amrecover_message)) {
+       fprintf(prompt_out, "MESSAGE %s\r\n", linebuf);
+       fflush(prompt_out);
+    }
+}
+
index 2dc32ca866be6074ff55debb863dad4be12b1d49..06cdadf2a1b87ba586109cd9fca49e141a2899e9 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: restore.h,v 1.5 2006/03/14 13:12:01 martinea Exp $
+ * $Id: restore.h,v 1.8 2006/06/22 17:16:39 martinea Exp $
  *
  * 
  */
@@ -58,8 +58,8 @@ typedef struct rst_flags_s {
     unsigned int amidxtaped:1; /* for client-daemon use */
     unsigned int check_labels:1;
     unsigned int mask_splits:1;
-    unsigned int fsf;
-    long blocksize;
+    off_t fsf;
+    ssize_t blocksize;
     int pipe_to_fd;
     char *restore_dir;
     char *comp_type;
@@ -67,23 +67,27 @@ typedef struct rst_flags_s {
     char *inventory_log;
 } rst_flags_t;
 
-char *make_filename P((dumpfile_t *file));
-int disk_match P((dumpfile_t *file, char *datestamp,
-                   char *hostname, char *diskname, char *level));
-void read_file_header P((dumpfile_t *file, int tapefd, int isafile,
-                        rst_flags_t *flags));
-ssize_t restore P((dumpfile_t *file, char *filename, int tapefd, int isafile,
-                       rst_flags_t *flags));
-void flush_open_outputs P((int reassemble, dumpfile_t *only_file));
-void search_tapes P((FILE *prompt_out, int use_changer, tapelist_t *tapelist,
+char *make_filename(dumpfile_t *file);
+int disk_match(dumpfile_t *file, char *datestamp,
+                   char *hostname, char *diskname, char *level);
+ssize_t read_file_header(dumpfile_t *file, int tapefd, int isafile,
+                        rst_flags_t *flags);
+ssize_t restore(dumpfile_t *file, char *filename, int tapefd, int isafile,
+                       rst_flags_t *flags);
+void flush_open_outputs(int reassemble, dumpfile_t *only_file);
+void search_tapes(FILE *prompt_out, int use_changer, tapelist_t *tapelist,
                         match_list_t *restorethese, rst_flags_t *flags, 
-                       am_feature_t *their_features));
-int have_all_parts P((dumpfile_t *file, int upto));
-rst_flags_t *new_rst_flags P((void));
-int check_rst_flags P((rst_flags_t *flags));
-void free_rst_flags P((rst_flags_t *flags));
-void free_match_list P((match_list_t *match_list));
-int lock_logfile P(());
+                       am_feature_t *their_features);
+int have_all_parts(dumpfile_t *file, int upto);
+rst_flags_t *new_rst_flags(void);
+int check_rst_flags(rst_flags_t *flags);
+void free_rst_flags(rst_flags_t *flags);
+void free_match_list(match_list_t *match_list);
+int lock_logfile(void);
+void send_message(FILE *prompt_out, rst_flags_t *flags,
+                 am_feature_t *their_features, char * format, ...);
+       /*     __attribute__ ((format (printf, 4, 5))); */
+
 
 #endif /* RESTORE_H */
 
index e3c46c4c21700c1e6450a1813c576721f40a9dfb..01f864101bc714aeb50041ea2853aa5e45f9ccc6 100644 (file)
@@ -3,7 +3,11 @@
 INCLUDES =     -I$(top_builddir)/common-src \
                -I$(top_srcdir)/common-src   \
                -I$(top_srcdir)/restore-src  \
-               -I$(top_srcdir)/tape-src
+               -I$(top_srcdir)/tape-src     \
+               -I$(top_srcdir)/amandad-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
 
 lib_LTLIBRARIES =      libamserver.la
 LIB_EXTENSION = la
@@ -20,7 +24,8 @@ libexec_PROGRAMS =    amindexd        amlogroll       amtrmidx        \
 sbin_SCRIPTS =         amcheckdb       amcleanup       amdump          \
                        amoverview      amrmtape        amtoc           \
                        amverify        amverifyrun     amstatus        \
-                       amcrypt         amaespipe
+                       amcrypt         amaespipe       amcrypt-ossl    \
+                       amcrypt-ossl-asym
 
 libamserver_la_SOURCES=        amindex.c       changer.c                       \
                        conffile.c      diskfile.c      driverio.c      \
@@ -38,7 +43,16 @@ libamserver_la_LDFLAGS= -release $(VERSION)
 ###
 
 LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION)             \
+       ../tape-src/libamtape.$(LIB_EXTENSION)   \
+       ../common-src/libamanda.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION)   \
+       ../common-src/libamanda.$(LIB_EXTENSION) \
+        $(READLINE_LIBS)
+
+amindexd_LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
        libamserver.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
@@ -62,9 +76,8 @@ EXTRA_PROGRAMS =      $(TEST_PROGS)
 
 CLEANFILES = *.test.c $(sbin_SCRIPTS)
 
-amindexd_SOURCES =     amindexd.c                                      \
-                       disk_history.c                  disk_history.h  \
-                       list_dir.c                      list_dir.h
+amindexd_CSRC =                amindexd.c      disk_history.c  list_dir.c
+amindexd_SOURCES =     disk_history.h  list_dir.h      $(amindexd_CSRC)
 
 amreport_SOURCES =     reporter.c
 
@@ -104,7 +117,10 @@ install-exec-hook:
                else true; \
                fi; \
        done
-if !WANT_SSH_SECURITY
+##                                                    ##
+## enterprise version will install dumper/planner suid ##
+##                                                    ##
+
        @list="dumper planner"; \
        for p in $$list; do \
                if echo "$(libexec_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
@@ -116,7 +132,38 @@ if !WANT_SSH_SECURITY
                else true; \
                fi; \
        done
-endif
+
+lint:
+       @ for p in $(libexec_PROGRAMS) $(sbin_PROGRAMS); do                     \
+               if [ $$p = "amindexd" ]; then                                   \
+                       s="$(amindexd_CSRC)";                                   \
+               elif [ $$p = "amreport" ]; then                                 \
+                       s="$(amreport_SOURCES)";                                \
+               elif [ $$p = "amgetconf" ]; then                                \
+                       s="$(getconf_SOURCES)";                                 \
+               else                                                            \
+                       s=$$p.c;                                                \
+               fi;                                                             \
+               f="$$s $(libamserver_la_SOURCES)";                              \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               (cd ../tape-src; make listlibsrc);                              \
+               f="$$f "`cat ../tape-src/listlibsrc.output`;                    \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+
+listlibsrc:
+       @ for p in $(libamserver_la_SOURCES); do                \
+               listlibsrcs="$$listlibsrcs `pwd`/$$p";          \
+       done;                                                   \
+       echo $$listlibsrcs >listlibsrc.output
+
 
 diskfile_SOURCES = diskfile.test.c
 conffile_SOURCES = conffile.test.c
index a284a8967d4d3ce0cf110db490fd9930f1ca3e62..2e8331143b8d9841cbf5f619a826d5dfe1935edb 100644 (file)
@@ -54,6 +54,7 @@ subdir = server-src
 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
        $(srcdir)/Makefile.in $(srcdir)/amaespipe.sh.in \
        $(srcdir)/amcheckdb.sh.in $(srcdir)/amcleanup.sh.in \
+       $(srcdir)/amcrypt-ossl-asym.sh.in $(srcdir)/amcrypt-ossl.sh.in \
        $(srcdir)/amcrypt.sh.in $(srcdir)/amdump.sh.in \
        $(srcdir)/amfreetapes.sh.in $(srcdir)/amoverview.pl.in \
        $(srcdir)/amrmtape.sh.in $(srcdir)/amstatus.pl.in \
@@ -68,7 +69,8 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config/config.h
 CONFIG_CLEAN_FILES = amcheckdb.sh amcleanup.sh amdump.sh \
        amfreetapes.sh amoverview.pl amrmtape.sh amtoc.pl amverify.sh \
-       amstatus.pl amverifyrun.sh amcrypt.sh amaespipe.sh
+       amstatus.pl amverifyrun.sh amcrypt.sh amaespipe.sh \
+       amcrypt-ossl.sh amcrypt-ossl-asym.sh
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -91,12 +93,13 @@ PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS)
 amadmin_SOURCES = amadmin.c
 amadmin_OBJECTS = amadmin.$(OBJEXT)
 amadmin_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
 amadmin_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        libamserver.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 amcheck_SOURCES = amcheck.c
 amcheck_OBJECTS = amcheck.$(OBJEXT)
 amcheck_LDADD = $(LDADD)
@@ -105,7 +108,7 @@ amcheck_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 amcleanupdisk_SOURCES = amcleanupdisk.c
 amcleanupdisk_OBJECTS = amcleanupdisk.$(OBJEXT)
 amcleanupdisk_LDADD = $(LDADD)
@@ -114,7 +117,7 @@ amcleanupdisk_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 amflush_SOURCES = amflush.c
 amflush_OBJECTS = amflush.$(OBJEXT)
 amflush_LDADD = $(LDADD)
@@ -123,7 +126,7 @@ amflush_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 am_amgetconf_OBJECTS = getconf.$(OBJEXT)
 amgetconf_OBJECTS = $(am_amgetconf_OBJECTS)
 amgetconf_LDADD = $(LDADD)
@@ -132,13 +135,14 @@ amgetconf_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
-am_amindexd_OBJECTS = amindexd.$(OBJEXT) disk_history.$(OBJEXT) \
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
+am__objects_1 = amindexd.$(OBJEXT) disk_history.$(OBJEXT) \
        list_dir.$(OBJEXT)
+am_amindexd_OBJECTS = $(am__objects_1)
 amindexd_OBJECTS = $(am_amindexd_OBJECTS)
-amindexd_LDADD = $(LDADD)
 amindexd_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        libamserver.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
@@ -151,7 +155,7 @@ amlabel_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 amlogroll_SOURCES = amlogroll.c
 amlogroll_OBJECTS = amlogroll.$(OBJEXT)
 amlogroll_LDADD = $(LDADD)
@@ -160,7 +164,7 @@ amlogroll_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 am_amreport_OBJECTS = reporter.$(OBJEXT)
 amreport_OBJECTS = $(am_amreport_OBJECTS)
 amreport_LDADD = $(LDADD)
@@ -169,7 +173,7 @@ amreport_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 amtape_SOURCES = amtape.c
 amtape_OBJECTS = amtape.$(OBJEXT)
 amtape_LDADD = $(LDADD)
@@ -178,7 +182,7 @@ amtape_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 amtrmidx_SOURCES = amtrmidx.c
 amtrmidx_OBJECTS = amtrmidx.$(OBJEXT)
 amtrmidx_LDADD = $(LDADD)
@@ -187,7 +191,7 @@ amtrmidx_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 amtrmlog_SOURCES = amtrmlog.c
 amtrmlog_OBJECTS = amtrmlog.$(OBJEXT)
 amtrmlog_LDADD = $(LDADD)
@@ -196,7 +200,7 @@ amtrmlog_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 chunker_SOURCES = chunker.c
 chunker_OBJECTS = chunker.$(OBJEXT)
 chunker_LDADD = $(LDADD)
@@ -205,7 +209,7 @@ chunker_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 am_conffile_OBJECTS = conffile.test.$(OBJEXT)
 conffile_OBJECTS = $(am_conffile_OBJECTS)
 conffile_LDADD = $(LDADD)
@@ -214,7 +218,7 @@ conffile_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 am_diskfile_OBJECTS = diskfile.test.$(OBJEXT)
 diskfile_OBJECTS = $(am_diskfile_OBJECTS)
 diskfile_LDADD = $(LDADD)
@@ -223,7 +227,7 @@ diskfile_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 driver_SOURCES = driver.c
 driver_OBJECTS = driver.$(OBJEXT)
 driver_LDADD = $(LDADD)
@@ -232,7 +236,7 @@ driver_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 dumper_SOURCES = dumper.c
 dumper_OBJECTS = dumper.$(OBJEXT)
 dumper_LDADD = $(LDADD)
@@ -241,7 +245,7 @@ dumper_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 am_infofile_OBJECTS = infofile.test.$(OBJEXT)
 infofile_OBJECTS = $(am_infofile_OBJECTS)
 infofile_LDADD = $(LDADD)
@@ -250,7 +254,7 @@ infofile_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 planner_SOURCES = planner.c
 planner_OBJECTS = planner.$(OBJEXT)
 planner_LDADD = $(LDADD)
@@ -259,7 +263,7 @@ planner_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 taper_SOURCES = taper.c
 taper_OBJECTS = taper.$(OBJEXT)
 taper_LDADD = $(LDADD)
@@ -268,7 +272,7 @@ taper_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
-       ../common-src/libamanda.$(LIB_EXTENSION)
+       ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
 sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 SCRIPTS = $(sbin_SCRIPTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
@@ -305,11 +309,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -317,6 +324,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -500,14 +509,18 @@ target_vendor = @target_vendor@
 INCLUDES = -I$(top_builddir)/common-src \
                -I$(top_srcdir)/common-src   \
                -I$(top_srcdir)/restore-src  \
-               -I$(top_srcdir)/tape-src
+               -I$(top_srcdir)/tape-src     \
+               -I$(top_srcdir)/amandad-src
 
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
 lib_LTLIBRARIES = libamserver.la
 LIB_EXTENSION = la
 sbin_SCRIPTS = amcheckdb       amcleanup       amdump          \
                        amoverview      amrmtape        amtoc           \
                        amverify        amverifyrun     amstatus        \
-                       amcrypt         amaespipe
+                       amcrypt         amaespipe       amcrypt-ossl    \
+                       amcrypt-ossl-asym
 
 libamserver_la_SOURCES = amindex.c     changer.c                       \
                        conffile.c      diskfile.c      driverio.c      \
@@ -524,7 +537,16 @@ libamserver_la_LDFLAGS = -release $(VERSION)
 # routines, and second to pick up any references in the other libraries.
 ###
 LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION)             \
+       ../tape-src/libamtape.$(LIB_EXTENSION)   \
+       ../common-src/libamanda.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION)   \
+       ../common-src/libamanda.$(LIB_EXTENSION) \
+        $(READLINE_LIBS)
+
+amindexd_LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
        libamserver.$(LIB_EXTENSION) \
+       ../amandad-src/libamandad.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
        ../common-src/libamanda.$(LIB_EXTENSION) \
        ../tape-src/libamtape.$(LIB_EXTENSION) \
@@ -535,10 +557,8 @@ SUFFIXES = .sh .pl
 # there are used for testing only:
 TEST_PROGS = diskfile conffile infofile
 CLEANFILES = *.test.c $(sbin_SCRIPTS)
-amindexd_SOURCES = amindexd.c                                  \
-                       disk_history.c                  disk_history.h  \
-                       list_dir.c                      list_dir.h
-
+amindexd_CSRC = amindexd.c     disk_history.c  list_dir.c
+amindexd_SOURCES = disk_history.h      list_dir.h      $(amindexd_CSRC)
 amreport_SOURCES = reporter.c
 amgetconf_SOURCES = getconf.c
 noinst_HEADERS = amindex.h     changer.h                       \
@@ -607,6 +627,10 @@ amcrypt.sh: $(top_builddir)/config.status $(srcdir)/amcrypt.sh.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 amaespipe.sh: $(top_builddir)/config.status $(srcdir)/amaespipe.sh.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amcrypt-ossl.sh: $(top_builddir)/config.status $(srcdir)/amcrypt-ossl.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amcrypt-ossl-asym.sh: $(top_builddir)/config.status $(srcdir)/amcrypt-ossl-asym.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
        @$(NORMAL_INSTALL)
        test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
@@ -1061,17 +1085,49 @@ install-exec-hook:
                else true; \
                fi; \
        done
-@WANT_SSH_SECURITY_FALSE@      @list="dumper planner"; \
-@WANT_SSH_SECURITY_FALSE@      for p in $$list; do \
-@WANT_SSH_SECURITY_FALSE@              if echo "$(libexec_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
-@WANT_SSH_SECURITY_FALSE@                      pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed '$(transform)'`; \
-@WANT_SSH_SECURITY_FALSE@                      echo chown root $$pa; \
-@WANT_SSH_SECURITY_FALSE@                      chown root $$pa; \
-@WANT_SSH_SECURITY_FALSE@                      echo chmod u+s,o-rwx $$pa; \
-@WANT_SSH_SECURITY_FALSE@                      chmod u+s,o-rwx $$pa; \
-@WANT_SSH_SECURITY_FALSE@              else true; \
-@WANT_SSH_SECURITY_FALSE@              fi; \
-@WANT_SSH_SECURITY_FALSE@      done
+
+       @list="dumper planner"; \
+       for p in $$list; do \
+               if echo "$(libexec_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
+                       pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed '$(transform)'`; \
+                       echo chown root $$pa; \
+                       chown root $$pa; \
+                       echo chmod u+s,o-rwx $$pa; \
+                       chmod u+s,o-rwx $$pa; \
+               else true; \
+               fi; \
+       done
+
+lint:
+       @ for p in $(libexec_PROGRAMS) $(sbin_PROGRAMS); do                     \
+               if [ $$p = "amindexd" ]; then                                   \
+                       s="$(amindexd_CSRC)";                                   \
+               elif [ $$p = "amreport" ]; then                                 \
+                       s="$(amreport_SOURCES)";                                \
+               elif [ $$p = "amgetconf" ]; then                                \
+                       s="$(getconf_SOURCES)";                                 \
+               else                                                            \
+                       s=$$p.c;                                                \
+               fi;                                                             \
+               f="$$s $(libamserver_la_SOURCES)";                              \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               (cd ../tape-src; make listlibsrc);                              \
+               f="$$f "`cat ../tape-src/listlibsrc.output`;                    \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+
+listlibsrc:
+       @ for p in $(libamserver_la_SOURCES); do                \
+               listlibsrcs="$$listlibsrcs `pwd`/$$p";          \
+       done;                                                   \
+       echo $$listlibsrcs >listlibsrc.output
 
 %.test.c: $(srcdir)/%.c
        echo '#define TEST' >$@
index 51ebb93375e58817802f6c73f2fad3a140433a7f..e54507600e71c1ae8b760f6f85c3cb91b43881a9 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: amadmin.c,v 1.105 2006/02/03 17:29:28 vectro Exp $
+ * $Id: amadmin.c,v 1.124 2006/07/26 15:17:37 martinea Exp $
  *
  * controlling process for the Amanda backup system
  */
 
 disklist_t diskq;
 
-int main P((int argc, char **argv));
-void usage P((void));
-void force P((int argc, char **argv));
-void force_one P((disk_t *dp));
-void unforce P((int argc, char **argv));
-void unforce_one P((disk_t *dp));
-void force_bump P((int argc, char **argv));
-void force_bump_one P((disk_t *dp));
-void force_no_bump P((int argc, char **argv));
-void force_no_bump_one P((disk_t *dp));
-void unforce_bump P((int argc, char **argv));
-void unforce_bump_one P((disk_t *dp));
-void reuse P((int argc, char **argv));
-void noreuse P((int argc, char **argv));
-void info P((int argc, char **argv));
-void info_one P((disk_t *dp));
-void due P((int argc, char **argv));
-void due_one P((disk_t *dp));
-void find P((int argc, char **argv));
-void delete P((int argc, char **argv));
-void delete_one P((disk_t *dp));
-void balance P((int argc, char **argv));
-void tape P((int argc, char **argv));
-void bumpsize P((int argc, char **argv));
-void diskloop P((int argc, char **argv, char *cmdname,
-                void (*func) P((disk_t *dp))));
-char *seqdatestr P((int seq));
-static int next_level0 P((disk_t *dp, info_t *info));
-int bump_thresh P((int level));
-void export_db P((int argc, char **argv));
-void import_db P((int argc, char **argv));
-void disklist P((int argc, char **argv));
-void disklist_one P((disk_t *dp));
-void show_version P((int argc, char **argv));
-static void check_dumpuser P((void));
+int main(int argc, char **argv);
+void usage(void);
+void force(int argc, char **argv);
+void force_one(disk_t *dp);
+void unforce(int argc, char **argv);
+void unforce_one(disk_t *dp);
+void force_bump(int argc, char **argv);
+void force_bump_one(disk_t *dp);
+void force_no_bump(int argc, char **argv);
+void force_no_bump_one(disk_t *dp);
+void unforce_bump(int argc, char **argv);
+void unforce_bump_one(disk_t *dp);
+void reuse(int argc, char **argv);
+void noreuse(int argc, char **argv);
+void info(int argc, char **argv);
+void info_one(disk_t *dp);
+void due(int argc, char **argv);
+void due_one(disk_t *dp);
+void find(int argc, char **argv);
+void delete(int argc, char **argv);
+void delete_one(disk_t *dp);
+void balance(int argc, char **argv);
+void tape(int argc, char **argv);
+void bumpsize(int argc, char **argv);
+void diskloop(int argc, char **argv, char *cmdname, void (*func)(disk_t *dp));
+char *seqdatestr(int seq);
+static int next_level0(disk_t *dp, info_t *info);
+int bump_thresh(int level);
+void export_db(int argc, char **argv);
+void import_db(int argc, char **argv);
+void disklist(int argc, char **argv);
+void disklist_one(disk_t *dp);
+void show_version(int argc, char **argv);
+static void show_config(int argc, char **argv);
+static void check_dumpuser(void);
 
 static char *conf_tapelist = NULL;
 static char *displayunit;
@@ -83,13 +83,15 @@ static long int unitdivisor;
 
 static const struct {
     const char *name;
-    void (*fn) P((int, char **));
+    void (*fn)(int, char **);
     const char *usage;
 } cmdtab[] = {
     { "version", show_version,
-       "\t\t\t\t# Show version info." },
+       "\t\t\t\t\t# Show version info." },
+    { "config", show_config,
+       "\t\t\t\t\t# Show configuration." },
     { "force", force,
-       " [<hostname> [<disks>]* ]+\t# Force level 0 at next run." },
+       " [<hostname> [<disks>]* ]+\t\t# Force level 0 at next run." },
     { "unforce", unforce,
        " [<hostname> [<disks>]* ]+\t# Clear force command." },
     { "force-bump", force_bump,
@@ -98,49 +100,55 @@ static const struct {
        " [<hostname> [<disks>]* ]+\t# Force no-bump at next run." },
     { "unforce-bump", unforce_bump,
        " [<hostname> [<disks>]* ]+\t# Clear bump command." },
+    { "disklist", disklist,
+       " [<hostname> [<disks>]* ]*\t# Debug disklist entries." },
     { "reuse", reuse,
-       " <tapelabel> ...\t\t# re-use this tape." },
+       " <tapelabel> ...\t\t # re-use this tape." },
     { "no-reuse", noreuse,
-       " <tapelabel> ...\t# never re-use this tape." },
+       " <tapelabel> ...\t # never re-use this tape." },
     { "find", find,
-       " [<hostname> [<disks>]* ]*\t# Show which tapes these dumps are on." },
+       " [<hostname> [<disks>]* ]*\t # Show which tapes these dumps are on." },
     { "delete", delete,
-       " [<hostname> [<disks>]* ]+\t# Delete from database." },
+       " [<hostname> [<disks>]* ]+ # Delete from database." },
     { "info", info,
-       " [<hostname> [<disks>]* ]*\t# Show current info records." },
+       " [<hostname> [<disks>]* ]*\t # Show current info records." },
     { "due", due,
-       " [<hostname> [<disks>]* ]*\t# Show due date." },
+       " [<hostname> [<disks>]* ]*\t # Show due date." },
     { "balance", balance,
-       " [-days <num>]\t\t# Show nightly dump size balance." },
+       " [-days <num>]\t\t # Show nightly dump size balance." },
     { "tape", tape,
-       " [-days <num>]\t\t\t# Show which tape is due next." },
+       " [-days <num>]\t\t # Show which tape is due next." },
     { "bumpsize", bumpsize,
-       "\t\t\t# Show current bump thresholds." },
+       "\t\t\t # Show current bump thresholds." },
     { "export", export_db,
-       " [<hostname> [<disks>]* ]*\t# Export curinfo database to stdout." },
+       " [<hostname> [<disks>]* ]* # Export curinfo database to stdout." },
     { "import", import_db,
-       "\t\t\t\t# Import curinfo database from stdin." },
-    { "disklist", disklist,
-       " [<hostname> [<disks>]* ]*\t# Debug disklist entries." },
+       "\t\t\t\t # Import curinfo database from stdin." },
 };
-#define        NCMDS   (sizeof(cmdtab) / sizeof(cmdtab[0]))
+#define        NCMDS   (int)(sizeof(cmdtab) / sizeof(cmdtab[0]))
 
-int main(argc, argv)
-     int argc;
-     char **argv;
+static char *conffile;
+
+int
+main(
+    int                argc,
+    char **    argv)
 {
     int i;
     char *conf_diskfile;
     char *conf_infofile;
-    char *conffile;
     unsigned long malloc_hist_1, malloc_size_1;
     unsigned long malloc_hist_2, malloc_size_2;
+    int new_argc;
+    char **new_argv;
 
     safe_fd(-1, 0);
     safe_cd();
 
     set_pname("amadmin");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -148,20 +156,28 @@ int main(argc, argv)
 
     erroutput_type = ERR_INTERACTIVE;
 
-    if(argc < 3) usage();
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+
+    if(new_argc < 3) usage();
 
-    if(strcmp(argv[2],"version") == 0) {
-       show_version(argc, argv);
+    if(strcmp(new_argv[2],"version") == 0) {
+       show_version(new_argc, new_argv);
        goto done;
     }
 
-    config_name = argv[1];
+    config_name = new_argv[1];
+
     config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     conffile = stralloc2(config_dir, CONFFILE_NAME);
 
-    if(read_conffile(conffile))
+    if(read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
-    amfree(conffile);
+       /*NOTREACHED*/
+    }
+
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
 
     check_dumpuser();
 
@@ -171,8 +187,10 @@ int main(argc, argv)
     } else {
        conf_diskfile = stralloc2(config_dir, conf_diskfile);
     }
-    if (read_diskfile(conf_diskfile, &diskq) < 0)
+    if (read_diskfile(conf_diskfile, &diskq) < 0) {
        error("could not load disklist \"%s\"", conf_diskfile);
+       /*NOTREACHED*/
+    }
     amfree(conf_diskfile);
 
     conf_tapelist = getconf_str(CNF_TAPELIST);
@@ -181,32 +199,37 @@ int main(argc, argv)
     } else {
        conf_tapelist = stralloc2(config_dir, conf_tapelist);
     }
-    if(read_tapelist(conf_tapelist))
+    if(read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
-
+       /*NOTREACHED*/
+    }
     conf_infofile = getconf_str(CNF_INFOFILE);
     if (*conf_infofile == '/') {
        conf_infofile = stralloc(conf_infofile);
     } else {
        conf_infofile = stralloc2(config_dir, conf_infofile);
     }
-    if(open_infofile(conf_infofile))
+    if(open_infofile(conf_infofile)) {
        error("could not open info db \"%s\"", conf_infofile);
+       /*NOTREACHED*/
+    }
     amfree(conf_infofile);
 
     displayunit = getconf_str(CNF_DISPLAYUNIT);
     unitdivisor = getconf_unit_divisor();
 
     for (i = 0; i < NCMDS; i++)
-       if (strcmp(argv[2], cmdtab[i].name) == 0) {
-           (*cmdtab[i].fn)(argc, argv);
+       if (strcmp(new_argv[2], cmdtab[i].name) == 0) {
+           (*cmdtab[i].fn)(new_argc, new_argv);
            break;
        }
     if (i == NCMDS) {
-       fprintf(stderr, "%s: unknown command \"%s\"\n", argv[0], argv[2]);
+       fprintf(stderr, "%s: unknown command \"%s\"\n", new_argv[0], new_argv[2]);
        usage();
     }
 
+    free_new_argv(new_argc, new_argv);
+
     close_infofile();
     clear_tapelist();
     amfree(conf_tapelist);
@@ -220,15 +243,20 @@ done:
        malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
     }
 
+    amfree(conffile);
+    free_disklist(&diskq);
+    free_server_config();
+    dbclose();
     return 0;
 }
 
 
-void usage P((void))
+void
+usage(void)
 {
     int i;
 
-    fprintf(stderr, "\nUsage: %s%s <conf> <command> {<args>} ...\n",
+    fprintf(stderr, "\nUsage: %s%s <conf> <command> {<args>} [-o configoption]* ...\n",
            get_pname(), versionsuffix());
     fprintf(stderr, "    Valid <command>s are:\n");
     for (i = 0; i < NCMDS; i++)
@@ -242,8 +270,9 @@ void usage P((void))
 #define SECS_PER_DAY (24*60*60)
 time_t today;
 
-char *seqdatestr(seq)
-int seq;
+char *
+seqdatestr(
+    int                seq)
 {
     static char str[16];
     static char *dow[7] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
@@ -252,18 +281,23 @@ int seq;
 
     tm = localtime(&t);
 
-    snprintf(str, sizeof(str),
-               "%2d/%02d %3s", tm->tm_mon+1, tm->tm_mday, dow[tm->tm_wday]);
+    if (tm)
+       snprintf(str, SIZEOF(str),
+                "%2d/%02d %3s", tm->tm_mon+1, tm->tm_mday, dow[tm->tm_wday]);
+    else
+       strcpy(str, "BAD DATE");
+
     return str;
 }
 
 #undef days_diff
-#define days_diff(a, b)        (((b) - (a) + SECS_PER_DAY) / SECS_PER_DAY)
+#define days_diff(a, b)        (int)(((b) - (a) + SECS_PER_DAY) / SECS_PER_DAY)
 
 /* when is next level 0 due? 0 = tonight, 1 = tommorrow, etc*/
-static int next_level0(dp, info)
-disk_t *dp;
-info_t *info;
+static int
+next_level0(
+    disk_t *   dp,
+    info_t *   info)
 {
     if(dp->strategy == DS_NOFULL)
        return 1;       /* fake it */
@@ -273,7 +307,8 @@ info_t *info;
        return dp->dumpcycle - days_diff(info->inf[0].date, today);
 }
 
-static void check_dumpuser()
+static void
+check_dumpuser(void)
 {
     static int been_here = 0;
     uid_t uid_me;
@@ -290,16 +325,17 @@ static void check_dumpuser()
 
     if ((pw = getpwnam(dumpuser)) == NULL) {
        error("cannot look up dump user \"%s\"", dumpuser);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
     uid_dumpuser = pw->pw_uid;
     if ((pw = getpwuid(uid_me)) == NULL) {
        error("cannot look up my own uid %ld", (long)uid_me);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
     if (uid_me != uid_dumpuser) {
        error("ERROR: running as user \"%s\" instead of \"%s\"",
              pw->pw_name, dumpuser);
+        /*NOTREACHED*/
     }
     been_here = 1;
     return;
@@ -307,14 +343,16 @@ static void check_dumpuser()
 
 /* ----------------------------------------------- */
 
-void diskloop(argc, argv, cmdname, func)
-int argc;
-char **argv;
-char *cmdname;
-void (*func) P((disk_t *dp));
+void
+diskloop(
+    int                argc,
+    char **    argv,
+    char *     cmdname,
+    void       (*func)(disk_t *dp))
 {
     disk_t *dp;
     int count = 0;
+    char *errstr;
 
     if(argc < 4) {
        fprintf(stderr,"%s: expecting \"%s [<hostname> [<disks>]* ]+\"\n",
@@ -322,7 +360,11 @@ void (*func) P((disk_t *dp));
        usage();
     }
 
-    match_disklist(&diskq, argc-3, argv+3);
+    errstr = match_disklist(&diskq, argc-3, argv+3);
+    if (errstr) {
+       printf("%s", errstr);
+       amfree(errstr);
+    }
 
     for(dp = diskq.head; dp != NULL; dp = dp->next) {
        if(dp->todo) {
@@ -338,8 +380,9 @@ void (*func) P((disk_t *dp));
 /* ----------------------------------------------- */
 
 
-void force_one(dp)
-disk_t *dp;
+void
+force_one(
+    disk_t *   dp)
 {
     char *hostname = dp->host->hostname;
     char *diskname = dp->name;
@@ -365,9 +408,10 @@ disk_t *dp;
 }
 
 
-void force(argc, argv)
-int argc;
-char **argv;
+void
+force(
+    int                argc,
+    char **    argv)
 {
     diskloop(argc, argv, "force", force_one);
 }
@@ -376,8 +420,9 @@ char **argv;
 /* ----------------------------------------------- */
 
 
-void unforce_one(dp)
-disk_t *dp;
+void
+unforce_one(
+    disk_t *   dp)
 {
     char *hostname = dp->host->hostname;
     char *diskname = dp->name;
@@ -404,9 +449,10 @@ disk_t *dp;
     }
 }
 
-void unforce(argc, argv)
-int argc;
-char **argv;
+void
+unforce(
+    int                argc,
+    char **    argv)
 {
     diskloop(argc, argv, "unforce", unforce_one);
 }
@@ -415,8 +461,9 @@ char **argv;
 /* ----------------------------------------------- */
 
 
-void force_bump_one(dp)
-disk_t *dp;
+void
+force_bump_one(
+    disk_t *   dp)
 {
     char *hostname = dp->host->hostname;
     char *diskname = dp->name;
@@ -447,9 +494,10 @@ disk_t *dp;
 }
 
 
-void force_bump(argc, argv)
-int argc;
-char **argv;
+void
+force_bump(
+    int                argc,
+    char **    argv)
 {
     diskloop(argc, argv, "force-bump", force_bump_one);
 }
@@ -458,8 +506,9 @@ char **argv;
 /* ----------------------------------------------- */
 
 
-void force_no_bump_one(dp)
-disk_t *dp;
+void
+force_no_bump_one(
+    disk_t *   dp)
 {
     char *hostname = dp->host->hostname;
     char *diskname = dp->name;
@@ -485,9 +534,10 @@ disk_t *dp;
 }
 
 
-void force_no_bump(argc, argv)
-int argc;
-char **argv;
+void
+force_no_bump(
+    int                argc,
+    char **    argv)
 {
     diskloop(argc, argv, "force-no-bump", force_no_bump_one);
 }
@@ -496,8 +546,9 @@ char **argv;
 /* ----------------------------------------------- */
 
 
-void unforce_bump_one(dp)
-disk_t *dp;
+void
+unforce_bump_one(
+    disk_t *   dp)
 {
     char *hostname = dp->host->hostname;
     char *diskname = dp->name;
@@ -524,9 +575,10 @@ disk_t *dp;
 }
 
 
-void unforce_bump(argc, argv)
-int argc;
-char **argv;
+void
+unforce_bump(
+    int                argc,
+    char **    argv)
 {
     diskloop(argc, argv, "unforce-bump", unforce_bump_one);
 }
@@ -534,9 +586,10 @@ char **argv;
 
 /* ----------------------------------------------- */
 
-void reuse(argc, argv)
-int argc;
-char **argv;
+void
+reuse(
+    int                argc,
+    char **    argv)
 {
     tape_t *tp;
     int count;
@@ -567,12 +620,14 @@ char **argv;
 
     if(write_tapelist(conf_tapelist)) {
        error("could not write tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
     }
 }
 
-void noreuse(argc, argv)
-int argc;
-char **argv;
+void
+noreuse(
+    int                argc,
+    char **    argv)
 {
     tape_t *tp;
     int count;
@@ -603,6 +658,7 @@ char **argv;
 
     if(write_tapelist(conf_tapelist)) {
        error("could not write tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
     }
 }
 
@@ -611,8 +667,9 @@ char **argv;
 
 static int deleted;
 
-void delete_one(dp)
-disk_t *dp;
+void
+delete_one(
+    disk_t *   dp)
 {
     char *hostname = dp->host->hostname;
     char *diskname = dp->name;
@@ -625,17 +682,20 @@ disk_t *dp;
     }
 
     deleted++;
-    if(del_info(hostname, diskname))
+    if(del_info(hostname, diskname)) {
        error("couldn't delete %s:%s from database: %s",
              hostname, diskname, strerror(errno));
-    else
+        /*NOTREACHED*/
+    } else {
        printf("%s: %s:%s deleted from curinfo database.\n",
               get_pname(), hostname, diskname);
+    }
 }
 
-void delete(argc, argv)
-int argc;
-char **argv;
+void
+delete(
+    int                argc,
+    char **    argv)
 {
     deleted = 0;
     diskloop(argc, argv, "delete", delete_one);
@@ -648,8 +708,9 @@ char **argv;
 
 /* ----------------------------------------------- */
 
-void info_one(dp)
-disk_t *dp;
+void
+info_one(
+    disk_t *   dp)
 {
     info_t info;
     int lev;
@@ -665,29 +726,46 @@ disk_t *dp;
        printf("  (Forcing bump at next run)\n");
     if (ISSET(info.command, FORCE_NO_BUMP))
        printf("  (Forcing no-bump at next run)\n");
-    printf("  Stats: dump rates (kps), Full:  %5.1f, %5.1f, %5.1f\n",
+    printf("  Stats: dump rates (kps), Full:  %5.1lf, %5.1lf, %5.1lf\n",
           info.full.rate[0], info.full.rate[1], info.full.rate[2]);
-    printf("                    Incremental:  %5.1f, %5.1f, %5.1f\n",
+    printf("                    Incremental:  %5.1lf, %5.1lf, %5.1lf\n",
           info.incr.rate[0], info.incr.rate[1], info.incr.rate[2]);
-    printf("          compressed size, Full: %5.1f%%,%5.1f%%,%5.1f%%\n",
+    printf("          compressed size, Full: %5.1lf%%,%5.1lf%%,%5.1lf%%\n",
           info.full.comp[0]*100, info.full.comp[1]*100, info.full.comp[2]*100);
-    printf("                    Incremental: %5.1f%%,%5.1f%%,%5.1f%%\n",
+    printf("                    Incremental: %5.1lf%%,%5.1lf%%,%5.1lf%%\n",
           info.incr.comp[0]*100, info.incr.comp[1]*100, info.incr.comp[2]*100);
 
     printf("  Dumps: lev datestmp  tape             file   origK   compK secs\n");
     for(lev = 0, sp = &info.inf[0]; lev < 9; lev++, sp++) {
        if(sp->date < (time_t)0 && sp->label[0] == '\0') continue;
        tm = localtime(&sp->date);
-       printf("          %d  %04d%02d%02d  %-15s  %4d %7ld %7ld %4ld\n",
-              lev, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
-              sp->label, sp->filenum, sp->size, sp->csize, sp->secs);
+       if (tm) {
+           printf("          %d  %04d%02d%02d  %-15s  "
+                  OFF_T_FMT " " OFF_T_FMT " " OFF_T_FMT " " TIME_T_FMT "\n",
+                  lev, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+                  sp->label,
+                  (OFF_T_FMT_TYPE)sp->filenum,
+                  (OFF_T_FMT_TYPE)sp->size,
+                  (OFF_T_FMT_TYPE)sp->csize,
+                  (TIME_T_FMT_TYPE)sp->secs);
+       } else {
+           printf("          %d  BAD-DATE  %-15s  "
+                  OFF_T_FMT " " OFF_T_FMT " " OFF_T_FMT " " TIME_T_FMT "\n",
+                  lev,
+                  sp->label,
+                  (OFF_T_FMT_TYPE)sp->filenum,
+                  (OFF_T_FMT_TYPE)sp->size,
+                  (OFF_T_FMT_TYPE)sp->csize,
+                  (TIME_T_FMT_TYPE)sp->secs);
+       }
     }
 }
 
 
-void info(argc, argv)
-int argc;
-char **argv;
+void
+info(
+    int                argc,
+    char **    argv)
 {
     disk_t *dp;
 
@@ -700,8 +778,9 @@ char **argv;
 
 /* ----------------------------------------------- */
 
-void due_one(dp)
-disk_t *dp;
+void
+due_one(
+    disk_t *   dp)
 {
     am_host_t *hp;
     int days;
@@ -729,9 +808,10 @@ disk_t *dp;
     }
 }
 
-void due(argc, argv)
-int argc;
-char **argv;
+void
+due(
+    int                argc,
+    char **    argv)
 {
     disk_t *dp;
 
@@ -745,9 +825,10 @@ char **argv;
 
 /* ----------------------------------------------- */
 
-void tape(argc, argv)
-int argc;
-char **argv;
+void
+tape(
+    int                argc,
+    char **    argv)
 {
     tape_t *tp, *lasttp;
     int runtapes, i, j;
@@ -759,6 +840,8 @@ char **argv;
            printf("days must be an integer bigger than 0\n");
            return;
        }
+       if (nb_days > 10000)
+           nb_days = 10000;
     }
 
     runtapes = getconf_int(CNF_RUNTAPES);
@@ -770,18 +853,24 @@ char **argv;
                printf("The next Amanda run should go onto ");
            else
                printf("                                   ");
-           if(tp != NULL)
-               printf("tape %s or ", tp->label);
-           printf("a new tape.\n");
+           if(tp != NULL) {
+               printf("tape %s or a new tape.\n", tp->label);
+           } else {
+               if (runtapes - i == 1)
+                   printf("1 new tape.\n");
+               else
+                   printf("%d new tapes.\n", runtapes - i);
+               i = runtapes;
+           }
        
            tp = lookup_last_reusable_tape(i + 1);
        }
     }
     lasttp = lookup_tapepos(lookup_nb_tape());
     i = runtapes;
-    if(lasttp && i > 0 && lasttp->datestamp == 0) {
+    if(lasttp && i > 0 && strcmp(lasttp->datestamp,"0") == 0) {
        int c = 0;
-       while(lasttp && i > 0 && lasttp->datestamp == 0) {
+       while(lasttp && i > 0 && strcmp(lasttp->datestamp,"0") == 0) {
            c++;
            lasttp = lasttp->prev;
            i--;
@@ -797,7 +886,7 @@ char **argv;
                   lasttp->label);
            lasttp = lasttp->prev;
            c--;
-           while(lasttp && c > 0 && lasttp->datestamp == 0) {
+           while(lasttp && c > 0 && strcmp(lasttp->datestamp,"0") == 0) {
                printf(", %s", lasttp->label);
                lasttp = lasttp->prev;
                c--;
@@ -809,28 +898,28 @@ char **argv;
 
 /* ----------------------------------------------- */
 
-void balance(argc, argv)
-int argc;
-char **argv;
+void
+balance(
+    int                argc,
+    char **    argv)
 {
     disk_t *dp;
     struct balance_stats {
        int disks;
-       long origsize, outsize;
+       off_t origsize, outsize;
     } *sp;
     int conf_runspercycle, conf_dumpcycle;
     int seq, runs_per_cycle, overdue, max_overdue;
     int later, total, balance, distinct;
-    float fseq, disk_dumpcycle;
+    double fseq, disk_dumpcycle;
     info_t info;
-    long int total_balanced, balanced;
+    off_t total_balanced, balanced;
     int empty_day;
 
     time(&today);
     conf_dumpcycle = getconf_int(CNF_DUMPCYCLE);
     conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
     later = conf_dumpcycle;
-    if(later > 10000) later = 10000;
     overdue = 0;
     max_overdue = 0;
 
@@ -838,6 +927,7 @@ char **argv;
        later = atoi(argv[4]);
        if(later < 0) later = conf_dumpcycle;
     }
+    if(later > 10000) later = 10000;
 
     if(conf_runspercycle == 0) {
        runs_per_cycle = conf_dumpcycle;
@@ -855,10 +945,12 @@ char **argv;
     distinct = later + 3;
 
     sp = (struct balance_stats *)
-       alloc(sizeof(struct balance_stats) * (distinct+1));
+       alloc(SIZEOF(struct balance_stats) * (distinct+1));
 
-    for(seq=0; seq <= distinct; seq++)
-       sp[seq].disks = sp[seq].origsize = sp[seq].outsize = 0;
+    for(seq=0; seq <= distinct; seq++) {
+       sp[seq].disks = 0;
+       sp[seq].origsize = sp[seq].outsize = (off_t)0;
+    }
 
     for(dp = diskq.head; dp != NULL; dp = dp->next) {
        if(get_info(dp->host->hostname, dp->name, &info)) {
@@ -869,24 +961,24 @@ char **argv;
            continue;
        }
        sp[distinct].disks++;
-       sp[distinct].origsize += info.inf[0].size/unitdivisor;
-       sp[distinct].outsize += info.inf[0].csize/unitdivisor;
+       sp[distinct].origsize += info.inf[0].size/(off_t)unitdivisor;
+       sp[distinct].outsize += info.inf[0].csize/(off_t)unitdivisor;
 
        sp[balance].disks++;
        if(dp->dumpcycle == 0) {
-           sp[balance].origsize += (info.inf[0].size/unitdivisor) * runs_per_cycle;
-           sp[balance].outsize += (info.inf[0].csize/unitdivisor) * runs_per_cycle;
+           sp[balance].origsize += (info.inf[0].size/(off_t)unitdivisor) * (off_t)runs_per_cycle;
+           sp[balance].outsize += (info.inf[0].csize/(off_t)unitdivisor) * (off_t)runs_per_cycle;
        }
        else {
-           sp[balance].origsize += (info.inf[0].size/unitdivisor) *
-                                   (conf_dumpcycle / dp->dumpcycle);
-           sp[balance].outsize += (info.inf[0].csize/unitdivisor) *
-                                  (conf_dumpcycle / dp->dumpcycle);
+           sp[balance].origsize += (info.inf[0].size/(off_t)unitdivisor) *
+                                   (off_t)(conf_dumpcycle / dp->dumpcycle);
+           sp[balance].outsize += (info.inf[0].csize/(off_t)unitdivisor) *
+                                  (off_t)(conf_dumpcycle / dp->dumpcycle);
        }
 
-       disk_dumpcycle = dp->dumpcycle;
+       disk_dumpcycle = (double)dp->dumpcycle;
        if(dp->dumpcycle <= 0)
-           disk_dumpcycle = ((float)conf_dumpcycle) / ((float)runs_per_cycle);
+           disk_dumpcycle = ((double)conf_dumpcycle) / ((double)runs_per_cycle);
 
        seq = next_level0(dp, &info);
        fseq = seq + 0.0001;
@@ -903,34 +995,34 @@ char **argv;
            }
            
            sp[seq].disks++;
-           sp[seq].origsize += info.inf[0].size/unitdivisor;
-           sp[seq].outsize += info.inf[0].csize/unitdivisor;
+           sp[seq].origsize += info.inf[0].size/(off_t)unitdivisor;
+           sp[seq].outsize += info.inf[0].csize/(off_t)unitdivisor;
 
            if(seq < later) {
                sp[total].disks++;
-               sp[total].origsize += info.inf[0].size/unitdivisor;
-               sp[total].outsize += info.inf[0].csize/unitdivisor;
+               sp[total].origsize += info.inf[0].size/(off_t)unitdivisor;
+               sp[total].outsize += info.inf[0].csize/(off_t)unitdivisor;
            }
            
            /* See, if there's another run in this dumpcycle */
            fseq += disk_dumpcycle;
-           seq = fseq;
+           seq = (int)fseq;
        } while (seq < later);
     }
 
-    if(sp[total].outsize == 0 && sp[later].outsize == 0) {
+    if(sp[total].outsize == (off_t)0 && sp[later].outsize == (off_t)0) {
        printf("\nNo data to report on yet.\n");
        amfree(sp);
        return;
     }
 
-    balanced = sp[balance].outsize / runs_per_cycle;
+    balanced = sp[balance].outsize / (off_t)runs_per_cycle;
     if(conf_dumpcycle == later) {
-       total_balanced = sp[total].outsize / runs_per_cycle;
+       total_balanced = sp[total].outsize / (off_t)runs_per_cycle;
     }
     else {
-       total_balanced = 1024*(((sp[total].outsize/1024) * conf_dumpcycle)
-                           / (runs_per_cycle * later));
+       total_balanced = (((sp[total].outsize/(off_t)1024) * (off_t)conf_dumpcycle)
+                           / (off_t)(runs_per_cycle * later)) * (off_t)1024;
     }
 
     empty_day = 0;
@@ -948,35 +1040,46 @@ char **argv;
                printf("\n");
                empty_day = 0;
            }
-           printf("%-9.9s  %3d %10ld %10ld ",
+           printf("%-9.9s  %3d " OFF_T_FMT " " OFF_T_FMT " ",
                   seqdatestr(seq), sp[seq].disks,
-                  sp[seq].origsize, sp[seq].outsize);
+                  (OFF_T_FMT_TYPE)sp[seq].origsize,
+                  (OFF_T_FMT_TYPE)sp[seq].outsize);
            if(!sp[seq].outsize) printf("     --- \n");
-           else printf("%+8.1f%%\n",
-                       (sp[seq].outsize-balanced)*100.0/(double)balanced);
+           else printf("%+8.1lf%%\n",
+                       (((double)sp[seq].outsize - (double)balanced) * 100.0 /
+                       (double)balanced));
        }
     }
 
     if(sp[later].disks != 0) {
-       printf("later      %3d %10ld %10ld ",
+       printf("later      %3d " OFF_T_FMT " " OFF_T_FMT " ",
               sp[later].disks,
-              sp[later].origsize, sp[later].outsize);
+              (OFF_T_FMT_TYPE)sp[later].origsize,
+              (OFF_T_FMT_TYPE)sp[later].outsize);
        if(!sp[later].outsize) printf("     --- \n");
-       else printf("%+8.1f%%\n",
-                   (sp[later].outsize-balanced)*100.0/(double)balanced);
+       else printf("%+8.1lf%%\n",
+                   (((double)sp[later].outsize - (double)balanced) * 100.0 /
+                   (double)balanced));
     }
     printf("----------------------------------------------\n");
-    printf("TOTAL      %3d %10ld %10ld %9ld\n", sp[total].disks,
-          sp[total].origsize, sp[total].outsize, total_balanced);
+    printf("TOTAL      %3d " OFF_T_FMT " " OFF_T_FMT " " OFF_T_FMT "\n",
+          sp[total].disks,
+          (OFF_T_FMT_TYPE)sp[total].origsize,
+          (OFF_T_FMT_TYPE)sp[total].outsize,
+          (OFF_T_FMT_TYPE)total_balanced);
     if (sp[balance].origsize != sp[total].origsize ||
         sp[balance].outsize != sp[total].outsize ||
        balanced != total_balanced) {
-       printf("BALANCED       %10ld %10ld %9ld\n",
-              sp[balance].origsize, sp[balance].outsize, balanced);
+       printf("BALANCED       " OFF_T_FMT " " OFF_T_FMT " " OFF_T_FMT "\n",
+              (OFF_T_FMT_TYPE)sp[balance].origsize,
+              (OFF_T_FMT_TYPE)sp[balance].outsize,
+              (OFF_T_FMT_TYPE)balanced);
     }
     if (sp[distinct].disks != sp[total].disks) {
-       printf("DISTINCT   %3d %10ld %10ld\n", sp[distinct].disks,
-              sp[distinct].origsize, sp[distinct].outsize);
+       printf("DISTINCT   %3d " OFF_T_FMT " " OFF_T_FMT "\n",
+              sp[distinct].disks,
+              (OFF_T_FMT_TYPE)sp[distinct].origsize,
+              (OFF_T_FMT_TYPE)sp[distinct].outsize);
     }
     printf("  (estimated %d run%s per dumpcycle)\n",
           runs_per_cycle, (runs_per_cycle == 1) ? "" : "s");
@@ -991,13 +1094,15 @@ char **argv;
 
 /* ----------------------------------------------- */
 
-void find(argc, argv)
-int argc;
-char **argv;
+void
+find(
+    int                argc,
+    char **    argv)
 {
     int start_argc;
     char *sort_order = NULL;
     find_result_t *output_find;
+    char *errstr;
 
     if(argc < 3) {
        fprintf(stderr,
@@ -1009,10 +1114,10 @@ char **argv;
 
     sort_order = newstralloc(sort_order, DEFAULT_SORT_ORDER);
     if(argc > 4 && strcmp(argv[3],"--sort") == 0) {
-       int i, valid_sort=1;
+       size_t i, valid_sort=1;
 
-       for(i=strlen(argv[4])-1;i>=0;i--) {
-           switch (argv[4][i]) {
+       for(i = strlen(argv[4]); i > 0; i--) {
+           switch (argv[4][i - 1]) {
            case 'h':
            case 'H':
            case 'k':
@@ -1021,6 +1126,8 @@ char **argv;
            case 'D':
            case 'l':
            case 'L':
+           case 'p':
+           case 'P':
            case 'b':
            case 'B':
                    break;
@@ -1037,11 +1144,21 @@ char **argv;
     } else {
        start_argc=4;
     }
-    match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
+    errstr = match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
+    if (errstr) {
+       printf("%s", errstr);
+       amfree(errstr);
+    }
+
     output_find = find_dump(1, &diskq);
     if(argc-(start_argc-1) > 0) {
        free_find_result(&output_find);
-       match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
+       errstr = match_disklist(&diskq, argc-(start_argc-1),
+                                       argv+(start_argc-1));
+       if (errstr) {
+           printf("%s", errstr);
+           amfree(errstr);
+       }
        output_find = find_dump(0, NULL);
     }
 
@@ -1058,31 +1175,37 @@ char **argv;
 
 /* shared code with planner.c */
 
-int bump_thresh(level)
-int level;
+int
+bump_thresh(
+    int                level)
 {
     int bump = getconf_int(CNF_BUMPSIZE);
     double mult = getconf_real(CNF_BUMPMULT);
 
-    while(--level) bump = (int) bump * mult;
+    while(--level)
+       bump = (int)((double)bump * mult);
     return bump;
 }
 
-void bumpsize(argc, argv)
-int argc;
-char **argv;
+void
+bumpsize(
+    int                argc,
+    char **    argv)
 {
     int l;
     int conf_bumppercent = getconf_int(CNF_BUMPPERCENT);
     double conf_bumpmult = getconf_real(CNF_BUMPMULT);
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
+
     printf("Current bump parameters:\n");
     if(conf_bumppercent == 0) {
        printf("  bumpsize %5d KB\t- minimum savings (threshold) to bump level 1 -> 2\n",
               getconf_int(CNF_BUMPSIZE));
        printf("  bumpdays %5d\t- minimum days at each level\n",
               getconf_int(CNF_BUMPDAYS));
-       printf("  bumpmult %5.5g\t- threshold = bumpsize * bumpmult**(level-1)\n\n",
+       printf("  bumpmult %5.5lg\t- threshold = bumpsize * bumpmult**(level-1)\n\n",
               conf_bumpmult);
 
        printf("      Bump -> To  Threshold\n");
@@ -1091,17 +1214,17 @@ char **argv;
        putchar('\n');
     }
     else {
-       double bumppercent = conf_bumppercent;
+       double bumppercent = (double)conf_bumppercent;
 
        printf("  bumppercent %3d %%\t- minimum savings (threshold) to bump level 1 -> 2\n",
               conf_bumppercent);
        printf("  bumpdays %5d\t- minimum days at each level\n",
               getconf_int(CNF_BUMPDAYS));
-       printf("  bumpmult %5.5g\t- threshold = disk_size * bumppercent * bumpmult**(level-1)\n\n",
+       printf("  bumpmult %5.5lg\t- threshold = disk_size * bumppercent * bumpmult**(level-1)\n\n",
               conf_bumpmult);
        printf("      Bump -> To  Threshold\n");
        for(l = 1; l < 9; l++) {
-           printf("\t%d  ->  %d  %7.2f %%\n", l, l+1, bumppercent);
+           printf("\t%d  ->  %d  %7.2lf %%\n", l, l+1, bumppercent);
            bumppercent *= conf_bumpmult;
            if(bumppercent >= 100.000) { bumppercent = 100.0;}
        }
@@ -1111,11 +1234,12 @@ char **argv;
 
 /* ----------------------------------------------- */
 
-void export_one P((disk_t *dp));
+void export_one(disk_t *dp);
 
-void export_db(argc, argv)
-int argc;
-char **argv;
+void
+export_db(
+    int                argc,
+    char **    argv)
 {
     disk_t *dp;
     time_t curtime;
@@ -1125,9 +1249,11 @@ char **argv;
     printf("CURINFO Version %s CONF %s\n", version(), getconf_str(CNF_ORG));
 
     curtime = time(0);
-    if(gethostname(hostname, sizeof(hostname)-1) == -1)
+    if(gethostname(hostname, SIZEOF(hostname)-1) == -1) {
        error("could not determine host name: %s\n", strerror(errno));
-    hostname[sizeof(hostname)-1] = '\0';
+       /*NOTREACHED*/
+    }
+    hostname[SIZEOF(hostname)-1] = '\0';
     printf("# Generated by:\n#    host: %s\n#    date: %s",
           hostname, ctime(&curtime));
 
@@ -1144,8 +1270,9 @@ char **argv;
        export_one(dp);
 }
 
-void export_one(dp)
-disk_t *dp;
+void
+export_one(
+    disk_t *   dp)
 {
     info_t info;
     int i,l;
@@ -1156,50 +1283,63 @@ disk_t *dp;
        return;
     }
     printf("host: %s\ndisk: %s\n", dp->host->hostname, dp->name);
-    printf("command: %d\n", info.command);
+    printf("command: %u\n", info.command);
     printf("last_level: %d\n",info.last_level);
     printf("consecutive_runs: %d\n",info.consecutive_runs);
     printf("full-rate:");
-    for(i=0;i<AVG_COUNT;i++) printf(" %f", info.full.rate[i]);
+    for(i=0;i<AVG_COUNT;i++) printf(" %lf", info.full.rate[i]);
     printf("\nfull-comp:");
-    for(i=0;i<AVG_COUNT;i++) printf(" %f", info.full.comp[i]);
+    for(i=0;i<AVG_COUNT;i++) printf(" %lf", info.full.comp[i]);
 
     printf("\nincr-rate:");
-    for(i=0;i<AVG_COUNT;i++) printf(" %f", info.incr.rate[i]);
+    for(i=0;i<AVG_COUNT;i++) printf(" %lf", info.incr.rate[i]);
     printf("\nincr-comp:");
-    for(i=0;i<AVG_COUNT;i++) printf(" %f", info.incr.comp[i]);
+    for(i=0;i<AVG_COUNT;i++) printf(" %lf", info.incr.comp[i]);
     printf("\n");
     for(l=0;l<DUMP_LEVELS;l++) {
        if(info.inf[l].date < (time_t)0 && info.inf[l].label[0] == '\0') continue;
-       printf("stats: %d %ld %ld %ld %ld %d %s\n", l,
-              info.inf[l].size, info.inf[l].csize, info.inf[l].secs,
-              (long)info.inf[l].date, info.inf[l].filenum,
+       printf("stats: %d " OFF_T_FMT " " OFF_T_FMT " " TIME_T_FMT " " TIME_T_FMT " " OFF_T_FMT " %s\n", l,
+              (OFF_T_FMT_TYPE)info.inf[l].size,
+              (OFF_T_FMT_TYPE)info.inf[l].csize,
+              (TIME_T_FMT_TYPE)info.inf[l].secs,
+              (TIME_T_FMT_TYPE)info.inf[l].date,
+              (OFF_T_FMT_TYPE)info.inf[l].filenum,
               info.inf[l].label);
     }
     for(l=0;info.history[l].level > -1;l++) {
-       printf("history: %d %ld %ld %ld\n",info.history[l].level,
-              info.history[l].size, info.history[l].csize,
-              info.history[l].date);
+       printf("history: %d " OFF_T_FMT " " OFF_T_FMT " " TIME_T_FMT "\n",
+              info.history[l].level,
+              (OFF_T_FMT_TYPE)info.history[l].size,
+              (OFF_T_FMT_TYPE)info.history[l].csize,
+              (TIME_T_FMT_TYPE)info.history[l].date);
     }
     printf("//\n");
 }
 
 /* ----------------------------------------------- */
 
-int import_one P((void));
-char *impget_line P((void));
+int import_one(void);
+char *impget_line(void);
 
-void import_db(argc, argv)
-int argc;
-char **argv;
+void
+import_db(
+    int                argc,
+    char **    argv)
 {
-    int vers_maj, vers_min, vers_patch, newer;
+    int vers_maj;
+    int vers_min;
+    int vers_patch;
+    int newer;
     char *org;
     char *line = NULL;
     char *hdr;
     char *s;
+    int rc;
     int ch;
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
+
     /* process header line */
 
     if((line = agets(stdin)) == NULL) {
@@ -1212,10 +1352,10 @@ char **argv;
 
     hdr = "version";
 #define sc "CURINFO Version"
-    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+    if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
        goto bad_header;
     }
-    s += sizeof(sc)-1;
+    s += SIZEOF(sc)-1;
     ch = *s++;
 #undef sc
     skip_whitespace(s, ch);
@@ -1246,10 +1386,10 @@ char **argv;
     hdr = "CONF";
     skip_whitespace(s, ch);                    /* find the org keyword */
 #define sc "CONF"
-    if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+    if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
        goto bad_header;
     }
-    s += sizeof(sc)-1;
+    s += SIZEOF(sc)-1;
     ch = *s++;
 #undef sc
 
@@ -1260,6 +1400,7 @@ char **argv;
     }
     org = s - 1;
 
+    /*@ignore@*/
     newer = (vers_maj != VERSION_MAJOR)? vers_maj > VERSION_MAJOR :
            (vers_min != VERSION_MINOR)? vers_min > VERSION_MINOR :
                                         vers_patch > VERSION_PATCH;
@@ -1267,20 +1408,23 @@ char **argv;
        fprintf(stderr,
             "%s: WARNING: input is from newer Amanda version: %d.%d.%d.\n",
                get_pname(), vers_maj, vers_min, vers_patch);
+    /*@end@*/
 
     if(strcmp(org, getconf_str(CNF_ORG)) != 0) {
        fprintf(stderr, "%s: WARNING: input is from different org: %s\n",
                get_pname(), org);
     }
 
-    while(import_one());
+    do {
+       rc = import_one();
+    } while (rc);
 
     amfree(line);
     return;
 
  bad_header:
 
-    amfree(line);
+    /*@i@*/ amfree(line);
     fprintf(stderr, "%s: bad CURINFO header line in input: %s.\n",
            get_pname(), hdr);
     fprintf(stderr, "    Was the input in \"amadmin export\" format?\n");
@@ -1288,24 +1432,27 @@ char **argv;
 }
 
 
-int import_one P((void))
+int
+import_one(void)
 {
     info_t info;
     stats_t onestat;
     int rc, level;
-    long onedate;
+    time_t onedate;
+    time_t *onedate_p = &onedate;
     char *line = NULL;
     char *s, *fp;
     int ch;
     int nb_history, i;
     char *hostname = NULL;
     char *diskname = NULL;
+    time_t *secs_p;
 
 #if TEXTDB
     check_dumpuser();
 #endif
 
-    memset(&info, 0, sizeof(info_t));
+    memset(&info, 0, SIZEOF(info_t));
 
     for(level = 0; level < DUMP_LEVELS; level++) {
         info.inf[level].date = (time_t)-1;
@@ -1321,8 +1468,8 @@ int import_one P((void))
 
     skip_whitespace(s, ch);
 #define sc "host:"
-    if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) goto parse_err;
-    s += sizeof(sc)-1;
+    if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) goto parse_err;
+    s += SIZEOF(sc)-1;
     ch = s[-1];
 #undef sc
     skip_whitespace(s, ch);
@@ -1331,7 +1478,7 @@ int import_one P((void))
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     hostname = stralloc(fp);
-    s[-1] = ch;
+    s[-1] = (char)ch;
 
     skip_whitespace(s, ch);
     while (ch == 0) {
@@ -1342,8 +1489,8 @@ int import_one P((void))
       skip_whitespace(s, ch);
     }
 #define sc "disk:"
-    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) goto parse_err;
-    s += sizeof(sc)-1;
+    if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) goto parse_err;
+    s += SIZEOF(sc)-1;
     ch = s[-1];
 #undef sc
     skip_whitespace(s, ch);
@@ -1352,11 +1499,11 @@ int import_one P((void))
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     diskname = stralloc(fp);
-    s[-1] = ch;
+    s[-1] = (char)ch;
 
     amfree(line);
     if((line = impget_line()) == NULL) goto shortfile_err;
-    if(sscanf(line, "command: %d", &info.command) != 1) goto parse_err;
+    if(sscanf(line, "command: %u", &info.command) != 1) goto parse_err;
 
     /* get last_level and consecutive_runs */
 
@@ -1373,13 +1520,13 @@ int import_one P((void))
 
     /* get rate: and comp: lines for full dumps */
 
-    rc = sscanf(line, "full-rate: %f %f %f",
+    rc = sscanf(line, "full-rate: %lf %lf %lf",
                &info.full.rate[0], &info.full.rate[1], &info.full.rate[2]);
     if(rc != 3) goto parse_err;
 
     amfree(line);
     if((line = impget_line()) == NULL) goto shortfile_err;
-    rc = sscanf(line, "full-comp: %f %f %f",
+    rc = sscanf(line, "full-comp: %lf %lf %lf",
                &info.full.comp[0], &info.full.comp[1], &info.full.comp[2]);
     if(rc != 3) goto parse_err;
 
@@ -1387,13 +1534,13 @@ int import_one P((void))
 
     amfree(line);
     if((line = impget_line()) == NULL) goto shortfile_err;
-    rc = sscanf(line, "incr-rate: %f %f %f",
+    rc = sscanf(line, "incr-rate: %lf %lf %lf",
                &info.incr.rate[0], &info.incr.rate[1], &info.incr.rate[2]);
     if(rc != 3) goto parse_err;
 
     amfree(line);
     if((line = impget_line()) == NULL) goto shortfile_err;
-    rc = sscanf(line, "incr-comp: %f %f %f",
+    rc = sscanf(line, "incr-comp: %lf %lf %lf",
                &info.incr.comp[0], &info.incr.comp[1], &info.incr.comp[2]);
     if(rc != 3) goto parse_err;
 
@@ -1410,17 +1557,17 @@ int import_one P((void))
            /* end of record */
            break;
        }
-       memset(&onestat, 0, sizeof(onestat));
+       memset(&onestat, 0, SIZEOF(onestat));
 
        s = line;
        ch = *s++;
 
        skip_whitespace(s, ch);
 #define sc "stats:"
-       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
            goto parse_err;
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
 
@@ -1431,32 +1578,37 @@ int import_one P((void))
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.size) != 1) {
+       if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&onestat.size) != 1) {
            goto parse_err;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.csize) != 1) {
+       if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&onestat.csize) != 1) {
            goto parse_err;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.secs) != 1) {
+        secs_p = &onestat.secs;
+       if(ch == '\0' || sscanf(s - 1, TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)secs_p) != 1) {
            goto parse_err;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf(s - 1, "%ld", &onedate) != 1) {
+       if(ch == '\0' || sscanf(s - 1, TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)onedate_p) != 1) {
            goto parse_err;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
        if(ch != '\0') {
-           if(sscanf(s - 1, "%d", &onestat.filenum) != 1) {
+           if(sscanf(s - 1, OFF_T_FMT, (OFF_T_FMT_TYPE *)&onestat.filenum) != 1) {
                goto parse_err;
            }
            skip_integer(s, ch);
@@ -1467,13 +1619,13 @@ int import_one P((void))
                    goto parse_err;
                onestat.label[0] = '\0';
            } else {
-               strncpy(onestat.label, s - 1, sizeof(onestat.label)-1);
-               onestat.label[sizeof(onestat.label)-1] = '\0';
+               strncpy(onestat.label, s - 1, SIZEOF(onestat.label)-1);
+               onestat.label[SIZEOF(onestat.label)-1] = '\0';
            }
        }
 
        /* time_t not guarranteed to be long */
-       onestat.date = onedate;
+       /*@i1@*/ onestat.date = onedate;
        if(level < 0 || level > 9) goto parse_err;
 
        info.inf[level] = onestat;
@@ -1484,21 +1636,22 @@ int import_one P((void))
     }
     while(1) {
        history_t onehistory;
-       long date;
+       time_t date;
+        time_t *date_p = &date;
 
        if(line[0] == '/' && line[1] == '/') {
            info.history[nb_history].level = -2;
            rc = 0;
            break;
        }
-       memset(&onehistory, 0, sizeof(onehistory));
+       memset(&onehistory, 0, SIZEOF(onehistory));
        s = line;
        ch = *s++;
 #define sc "history:"
-       if(strncmp(line, sc, sizeof(sc)-1) != 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) != 0) {
            break;
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
        skip_whitespace(s, ch);
@@ -1508,29 +1661,32 @@ int import_one P((void))
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &onehistory.size) != 1) {
+       if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&onehistory.size) != 1) {
            break;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &onehistory.csize) != 1) {
+       if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&onehistory.csize) != 1) {
            break;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &date) != 1) {
+       if((ch == '\0') || (sscanf((s - 1), TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)date_p) != 1)) {
            break;
        }
        skip_integer(s, ch);
-       onehistory.date = date; /* time_t not guarranteed to be long */
+       /*@i1@*/onehistory.date = date; /* time_t not guarranteed to be long */
 
        info.history[nb_history++] = onehistory;
        amfree(line);
        if((line = impget_line()) == NULL) goto shortfile_err;
     }
-    amfree(line);
+    /*@i@*/ amfree(line);
 
     /* got a full record, now write it out to the database */
 
@@ -1543,14 +1699,14 @@ int import_one P((void))
     return 1;
 
  parse_err:
-    amfree(line);
+    /*@i@*/ amfree(line);
     amfree(hostname);
     amfree(diskname);
     fprintf(stderr, "%s: parse error reading import record.\n", get_pname());
     return 0;
 
  shortfile_err:
-    amfree(line);
+    /*@i@*/ amfree(line);
     amfree(hostname);
     amfree(diskname);
     fprintf(stderr, "%s: short file reading import record.\n", get_pname());
@@ -1558,7 +1714,7 @@ int import_one P((void))
 }
 
 char *
-impget_line ()
+impget_line(void)
 {
     char *line;
     char *s;
@@ -1587,8 +1743,9 @@ impget_line ()
 
 /* ----------------------------------------------- */
 
-void disklist_one(dp)
-disk_t *dp;
+void
+disklist_one(
+    disk_t *   dp)
 {
     am_host_t *hp;
     interface_t *ip;
@@ -1604,7 +1761,6 @@ disk_t *dp;
     printf("    host %s:\n", hp->hostname);
     printf("        interface %s\n",
           ip->name[0] ? ip->name : "default");
-
     printf("    disk %s:\n", dp->name);
     if(dp->device) printf("        device %s\n", dp->device);
 
@@ -1639,18 +1795,19 @@ disk_t *dp;
        }
        printf("\n");
     }
-    printf("        priority %ld\n", dp->priority);
-    printf("        dumpcycle %ld\n", dp->dumpcycle);
+    printf("        priority %d\n", dp->priority);
+    printf("        dumpcycle %d\n", dp->dumpcycle);
     printf("        maxdumps %d\n", dp->maxdumps);
     printf("        maxpromoteday %d\n", dp->maxpromoteday);
     if(dp->bumppercent > 0) {
        printf("        bumppercent %d\n", dp->bumppercent);
     }
     else {
-       printf("        bumpsize %d\n", dp->bumpsize);
+       printf("        bumpsize " OFF_T_FMT "\n",
+               (OFF_T_FMT_TYPE)dp->bumpsize);
     }
     printf("        bumpdays %d\n", dp->bumpdays);
-    printf("        bumpmult %f\n", dp->bumpmult);
+    printf("        bumpmult %lf\n", dp->bumpmult);
 
     printf("        strategy ");
     switch(dp->strategy) {
@@ -1706,7 +1863,7 @@ disk_t *dp;
        break;
     }
     if(dp->compress != COMP_NONE) {
-       printf("        comprate %.2f %.2f\n",
+       printf("        comprate %.2lf %.2lf\n",
               dp->comprate[0], dp->comprate[1]);
     }
 
@@ -1725,34 +1882,57 @@ disk_t *dp;
 
     printf("        auth %s\n", dp->security_driver);
     printf("        kencrypt %s\n", (dp->kencrypt? "YES" : "NO"));
-    printf("        holdingdisk %s\n", (!dp->no_hold? "YES" : "NO"));
+    printf("        amandad_path %s\n", dp->amandad_path);
+    printf("        client_username %s\n", dp->client_username);
+    printf("        ssh_keys %s\n", dp->ssh_keys);
+
+    printf("        holdingdisk ");
+    switch(dp->to_holdingdisk) {
+    case HOLD_NEVER:
+       printf("NEVER\n");
+       break;
+    case HOLD_AUTO:
+       printf("AUTO\n");
+       break;
+    case HOLD_REQUIRED:
+       printf("REQUIRED\n");
+       break;
+    }
+
     printf("        record %s\n", (dp->record? "YES" : "NO"));
     printf("        index %s\n", (dp->index? "YES" : "NO"));
     st = dp->start_t;
         if(st) {
             stm = localtime(&st);
-            printf("        starttime %d:%02d:%02d\n",
-              stm->tm_hour, stm->tm_min, stm->tm_sec);
+           if (stm) 
+               printf("        starttime %d:%02d:%02d\n",
+                      stm->tm_hour, stm->tm_min, stm->tm_sec);
+           else
+               printf("        starttime BAD DATE\n");
         }
    
-    if(dp->tape_splitsize > 0) {
-       printf("        tape_splitsize %ld\n", dp->tape_splitsize);
+    if(dp->tape_splitsize > (off_t)0) {
+       printf("        tape_splitsize " OFF_T_FMT "\n",
+              (OFF_T_FMT_TYPE)dp->tape_splitsize);
     }
     if(dp->split_diskbuffer) {
        printf("        split_diskbuffer %s\n", dp->split_diskbuffer);
     }
-    if(dp->fallback_splitsize > 0) {
-       printf("        fallback_splitsize %ldMb\n", (dp->fallback_splitsize / 1024));
+    if(dp->fallback_splitsize > (off_t)0) {
+       printf("        fallback_splitsize " OFF_T_FMT "Mb\n",
+              (OFF_T_FMT_TYPE)(dp->fallback_splitsize / (off_t)1024));
     }
     printf("        skip-incr %s\n", (dp->skip_incr? "YES" : "NO"));
     printf("        skip-full %s\n", (dp->skip_full? "YES" : "NO"));
+    printf("        spindle %d\n", dp->spindle);
 
     printf("\n");
 }
 
-void disklist(argc, argv)
-int argc;
-char **argv;
+void
+disklist(
+    int                argc,
+    char **    argv)
 {
     disk_t *dp;
 
@@ -1763,12 +1943,27 @@ char **argv;
            disklist_one(dp);
 }
 
-void show_version(argc, argv)
-int argc;
-char **argv;
+void
+show_version(
+    int                argc,
+    char **    argv)
 {
     int i;
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
+
     for(i = 0; version_info[i] != NULL; i++)
        printf("%s", version_info[i]);
 }
+
+
+void show_config(
+    int argc,
+    char **argv)
+{
+    argc = argc;
+    argv = argv;
+    dump_configuration(conffile);
+}
+
index dd1b5c71eec0ce3fcad384587f7c395bef6e42d8..123786c6af1e55993fd34f276c8cb31dd864390d 100755 (executable)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! @SHELL@
 #
 # Copyright (c) 2005 Zmanda Inc.  All Rights Reserved.
 # 
index 36ab3d957e10cfdfdb009495ae6c001b477c5fab..9e83962ea1ba19cdf84a5241a592870213b6a933 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amcheck.c,v 1.121 2006/02/06 22:17:09 ktill Exp $
+ * $Id: amcheck.c,v 1.149 2006/08/24 01:57:16 paddy_s Exp $
  *
  * checks for common problems in server and clients
  */
@@ -50,7 +50,7 @@
 
 #define BUFFER_SIZE    32768
 
-static int conf_ctimeout;
+static time_t conf_ctimeout;
 static int overwrite;
 
 static disklist_t origq;
@@ -59,16 +59,17 @@ static uid_t uid_dumpuser;
 
 /* local functions */
 
-void usage P((void));
-int start_client_checks P((int fd));
-int start_server_check P((int fd, int do_localchk, int do_tapechk));
-int main P((int argc, char **argv));
-int test_server_pgm P((FILE *outf, char *dir, char *pgm,
-                      int suid, uid_t dumpuid));
+void usage(void);
+pid_t start_client_checks(int fd);
+pid_t start_server_check(int fd, int do_localchk, int do_tapechk);
+int main(int argc, char **argv);
+int test_server_pgm(FILE *outf, char *dir, char *pgm, int suid, uid_t dumpuid);
 
-void usage()
+void
+usage(void)
 {
-    error("Usage: amcheck%s [-M <username>] [-mawsclt] <conf> [host [disk]* ]*", versionsuffix());
+    error("Usage: amcheck%s [-am] [-w] [-sclt] [-M <address>] <conf> [host [disk]* ]* [-o configoption]*", versionsuffix());
+    /*NOTREACHED*/
 }
 
 static unsigned long malloc_hist_1, malloc_size_1;
@@ -79,18 +80,20 @@ static char *our_feature_string = NULL;
 static char *displayunit;
 static long int unitdivisor;
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     char buffer[BUFFER_SIZE];
     char *version_string;
     char *mainfname = NULL;
     char pid_str[NUM_STR_SIZE];
-    int do_clientchk, clientchk_pid, client_probs;
-    int do_localchk, do_tapechk, serverchk_pid, server_probs;
-    int chk_flag;
-    int opt, size, tempfd, mainfd;
+    int do_clientchk, client_probs;
+    int do_localchk, do_tapechk, server_probs;
+    pid_t clientchk_pid, serverchk_pid;
+    int opt, tempfd, mainfd;
+    ssize_t size;
     amwait_t retstat;
     pid_t pid;
     extern int optind;
@@ -104,6 +107,9 @@ char **argv;
     char *dumpuser;
     struct passwd *pw;
     uid_t uid_me;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
+    char *errstr;
 
     safe_fd(-1, 0);
     safe_cd();
@@ -113,11 +119,12 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-    dbopen();
+    dbopen(DBG_SUBDIR_SERVER);
 
+    memset(buffer, 0, sizeof(buffer));
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
-    snprintf(pid_str, sizeof(pid_str), "%ld", (long)getpid());
+    snprintf(pid_str, SIZEOF(pid_str), "%ld", (long)getpid());
 
     erroutput_type = ERR_INTERACTIVE;
 
@@ -131,15 +138,23 @@ char **argv;
 
     alwaysmail = mailout = overwrite = 0;
     do_localchk = do_tapechk = do_clientchk = 0;
-    chk_flag = 0;
     server_probs = client_probs = 0;
     tempfd = mainfd = -1;
 
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
     /* process arguments */
 
-    while((opt = getopt(argc, argv, "M:mawsclt")) != EOF) {
+    while((opt = getopt(my_argc, my_argv, "M:mawsclt")) != EOF) {
        switch(opt) {
        case 'M':       mailto=stralloc(optarg);
+                       if(!validate_mailto(mailto)){
+                          printf("Invalid characters in mail address\n");
+                          exit(1);
+                       }
+                       /*FALLTHROUGH*/
        case 'm':       
 #ifdef MAILER
                        mailout = 1;
@@ -159,43 +174,77 @@ char **argv;
                        exit(1);
 #endif
                        break;
-       case 's':       do_localchk = 1; do_tapechk = 1;
-                       chk_flag = 1;
+       case 's':       do_localchk = do_clientchk = do_tapechk = 1;
                        break;
        case 'c':       do_clientchk = 1;
-                       chk_flag = 1;
                        break;
        case 'l':       do_localchk = 1;
-                       chk_flag = 1;
                        break;
-       case 'w':       do_tapechk = 1; overwrite = 1;
-                       chk_flag = 1;
+       case 'w':       overwrite = 1;
                        break;
        case 't':       do_tapechk = 1;
-                       chk_flag = 1;
                        break;
        case '?':
        default:
            usage();
        }
     }
-    argc -= optind, argv += optind;
-    if(! chk_flag) {
+    my_argc -= optind, my_argv += optind;
+    if(my_argc < 1) usage();
+
+
+    if ((do_localchk | do_clientchk | do_tapechk) == 0) {
+       /* Check everything if individual checks were not asked for */
        do_localchk = do_clientchk = do_tapechk = 1;
     }
 
-    if(argc < 1) usage();
+    if(overwrite)
+       do_tapechk = 1;
 
-    config_name = stralloc(*argv);
+    config_name = stralloc(*my_argv);
 
     config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if(read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
+
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     amfree(conffile);
+    if(mailout && !mailto && 
+       (getconf_seen(CNF_MAILTO)==0 || strlen(getconf_str(CNF_MAILTO)) == 0)) {
+       printf("\nNo mail address configured in  amanda.conf\n");
+        if(alwaysmail)        
+               printf("When using -a option please specify -Maddress also\n\n"); 
+       else
+               printf("Use -Maddress instead of -m\n\n"); 
+       exit(1);
+    }
+    if(mailout && !mailto)
+    { 
+       if(getconf_seen(CNF_MAILTO) && 
+          strlen(getconf_str(CNF_MAILTO)) > 0) {
+          if(!validate_mailto(getconf_str(CNF_MAILTO))){
+               printf("\nMail address in amanda.conf has invalid characters"); 
+               printf("\nNo email will be sent\n"); 
+                mailout = 0;
+          }
+       }
+       else {
+         printf("\nNo mail address configured in  amanda.conf\n");
+          if(alwaysmail)        
+               printf("When using -a option please specify -Maddress also\n\n"); 
+         else
+               printf("Use -Maddress instead of -m\n\n"); 
+         exit(1);
+      }
+    }
 
-    conf_ctimeout = getconf_int(CNF_CTIMEOUT);
+    conf_ctimeout = getconf_time(CNF_CTIMEOUT);
 
     conf_diskfile = getconf_str(CNF_DISKFILE);
     if (*conf_diskfile == '/') {
@@ -205,8 +254,13 @@ char **argv;
     }
     if(read_diskfile(conf_diskfile, &origq) < 0) {
        error("could not load disklist %s", conf_diskfile);
+       /*NOTREACHED*/
+    }
+    errstr = match_disklist(&origq, my_argc-1, my_argv+1);
+    if (errstr) {
+       printf("%s",errstr);
+       amfree(errstr);
     }
-    match_disklist(&origq, argc-1, argv+1);
     amfree(conf_diskfile);
 
     /*
@@ -215,15 +269,17 @@ char **argv;
     dumpuser = getconf_str(CNF_DUMPUSER);
     if ((pw = getpwnam(dumpuser)) == NULL) {
        error("cannot look up dump user \"%s\"", dumpuser);
+       /*NOTREACHED*/
     }
     uid_dumpuser = pw->pw_uid;
     if ((pw = getpwuid(uid_me)) == NULL) {
        error("cannot look up my own uid (%ld)", (long)uid_me);
+       /*NOTREACHED*/
     }
     if (uid_me != uid_dumpuser) {
        error("running as user \"%s\" instead of \"%s\"",
-             pw->pw_name,
-             dumpuser);
+             pw->pw_name, dumpuser);
+        /*NOTREACHED*/
     }
 
     displayunit = getconf_str(CNF_DISPLAYUNIT);
@@ -240,8 +296,10 @@ char **argv;
     if(do_clientchk && (do_localchk || do_tapechk)) {
        /* we need the temp file */
        tempfname = vstralloc(AMANDA_TMPDIR, "/amcheck.temp.", pid_str, NULL);
-       if((tempfd = open(tempfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1)
+       if((tempfd = open(tempfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) {
            error("could not open %s: %s", tempfname, strerror(errno));
+           /*NOTREACHED*/
+       }
        unlink(tempfname);                      /* so it goes away on close */
        amfree(tempfname);
     }
@@ -249,8 +307,10 @@ char **argv;
     if(mailout) {
        /* the main fd is a file too */
        mainfname = vstralloc(AMANDA_TMPDIR, "/amcheck.main.", pid_str, NULL);
-       if((mainfd = open(mainfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1)
+       if((mainfd = open(mainfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) {
            error("could not open %s: %s", mainfname, strerror(errno));
+           /*NOTREACHED*/
+       }
        unlink(mainfname);                      /* so it goes away on close */
        amfree(mainfname);
     }
@@ -289,11 +349,13 @@ char **argv;
            char number[NUM_STR_SIZE];
            char *wait_msg = NULL;
 
-           snprintf(number, sizeof(number), "%ld", (long)pid);
+           snprintf(number, SIZEOF(number), "%ld", (long)pid);
            wait_msg = vstralloc("parent: reaped bogus pid ", number, "\n",
                                 NULL);
-           if (fullwrite(mainfd, wait_msg, strlen(wait_msg)) < 0)
+           if (fullwrite(mainfd, wait_msg, strlen(wait_msg)) < 0) {
                error("write main file: %s", strerror(errno));
+               /*NOTREACHED*/
+           }
            amfree(wait_msg);
        }
     }
@@ -301,23 +363,31 @@ char **argv;
     /* copy temp output to main output and write tagline */
 
     if(do_clientchk && (do_localchk || do_tapechk)) {
-       if(lseek(tempfd, 0, 0) == -1)
+       if(lseek(tempfd, (off_t)0, 0) == (off_t)-1) {
            error("seek temp file: %s", strerror(errno));
+           /*NOTREACHED*/
+       }
 
-       while((size=fullread(tempfd, buffer, sizeof(buffer))) > 0) {
-           if (fullwrite(mainfd, buffer, size) < 0)
+       while((size = fullread(tempfd, buffer, SIZEOF(buffer))) > 0) {
+           if (fullwrite(mainfd, buffer, (size_t)size) < 0) {
                error("write main file: %s", strerror(errno));
+               /*NOTREACHED*/
+           }
        }
-       if(size < 0)
+       if(size < 0) {
            error("read temp file: %s", strerror(errno));
+           /*NOTREACHED*/
+       }
        aclose(tempfd);
     }
 
     version_string = vstralloc("\n",
                               "(brought to you by Amanda ", version(), ")\n",
                               NULL);
-    if (fullwrite(mainfd, version_string, strlen(version_string)) < 0)
+    if (fullwrite(mainfd, version_string, strlen(version_string)) < 0) {
        error("write main file: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
     amfree(version_string);
     amfree(config_dir);
     amfree(config_name);
@@ -344,10 +414,8 @@ char **argv;
        char *subject;
        char **a;
        amwait_t retstat;
-       pid_t mailpid;
-       pid_t wpid;
-       int r;
-       int w;
+       ssize_t r;
+       ssize_t w;
        char *err = NULL;
        char *extra_info = NULL;
        char *line = NULL;
@@ -357,8 +425,9 @@ char **argv;
        char number[NUM_STR_SIZE];
 
        fflush(stdout);
-       if(lseek(mainfd, (off_t)0, SEEK_SET) == -1) {
+       if(lseek(mainfd, (off_t)0, SEEK_SET) == (off_t)-1) {
            error("lseek main file: %s", strerror(errno));
+           /*NOTREACHED*/
        }
        if(alwaysmail && !(server_probs || client_probs)) {
            subject = stralloc2(getconf_str(CNF_ORG),
@@ -375,19 +444,20 @@ char **argv;
         * Remember that split() returns the original input string in
         * argv[0], so we have to skip over that.
         */
-       a = (char **) alloc((MAILTO_LIMIT + 1) * sizeof(char *));
-       memset(a, 0, (MAILTO_LIMIT + 1) * sizeof(char *));
+       a = (char **) alloc((MAILTO_LIMIT + 1) * SIZEOF(char *));
+       memset(a, 0, (MAILTO_LIMIT + 1) * SIZEOF(char *));
        if(mailto) {
            a[1] = mailto;
            a[2] = NULL;
        } else {
-           r = split(getconf_str(CNF_MAILTO), a, MAILTO_LIMIT, " ");
+           r = (ssize_t)split(getconf_str(CNF_MAILTO), a, MAILTO_LIMIT, " ");
            a[r + 1] = NULL;
        }
        if((nullfd = open("/dev/null", O_RDWR)) < 0) {
            error("nullfd: /dev/null: %s", strerror(errno));
+           /*NOTREACHED*/
        }
-       mailpid = pipespawn(MAILER, STDIN_PIPE | STDERR_PIPE,
+       pipespawn(MAILER, STDIN_PIPE | STDERR_PIPE,
                            &mailfd, &nullfd, &errfd,
                            MAILER,
                            "-s", subject,
@@ -402,28 +472,36 @@ char **argv;
         * cases, the pipe will break and we will exit out of the loop.
         */
        signal(SIGPIPE, SIG_IGN);
-       while((r = fullread(mainfd, buffer, sizeof(buffer))) > 0) {
-           if((w = fullwrite(mailfd, buffer, r)) != r) {
+       while((r = fullread(mainfd, buffer, SIZEOF(buffer))) > 0) {
+           if((w = fullwrite(mailfd, buffer, (size_t)r)) != (ssize_t)r) {
                if(w < 0 && errno == EPIPE) {
                    strappend(extra_info, "EPIPE writing to mail process\n");
                    break;
                } else if(w < 0) {
                    error("mailfd write: %s", strerror(errno));
+                   /*NOTREACHED*/
                } else {
                    error("mailfd write: wrote %d instead of %d", w, r);
+                   /*NOTREACHED*/
                }
            }
        }
        aclose(mailfd);
        ferr = fdopen(errfd, "r");
+       if (!ferr) {
+           error("Can't fdopen: %s", strerror(errno));
+           /*NOTREACHED*/
+       }
        for(; (line = agets(ferr)) != NULL; free(line)) {
+           if (line[0] == '\0')
+               continue;
            strappend(extra_info, line);
            strappend(extra_info, "\n");
        }
        afclose(ferr);
        errfd = -1;
        rc = 0;
-       while ((wpid = wait(&retstat)) != -1) {
+       while (wait(&retstat) != -1) {
            if (WIFSIGNALED(retstat)) {
                    ret = 0;
                    rc = sig = WTERMSIG(retstat);
@@ -438,7 +516,7 @@ char **argv;
                    } else {
                        strappend(err, "returned ");
                    }
-                   snprintf(number, sizeof(number), "%d", ret);
+                   snprintf(number, SIZEOF(number), "%d", ret);
                    strappend(err, number);
            }
        }
@@ -448,9 +526,13 @@ char **argv;
                amfree(extra_info);
            }
            error("error running mailer %s: %s", MAILER, err);
+           /*NOTREACHED*/
        }
     }
 #endif
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
+
     dbclose();
     return (server_probs || client_probs);
 }
@@ -463,58 +545,71 @@ char *first_match_label = NULL, *first_match = NULL, *found_device = NULL;
 char *label;
 char *searchlabel, *labelstr;
 tape_t *tp;
-FILE *errf;
-
-int test_server_pgm(outf, dir, pgm, suid, dumpuid)
-FILE *outf;
-char *dir;
-char *pgm;
-int suid;
-uid_t dumpuid;
+FILE *errf = NULL;
+
+int
+test_server_pgm(
+    FILE *     outf,
+    char *     dir,
+    char *     pgm,
+    int                suid,
+    uid_t      dumpuid)
 {
     struct stat statbuf;
     int pgmbad = 0;
+    char *quoted;
 
     pgm = vstralloc(dir, "/", pgm, versionsuffix(), NULL);
+    quoted = quote_string(pgm);
     if(stat(pgm, &statbuf) == -1) {
        fprintf(outf, "ERROR: program %s: does not exist\n",
-               pgm);
+               quoted);
        pgmbad = 1;
     } else if (!S_ISREG(statbuf.st_mode)) {
        fprintf(outf, "ERROR: program %s: not a file\n",
-               pgm);
+               quoted);
        pgmbad = 1;
     } else if (access(pgm, X_OK) == -1) {
        fprintf(outf, "ERROR: program %s: not executable\n",
-               pgm);
+               quoted);
        pgmbad = 1;
     } else if (suid \
               && dumpuid != 0
               && (statbuf.st_uid != 0 || (statbuf.st_mode & 04000) == 0)) {
-       fprintf(outf, "WARNING: program %s: not setuid-root\n",
-               pgm);
+       fprintf(outf, "ERROR: program %s: not setuid-root\n",
+               quoted);
+       pgmbad = 1;
     }
+    amfree(quoted);
     amfree(pgm);
     return pgmbad;
 }
 
-int start_server_check(fd, do_localchk, do_tapechk)
-    int fd;
-    int do_localchk, do_tapechk;
+pid_t
+start_server_check(
+    int                fd,
+    int                do_localchk,
+    int                do_tapechk)
 {
     char *tapename;
     generic_fs_stats_t fs;
-    FILE *outf;
+    FILE *outf = NULL;
     holdingdisk_t *hdp;
-    int pid;
+    pid_t pid;
     int confbad = 0, tapebad = 0, disklow = 0, logbad = 0;
     int userbad = 0, infobad = 0, indexbad = 0, pgmbad = 0;
     int testtape = do_tapechk;
     tapetype_t *tp = NULL;
+    char *quoted;
 
     switch(pid = fork()) {
-    case -1: error("could not fork server check: %s", strerror(errno));
-    case 0: break;
+    case -1:
+       error("could not fork server check: %s", strerror(errno));
+       /*NOTREACHED*/
+
+    case 0:
+       break;
+
     default:
        return pid;
     }
@@ -526,8 +621,10 @@ int start_server_check(fd, do_localchk, do_tapechk)
 
     startclock();
 
-    if((outf = fdopen(fd, "w")) == NULL)
+    if((outf = fdopen(fd, "w")) == NULL) {
        error("fdopen %d: %s", fd, strerror(errno));
+       /*NOTREACHED*/
+    }
     errf = outf;
 
     fprintf(outf, "Amanda Tape Server Host Check\n");
@@ -551,7 +648,7 @@ int start_server_check(fd, do_localchk, do_tapechk)
            amfree(errstr);
            confbad = 1;
        }
-       lbl_templ = tp->lbl_templ;
+       lbl_templ = tapetype_get_lbl_templ(tp);
        if(strcmp(lbl_templ, "") != 0) {
            if(strchr(lbl_templ, '/') == NULL) {
                lbl_templ = stralloc2(config_dir, lbl_templ);
@@ -570,61 +667,61 @@ int start_server_check(fd, do_localchk, do_tapechk)
            confbad = 1;
 #endif
        }
+
+       /* check that localhost is resolvable */
+       if ((gethostbyname("localhost")) == NULL) {
+           fprintf(outf, "ERROR: Cannot resolve `localhost'.\n");
+       }
     }
 
     /*
      * Look up the programs used on the server side.
      */
     if(do_localchk) {
-       int suid_check=1;
-#ifdef SSH_SECURITY
-       suid_check=0;
-#endif 
+       /* 
+        * entreprise version will do planner/dumper suid check
+        */
        if(access(libexecdir, X_OK) == -1) {
+           quoted = quote_string(libexecdir);
            fprintf(outf, "ERROR: program dir %s: not accessible\n",
-                   libexecdir);
+                   quoted);
            pgmbad = 1;
+           amfree(quoted);
        } else {
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, libexecdir, "planner",
-                                       suid_check, uid_dumpuser);
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, libexecdir, "dumper",
-                                       suid_check, uid_dumpuser);
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, libexecdir, "driver",
-                                       0, uid_dumpuser);
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, libexecdir, "taper",
-                                       0, uid_dumpuser);
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, libexecdir, "amtrmidx",
-                                       0, uid_dumpuser);
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, libexecdir, "amlogroll",
-                                       0, uid_dumpuser);
+           if(test_server_pgm(outf, libexecdir, "planner", 1, uid_dumpuser))
+               pgmbad = 1;
+           if(test_server_pgm(outf, libexecdir, "dumper", 1, uid_dumpuser))
+               pgmbad = 1;
+           if(test_server_pgm(outf, libexecdir, "driver", 0, uid_dumpuser))
+               pgmbad = 1;
+           if(test_server_pgm(outf, libexecdir, "taper", 0, uid_dumpuser))
+               pgmbad = 1;
+           if(test_server_pgm(outf, libexecdir, "amtrmidx", 0, uid_dumpuser))
+               pgmbad = 1;
+           if(test_server_pgm(outf, libexecdir, "amlogroll", 0, uid_dumpuser))
+               pgmbad = 1;
        }
        if(access(sbindir, X_OK) == -1) {
+           quoted = quote_string(sbindir);
            fprintf(outf, "ERROR: program dir %s: not accessible\n",
                    sbindir);
            pgmbad = 1;
+           amfree(quoted);
        } else {
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, sbindir, "amgetconf",
-                                       0, uid_dumpuser);
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, sbindir, "amcheck",
-                                       1, uid_dumpuser);
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, sbindir, "amdump",
-                                       0, uid_dumpuser);
-           pgmbad = pgmbad \
-                    || test_server_pgm(outf, sbindir, "amreport",
-                                       0, uid_dumpuser);
+           if(test_server_pgm(outf, sbindir, "amgetconf", 0, uid_dumpuser))
+               pgmbad = 1;
+           if(test_server_pgm(outf, sbindir, "amcheck", 1, uid_dumpuser))
+               pgmbad = 1;
+           if(test_server_pgm(outf, sbindir, "amdump", 0, uid_dumpuser))
+               pgmbad = 1;
+           if(test_server_pgm(outf, sbindir, "amreport", 0, uid_dumpuser))
+               pgmbad = 1;
        }
        if(access(COMPRESS_PATH, X_OK) == -1) {
+           quoted = quote_string(COMPRESS_PATH);
            fprintf(outf, "WARNING: %s is not executable, server-compression and indexing will not work\n",
-                   COMPRESS_PATH);
+                   quoted);
+           amfree(quoted);
        }
     }
 
@@ -660,31 +757,47 @@ int start_server_check(fd, do_localchk, do_tapechk)
         */
        }
        if(access(tape_dir, W_OK) == -1) {
-           fprintf(outf, "ERROR: tapelist dir %s: not writable.\n", tape_dir);
+           quoted = quote_string(tape_dir);
+           fprintf(outf, "ERROR: tapelist dir %s: not writable.\n", quoted);
            tapebad = 1;
+           amfree(quoted);
        }
        else if(stat(tapefile, &statbuf) == -1) {
-           fprintf(outf, "ERROR: tapefile %s: %s, you must create an empty file.\n",
-                   tapefile, strerror(errno));
+           quoted = quote_string(tape_dir);
+           fprintf(outf, "ERROR: tapefile %s (%s), "
+                   "you must create an empty file.\n",
+                   quoted, strerror(errno));
            tapebad = 1;
+           amfree(quoted);
        }
        else if(!S_ISREG(statbuf.st_mode)) {
-           fprintf(outf, "ERROR: tapefile %s: should be a regular file.\n", tapefile);
+           quoted = quote_string(tapefile);
+           fprintf(outf, "ERROR: tapefile %s: should be a regular file.\n",
+                   quoted);
            tapebad = 1;
+           amfree(quoted);
        }
        else if(access(tapefile, F_OK) != 0) {
-           fprintf(outf, "ERROR: can't access tape list %s\n", tapefile);
+           quoted = quote_string(tapefile);
+           fprintf(outf, "ERROR: can't access tape list %s\n", quoted);
            tapebad = 1;
+           amfree(quoted);
        } else if(access(tapefile, F_OK) == 0 && access(tapefile, W_OK) != 0) {
-           fprintf(outf, "ERROR: tape list %s: not writable\n", tapefile);
+           quoted = quote_string(tapefile);
+           fprintf(outf, "ERROR: tape list %s: not writable\n", quoted);
            tapebad = 1;
+           amfree(quoted);
        } else if(read_tapelist(tapefile)) {
-           fprintf(outf, "ERROR: tape list %s: parse error\n", tapefile);
+           quoted = quote_string(tapefile);
+           fprintf(outf, "ERROR: tape list %s: parse error\n", quoted);
            tapebad = 1;
+           amfree(quoted);
        }
        holdfile = vstralloc(config_dir, "/", "hold", NULL);
        if(access(holdfile, F_OK) != -1) {
+           quoted = quote_string(holdfile);
            fprintf(outf, "WARNING: hold file %s exists\n", holdfile);
+           amfree(quoted);
        }
        amfree(tapefile);
        amfree(tape_dir);
@@ -703,48 +816,73 @@ int start_server_check(fd, do_localchk, do_tapechk)
 
     if(do_localchk) {
        for(hdp = holdingdisks; hdp != NULL; hdp = hdp->next) {
-           if(get_fs_stats(hdp->diskdir, &fs) == -1) {
-               fprintf(outf, "ERROR: holding dir %s: %s, you must create a directory.\n",
-                       hdp->diskdir, strerror(errno));
+           quoted = quote_string(holdingdisk_get_diskdir(hdp));
+           if(get_fs_stats(holdingdisk_get_diskdir(hdp), &fs) == -1) {
+               fprintf(outf, "ERROR: holding dir %s (%s), "
+                       "you must create a directory.\n",
+                       quoted, strerror(errno));
                disklow = 1;
            }
-           else if(access(hdp->diskdir, W_OK) == -1) {
+           else if(access(holdingdisk_get_diskdir(hdp), W_OK) == -1) {
                fprintf(outf, "ERROR: holding disk %s: not writable: %s.\n",
-                       hdp->diskdir, strerror(errno));
+                       quoted, strerror(errno));
+               disklow = 1;
+           }
+           else if(access(holdingdisk_get_diskdir(hdp), X_OK) == -1) {
+               fprintf(outf, "ERROR: holding disk %s: not searcheable: %s.\n",
+                       quoted, strerror(errno));
                disklow = 1;
            }
-           else if(fs.avail == -1) {
+           else if(fs.avail == (off_t)-1) {
                fprintf(outf,
-                       "WARNING: holding disk %s: available space unknown (%ld KB requested)\n",
-                       hdp->diskdir, (long)hdp->disksize);
+                       "WARNING: holding disk %s: "
+                       "available space unknown (" OFF_T_FMT" KB requested)\n",
+                       quoted, (OFF_T_FMT_TYPE)holdingdisk_get_disksize(hdp));
                disklow = 1;
            }
-           else if(hdp->disksize > 0) {
-               if(fs.avail < hdp->disksize) {
+           else if(holdingdisk_get_disksize(hdp) > (off_t)0) {
+               if(fs.avail < holdingdisk_get_disksize(hdp)) {
                    fprintf(outf,
-                           "WARNING: holding disk %s: only %ld %sB free (%ld %sB requested)\n",
-                           hdp->diskdir, (long)fs.avail/unitdivisor, displayunit,
-                           (long)hdp->disksize/unitdivisor, displayunit);
+                           "WARNING: holding disk %s: "
+                           "only " OFF_T_FMT " %sB free ("
+                           OFF_T_FMT " %sB requested)\n", quoted,
+                           (OFF_T_FMT_TYPE)(fs.avail / (off_t)unitdivisor),
+                           displayunit,
+                           (OFF_T_FMT_TYPE)(holdingdisk_get_disksize(hdp)/(off_t)unitdivisor),
+                           displayunit);
                    disklow = 1;
                }
-               else
+               else {
                    fprintf(outf,
-                           "Holding disk %s: %ld %sB disk space available, that's plenty\n",
-                           hdp->diskdir, fs.avail/unitdivisor, displayunit);
+                           "Holding disk %s: " OFF_T_FMT
+                           " %sB disk space available, that's plenty\n",
+                           quoted, (OFF_T_FMT_TYPE)(fs.avail/(off_t)unitdivisor),
+                           displayunit);
+               }
            }
            else {
-               if(fs.avail < -hdp->disksize) {
+               assert(holdingdisk_get_disksize(hdp) < (off_t)0);
+               if((fs.avail + holdingdisk_get_disksize(hdp)) <= (off_t)0) {
                    fprintf(outf,
-                           "WARNING: holding disk %s: only %ld %sB free, using nothing\n",
-                           hdp->diskdir, fs.avail/unitdivisor, displayunit);
+                           "WARNING: holding disk %s: "
+                           "only " OFF_T_FMT " %sB free, using nothing\n",
+                           quoted, (OFF_T_FMT_TYPE)(fs.avail/(off_t)unitdivisor),
+                           displayunit);
                    disklow = 1;
                }
-               else
+               else {
                    fprintf(outf,
-                           "Holding disk %s: %ld %sB disk space available, using %ld %sB\n",
-                           hdp->diskdir, fs.avail/unitdivisor, displayunit,
-                           (fs.avail + hdp->disksize)/unitdivisor, displayunit);
+                           "Holding disk %s: "
+                           OFF_T_FMT " %sB disk space available, using "
+                           OFF_T_FMT " %sB\n",
+                           quoted,
+                           (OFF_T_FMT_TYPE)(fs.avail/(off_t)unitdivisor),
+                           displayunit,
+                           (OFF_T_FMT_TYPE)(fs.avail + holdingdisk_get_disksize(hdp) / (off_t)unitdivisor),
+                           displayunit);
+               }
            }
+           amfree(quoted);
        }
     }
 
@@ -765,36 +903,44 @@ int start_server_check(fd, do_localchk, do_tapechk)
        }
        logfile = vstralloc(conf_logdir, "/log", NULL);
 
+       quoted = quote_string(conf_logdir);
        if(stat(conf_logdir, &statbuf) == -1) {
-           fprintf(outf, "ERROR: logdir %s: %s, you must create a directory.\n",
-                   conf_logdir, strerror(errno));
+           fprintf(outf, "ERROR: logdir %s (%s), you must create directory.\n",
+                   quoted, strerror(errno));
            disklow = 1;
        }
        else if(access(conf_logdir, W_OK) == -1) {
-           fprintf(outf, "ERROR: log dir %s: not writable\n", conf_logdir);
+           fprintf(outf, "ERROR: log dir %s: not writable\n", quoted);
            logbad = 1;
        }
+       amfree(quoted);
 
        if(access(logfile, F_OK) == 0) {
            testtape = 0;
            logbad = 1;
-           if(access(logfile, W_OK) != 0)
-               fprintf(outf, "ERROR: log file %s: not writable\n",
-                       logfile);
+           if(access(logfile, W_OK) != 0) {
+               quoted = quote_string(logfile);
+               fprintf(outf, "ERROR: log file %s: not writable\n", quoted);
+               amfree(quoted);
+           }
        }
 
        olddir = vstralloc(conf_logdir, "/oldlog", NULL);
+       quoted = quote_string(olddir);
        if (stat(olddir,&stat_old) == 0) { /* oldlog exist */
            if(!(S_ISDIR(stat_old.st_mode))) {
-               fprintf(outf, "ERROR: oldlog directory \"%s\" is not a directory\n", olddir);
+               fprintf(outf, "ERROR: oldlog directory %s is not a directory\n",
+                       quoted);
            }
            if(access(olddir, W_OK) == -1) {
-               fprintf(outf, "ERROR: oldlog dir %s: not writable\n", olddir);
+               fprintf(outf, "ERROR: oldlog dir %s: not writable\n", quoted);
            }
        }
        else if(lstat(olddir,&stat_old) == 0) {
-           fprintf(outf, "ERROR: oldlog directory \"%s\" is not a directory\n", olddir);
+           fprintf(outf, "ERROR: oldlog directory %s is not a directory\n",
+                   quoted);
        }
+       amfree(quoted);
 
        if (testtape) {
            logfile = newvstralloc(logfile, conf_logdir, "/amdump", NULL);
@@ -804,13 +950,13 @@ int start_server_check(fd, do_localchk, do_tapechk)
            }
        }
 
+       amfree(olddir);
        amfree(logfile);
        amfree(conf_logdir);
     }
 
     if (testtape) {
        /* check that the tape is a valid amanda tape */
-        char *error_msg;
         int tape_status;
 
        tapedays = getconf_int(CNF_TAPECYCLE);
@@ -822,20 +968,19 @@ int start_server_check(fd, do_localchk, do_tapechk)
                    "WARNING: if a tape changer is not available, runtapes must be set to 1\n");
        }
 
-        tape_status = taper_scan(NULL, &label, &datestamp, &error_msg,
-                                 &tapename);
-        fprintf(outf, "%s\n", error_msg);
-        amfree(error_msg);
+        tape_status = taper_scan(NULL, &label, &datestamp, &tapename,
+                                FILE_taperscan_output_callback, outf);
         if (tape_status < 0) {
            tape_t *exptape = lookup_last_reusable_tape(0);
            fprintf(outf, "       (expecting ");
            if(exptape != NULL) fprintf(outf, "tape %s or ", exptape->label);
            fprintf(outf, "a new tape)\n");
+            tapebad = 1;
        } else {
             if (overwrite) {
                 char *wrlabel_status;
                 wrlabel_status = tape_wrlabel(tapename, "X", label,
-                                              tp->blocksize * 1024);
+                               (unsigned)(tapetype_get_blocksize(tp) * 1024));
                 if (wrlabel_status != NULL) {
                     if (tape_status == 3) {
                         fprintf(outf,
@@ -865,6 +1010,7 @@ int start_server_check(fd, do_localchk, do_tapechk)
                 }                    
             }
         }
+       amfree(tapename);
     } else if (do_tapechk) {
        fprintf(outf, "WARNING: skipping tape test because amdump or amflush seem to be running\n");
        fprintf(outf, "WARNING: if they are not, you must run amcleanup\n");
@@ -916,21 +1062,29 @@ int start_server_check(fd, do_localchk, do_tapechk)
        }
 
 #if TEXTDB
+       quoted = quote_string(conf_infofile);
        if(stat(conf_infofile, &statbuf) == -1) {
-           fprintf(outf, "NOTE: info dir %s: does not exist\n", conf_infofile);
-           fprintf(outf, "NOTE: it will be created on the next run.\n");
+           if (errno == ENOENT) {
+               fprintf(outf, "NOTE: conf info dir %s does not exist\n",
+                       quoted);
+               fprintf(outf, "NOTE: it will be created on the next run.\n");
+           } else {
+               fprintf(outf, "ERROR: conf info dir %s (%s)\n",
+                       quoted, strerror(errno));
+           }   
            amfree(conf_infofile);
        } else if (!S_ISDIR(statbuf.st_mode)) {
-           fprintf(outf, "ERROR: info dir %s: not a directory\n", conf_infofile);
+           fprintf(outf, "ERROR: info dir %s: not a directory\n", quoted);
            amfree(conf_infofile);
            infobad = 1;
        } else if (access(conf_infofile, W_OK) == -1) {
-           fprintf(outf, "ERROR: info dir %s: not writable\n", conf_infofile);
+           fprintf(outf, "ERROR: info dir %s: not writable\n", quoted);
            amfree(conf_infofile);
            infobad = 1;
        } else {
            strappend(conf_infofile, "/");
        }
+       amfree(quoted);
 #endif
 
        while(!empty(origq)) {
@@ -939,135 +1093,191 @@ int start_server_check(fd, do_localchk, do_tapechk)
 #if TEXTDB
            if(conf_infofile) {
                hostinfodir = newstralloc2(hostinfodir, conf_infofile, host);
+               quoted = quote_string(hostinfodir);
                if(stat(hostinfodir, &statbuf) == -1) {
-                   fprintf(outf, "NOTE: info dir %s: does not exist\n",
-                           hostinfodir);
-                   fprintf(outf, "NOTE: it will be created on the next run.\n");
+                   if (errno == ENOENT) {
+                       fprintf(outf, "NOTE: host info dir %s does not exist\n",
+                               quoted);
+                       fprintf(outf,
+                               "NOTE: it will be created on the next run.\n");
+                   } else {
+                       fprintf(outf, "ERROR: host info dir %s (%s)\n",
+                               quoted, strerror(errno));
+                   }   
                    amfree(hostinfodir);
                } else if (!S_ISDIR(statbuf.st_mode)) {
                    fprintf(outf, "ERROR: info dir %s: not a directory\n",
-                           hostinfodir);
+                           quoted);
                    amfree(hostinfodir);
                    infobad = 1;
                } else if (access(hostinfodir, W_OK) == -1) {
-                   fprintf(outf, "ERROR: info dir %s: not writable\n",
-                           hostinfodir);
+                   fprintf(outf, "ERROR: info dir %s: not writable\n", quoted);
                    amfree(hostinfodir);
                    infobad = 1;
                } else {
                    strappend(hostinfodir, "/");
                }
+               amfree(quoted);
            }
 #endif
            for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
                disk = sanitise_filename(dp->name);
 #if TEXTDB
                if(hostinfodir) {
+                   char *quotedif;
+
                    diskdir = newstralloc2(diskdir, hostinfodir, disk);
                    infofile = vstralloc(diskdir, "/", "info", NULL);
+                   quoted = quote_string(diskdir);
+                   quotedif = quote_string(infofile);
                    if(stat(diskdir, &statbuf) == -1) {
-                       fprintf(outf, "NOTE: info dir %s: does not exist\n",
-                               diskdir);
-                       fprintf(outf, "NOTE: it will be created on the next run.\n");
+                       if (errno == ENOENT) {
+                           fprintf(outf, "NOTE: info dir %s does not exist\n",
+                               quoted);
+                           fprintf(outf,
+                               "NOTE: it will be created on the next run.\n");
+                       } else {
+                           fprintf(outf, "ERROR: info dir %s (%s)\n",
+                                   quoted, strerror(errno));
+                       }       
                    } else if (!S_ISDIR(statbuf.st_mode)) {
                        fprintf(outf, "ERROR: info dir %s: not a directory\n",
-                               diskdir);
+                               quoted);
                        infobad = 1;
                    } else if (access(diskdir, W_OK) == -1) {
                        fprintf(outf, "ERROR: info dir %s: not writable\n",
-                               diskdir);
+                               quoted);
                        infobad = 1;
                    } else if(stat(infofile, &statbuf) == -1) {
-                       fprintf(outf, "WARNING: info file %s: does not exist\n",
-                               infofile);
-                       fprintf(outf, "NOTE: it will be created on the next run.\n");
+                       if (errno == ENOENT) {
+                           fprintf(outf, "NOTE: info file %s does not exist\n",
+                                   quotedif);
+                           fprintf(outf, "NOTE: it will be created on the next run.\n");
+                       } else {
+                           fprintf(outf, "ERROR: info dir %s (%s)\n",
+                               quoted, strerror(errno));
+                       }       
                    } else if (!S_ISREG(statbuf.st_mode)) {
                        fprintf(outf, "ERROR: info file %s: not a file\n",
-                               infofile);
+                               quotedif);
                        infobad = 1;
                    } else if (access(infofile, R_OK) == -1) {
                        fprintf(outf, "ERROR: info file %s: not readable\n",
-                               infofile);
+                               quotedif);
                        infobad = 1;
                    }
+                   amfree(quotedif);
+                   amfree(quoted);
                    amfree(infofile);
                }
 #endif
                if(dp->index) {
                    if(! indexdir_checked) {
+                       quoted = quote_string(conf_indexdir);
                        if(stat(conf_indexdir, &statbuf) == -1) {
-                           fprintf(outf, "NOTE: index dir %s: does not exist\n",
-                                   conf_indexdir);
-                           fprintf(outf, "NOTE: it will be created on the next run.\n");
+                           if (errno == ENOENT) {
+                               fprintf(outf, "NOTE: index dir %s does not exist\n",
+                                   quoted);
+                               fprintf(outf, "NOTE: it will be created on the next run.\n");
+                           } else {
+                               fprintf(outf, "ERROR: index dir %s (%s)\n",
+                                       quoted, strerror(errno));
+                           }   
                            amfree(conf_indexdir);
                        } else if (!S_ISDIR(statbuf.st_mode)) {
                            fprintf(outf, "ERROR: index dir %s: not a directory\n",
-                                   conf_indexdir);
+                                   quoted);
                            amfree(conf_indexdir);
                            indexbad = 1;
                        } else if (access(conf_indexdir, W_OK) == -1) {
                            fprintf(outf, "ERROR: index dir %s: not writable\n",
-                                   conf_indexdir);
+                                   quoted);
                            amfree(conf_indexdir);
                            indexbad = 1;
                        } else {
                            strappend(conf_indexdir, "/");
                        }
                        indexdir_checked = 1;
+                       amfree(quoted);
                    }
                    if(conf_indexdir) {
                        if(! hostindexdir_checked) {
                            hostindexdir = stralloc2(conf_indexdir, host);
+                           quoted = quote_string(hostindexdir);
                            if(stat(hostindexdir, &statbuf) == -1) {
-                               fprintf(outf, "NOTE: index dir %s: does not exist\n",
-                                       hostindexdir);
-                               fprintf(outf, "NOTE: it will be created on the next run.\n");
+                               if (errno == ENOENT) {
+                                   fprintf(outf, "NOTE: index dir %s does not exist\n",
+                                       quoted);
+                                   fprintf(outf, "NOTE: it will be created on the next run.\n");
+                               } else {
+                                   fprintf(outf, "ERROR: index dir %s (%s)\n",
+                                           quoted, strerror(errno));
+                               }
                                amfree(hostindexdir);
                            } else if (!S_ISDIR(statbuf.st_mode)) {
                                fprintf(outf, "ERROR: index dir %s: not a directory\n",
-                                       hostindexdir);
+                                       quoted);
                                amfree(hostindexdir);
                                indexbad = 1;
                            } else if (access(hostindexdir, W_OK) == -1) {
                                fprintf(outf, "ERROR: index dir %s: not writable\n",
-                                       hostindexdir);
+                                       quoted);
                                amfree(hostindexdir);
                                indexbad = 1;
                            } else {
                                strappend(hostindexdir, "/");
                            }
                            hostindexdir_checked = 1;
+                           amfree(quoted);
                        }
                        if(hostindexdir) {
                            diskdir = newstralloc2(diskdir, hostindexdir, disk);
+                           quoted = quote_string(diskdir);
                            if(stat(diskdir, &statbuf) == -1) {
-                               fprintf(outf, "NOTE: index dir %s: does not exist\n",
-                                       diskdir);
-                               fprintf(outf, "NOTE: it will be created on the next run.\n");
+                               if (errno == ENOENT) {
+                                   fprintf(outf, "NOTE: index dir %s does not exist\n",
+                                       quoted);
+                                   fprintf(outf, "NOTE: it will be created on the next run.\n");
+                               } else {
+                                   fprintf(outf, "ERROR: index dir %s (%s)\n",
+                                       quoted, strerror(errno));
+                               }       
                            } else if (!S_ISDIR(statbuf.st_mode)) {
                                fprintf(outf, "ERROR: index dir %s: not a directory\n",
-                                       diskdir);
+                                       quoted);
                                indexbad = 1;
                            } else if (access(diskdir, W_OK) == -1) {
                                fprintf(outf, "ERROR: index dir %s: is not writable\n",
-                                       diskdir);
+                                       quoted);
                                indexbad = 1;
                            }
+                           amfree(quoted);
                        }
                    }
                }
 
-               if ( dp->encrypt == ENCRYPT_SERV_CUST && dp->srv_encrypt ) {
-                 if(access(dp->srv_encrypt, X_OK) == -1) {
+               if ( dp->encrypt == ENCRYPT_SERV_CUST ) {
+                 if ( dp->srv_encrypt[0] == '\0' ) {
+                   fprintf(outf, "ERROR: server encryption program not specified\n");
+                   pgmbad = 1;
+                 }
+                 else if(access(dp->srv_encrypt, X_OK) == -1) {
                    fprintf(outf, "ERROR: %s is not executable, server encryption will not work\n",
                            dp->srv_encrypt );
                    pgmbad = 1;
                  }
                }
-               if ( dp->compress == COMP_SERV_CUST && dp->srvcompprog ) {
-                 if(access(dp->srvcompprog, X_OK) == -1) {
+               if ( dp->compress == COMP_SERV_CUST ) {
+                 if ( dp->srvcompprog[0] == '\0' ) {
+                   fprintf(outf, "ERROR: server custom compression program not specified\n");
+                   pgmbad = 1;
+                 }
+                 else if(access(dp->srvcompprog, X_OK) == -1) {
+                   quoted = quote_string(dp->srvcompprog);
+
                    fprintf(outf, "ERROR: %s is not executable, server custom compression will not work\n",
-                           dp->srvcompprog );
+                           quoted);
+                   amfree(quoted);
                    pgmbad = 1;
                  }
                }
@@ -1108,7 +1318,7 @@ int start_server_check(fd, do_localchk, do_tapechk)
         || infobad \
         || indexbad \
         || pgmbad);
-    /* NOTREACHED */
+    /*NOTREACHED*/
     return 0;
 }
 
@@ -1117,7 +1327,8 @@ int start_server_check(fd, do_localchk, do_tapechk)
 int remote_errors;
 FILE *outf;
 
-static void handle_result P((void *, pkt_t *, security_handle_t *));
+static void handle_result(void *, pkt_t *, security_handle_t *);
+void start_host(am_host_t *hostp);
 
 #define HOST_READY                             ((void *)0)     /* must be 0 */
 #define HOST_ACTIVE                            ((void *)1)
@@ -1127,12 +1338,13 @@ static void handle_result P((void *, pkt_t *, security_handle_t *));
 #define DISK_ACTIVE                            ((void *)1)
 #define DISK_DONE                              ((void *)2)
 
-void start_host(hostp)
-    am_host_t *hostp;
+void
+start_host(
+    am_host_t *hostp)
 {
     disk_t *dp;
     char *req = NULL;
-    int req_len = 0;
+    size_t req_len = 0;
     int disk_count;
     const security_driver_t *secdrv;
     char number[NUM_STR_SIZE];
@@ -1162,6 +1374,8 @@ void start_host(hostp)
                                          fe_req_options_hostname);
        int has_maxdumps = am_has_feature(hostp->features,
                                          fe_req_options_maxdumps);
+       int has_config   = am_has_feature(hostp->features,
+                                         fe_req_options_config);
 
        if(!am_has_feature(hostp->features, fe_selfcheck_req) &&
           !am_has_feature(hostp->features, fe_selfcheck_req_device)) {
@@ -1198,7 +1412,7 @@ void start_host(hostp)
                   hostp->hostname);
        }
 
-       snprintf(number, sizeof(number), "%d", hostp->maxdumps);
+       snprintf(number, SIZEOF(number), "%d", hostp->maxdumps);
        req = vstralloc("SERVICE ", "selfcheck", "\n",
                        "OPTIONS ",
                        has_features ? "features=" : "",
@@ -1210,6 +1424,9 @@ void start_host(hostp)
                        has_hostname ? "hostname=" : "",
                        has_hostname ? hostp->hostname : "",
                        has_hostname ? ";" : "",
+                       has_config   ? "config=" : "",
+                       has_config   ? config_name : "",
+                       has_config   ? ";" : "",
                        "\n",
                        NULL);
 
@@ -1218,30 +1435,46 @@ void start_host(hostp)
        req_len += 256;                         /* room for non-disk answers */
        for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
            char *l;
-           int l_len;
+           size_t l_len;
            char *o;
-           char* calcsize;
+           char *calcsize;
+           char *qname;
+           char *qdevice;
 
            if(dp->up != DISK_READY || dp->todo != 1) {
                continue;
            }
            o = optionstr(dp, hostp->features, outf);
+           if (o == NULL) {
+               remote_errors++;
+               continue;
+           }
+           qname = quote_string(dp->name); 
+           qdevice = quote_string(dp->device); 
+           if ((dp->name && qname[0] == '"') || 
+               (dp->device && qdevice[0] == '"')) {
+               if(!am_has_feature(hostp->features, fe_interface_quoted_text)) {
+                   fprintf(outf,
+                           "WARNING: %s:%s:%s host does not support quoted text\n",
+                           hostp->hostname, qname, qdevice);
+               }
+           }
 
            if(dp->device) {
                if(!am_has_feature(hostp->features, fe_selfcheck_req_device)) {
                    fprintf(outf,
                     "ERROR: %s:%s (%s): selfcheck does not support device.\n",
-                    hostp->hostname, dp->name, dp->device);
+                    hostp->hostname, qname, dp->device);
                }
                if(!am_has_feature(hostp->features, fe_sendsize_req_device)) {
                    fprintf(outf,
                     "ERROR: %s:%s (%s): sendsize does not support device.\n",
-                    hostp->hostname, dp->name, dp->device);
+                    hostp->hostname, qname, dp->device);
                }
                if(!am_has_feature(hostp->features, fe_sendbackup_req_device)) {
                    fprintf(outf,
                     "ERROR: %s:%s (%s): sendbackup does not support device.\n",
-                    hostp->hostname, dp->name, dp->device);
+                    hostp->hostname, qname, dp->device);
                }
            }
            if(strncmp(dp->program,"DUMP",4) == 0 || 
@@ -1249,17 +1482,17 @@ void start_host(hostp)
                if(strcmp(dp->program, "DUMP") == 0 &&
                   !am_has_feature(hostp->features, fe_program_dump)) {
                    fprintf(outf, "ERROR: %s:%s does not support DUMP.\n",
-                           hostp->hostname, dp->name);
+                           hostp->hostname, qname);
                }
                if(strcmp(dp->program, "GNUTAR") == 0 &&
                   !am_has_feature(hostp->features, fe_program_gnutar)) {
                    fprintf(outf, "ERROR: %s:%s does not support GNUTAR.\n",
-                           hostp->hostname, dp->name);
+                           hostp->hostname, qname);
                }
                if(dp->estimate == ES_CALCSIZE &&
                   !am_has_feature(hostp->features, fe_calcsize_estimate)) {
                    fprintf(outf, "ERROR: %s:%s does not support CALCSIZE for estimate, using CLIENT.\n",
-                           hostp->hostname, dp->name);
+                           hostp->hostname, qname);
                    dp->estimate = ES_CLIENT;
                }
                if(dp->estimate == ES_CALCSIZE &&
@@ -1291,7 +1524,7 @@ void start_host(hostp)
                if(dp->device) {
                    l = vstralloc(calcsize,
                                  dp->program, " ",
-                                 dp->name, " ",
+                                 qname, " ",
                                  dp->device,
                                  " 0 OPTIONS |",
                                  o,
@@ -1301,7 +1534,7 @@ void start_host(hostp)
                else {
                    l = vstralloc(calcsize,
                                  dp->program, " ",
-                                 dp->name,
+                                 qname,
                                  " 0 OPTIONS |",
                                  o,
                                  "\n",
@@ -1310,12 +1543,12 @@ void start_host(hostp)
            } else {
                if(!am_has_feature(hostp->features, fe_program_dumper_api)) {
                    fprintf(outf, "ERROR: %s:%s does not support DUMPER-API.\n",
-                           hostp->hostname, dp->name);
+                           hostp->hostname, qname);
                }
                l = vstralloc("DUMPER ",
                              dp->program, 
                              " ",
-                             dp->name,
+                             qname,
                              " ",
                              dp->device,
                              " 0 OPTIONS |",
@@ -1323,15 +1556,11 @@ void start_host(hostp)
                              "\n",
                              NULL);
            }
+           amfree(qname);
+           amfree(qdevice);
            l_len = strlen(l);
            amfree(o);
-           /*
-            * Allow 2X for err response.
-            */
-           if(req_len + l_len > MAX_PACKET / 2) {
-               amfree(l);
-               break;
-           }
+
            strappend(req, l);
            req_len += l_len;
            amfree(l);
@@ -1363,8 +1592,9 @@ void start_host(hostp)
     if (secdrv == NULL) {
        error("could not find security driver '%s' for host '%s'",
              hostp->disks->security_driver, hostp->hostname);
+        /*NOTREACHED*/
     }
-    protocol_sendreq(hostp->hostname, secdrv, generic_get_security_conf, 
+    protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf, 
                     req, conf_ctimeout, handle_result, hostp);
 
     amfree(req);
@@ -1372,17 +1602,24 @@ void start_host(hostp)
     hostp->up = HOST_ACTIVE;
 }
 
-int start_client_checks(fd)
-int fd;
+pid_t
+start_client_checks(
+    int                fd)
 {
     am_host_t *hostp;
     disk_t *dp;
-    int hostcount, pid;
+    int hostcount;
+    pid_t pid;
     int userbad = 0;
 
     switch(pid = fork()) {
-    case -1: error("could not fork client check: %s", strerror(errno));
-    case 0: break;
+    case -1:
+       error("could not fork client check: %s", strerror(errno));
+       /*NOTREACHED*/
+
+    case 0:
+       break;
+
     default:
        return pid;
     }
@@ -1394,8 +1631,10 @@ int fd;
 
     startclock();
 
-    if((outf = fdopen(fd, "w")) == NULL)
+    if((outf = fdopen(fd, "w")) == NULL) {
        error("fdopen %d: %s", fd, strerror(errno));
+       /*NOTREACHED*/
+    }
     errf = outf;
 
     fprintf(outf, "\nAmanda Backup Client Hosts Check\n");
@@ -1407,7 +1646,7 @@ int fd;
 
     for(dp = origq.head; dp != NULL; dp = dp->next) {
        hostp = dp->host;
-       if(hostp->up == HOST_READY) {
+       if(hostp->up == HOST_READY && dp->todo == 1) {
            start_host(hostp);
            hostcount++;
            protocol_check();
@@ -1433,14 +1672,15 @@ int fd;
     }
 
     exit(userbad || remote_errors > 0);
-    /* NOTREACHED */
+    /*NOTREACHED*/
     return 0;
 }
 
-static void handle_result(datap, pkt, sech)
-void *datap;
-pkt_t *pkt;
-security_handle_t *sech;
+static void
+handle_result(
+    void *             datap,
+    pkt_t *            pkt,
+    security_handle_t *        sech)
 {
     am_host_t *hostp;
     disk_t *dp;
@@ -1471,19 +1711,19 @@ security_handle_t *sech;
     ch = *s++;
     while(ch) {
        line = s - 1;
-       skip_line(s, ch);
+       skip_quoted_line(s, ch);
        if (s[-2] == '\n') {
            s[-2] = '\0';
        }
 
 #define sc "OPTIONS "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
 #undef sc
 
 #define sc "features="
            t = strstr(line, sc);
            if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
-               t += sizeof(sc)-1;
+               t += SIZEOF(sc)-1;
 #undef sc
                am_release_feature_set(hostp->features);
                if((hostp->features = am_string_to_feature(t)) == NULL) {
@@ -1496,14 +1736,14 @@ security_handle_t *sech;
        }
 
 #define sc "OK "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
            continue;
 #undef sc
        }
 
 #define sc "ERROR "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
-           t = line + sizeof(sc) - 1;
+       if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
+           t = line + SIZEOF(sc) - 1;
            tch = t[-1];
 #undef sc
 
@@ -1513,11 +1753,9 @@ security_handle_t *sech;
             * just means the client is "old" (does not support the service).
             * We can ignore this.
             */
-           if(hostp->features == NULL
-              && pkt->type == P_NAK
-              && (strcmp(t - 1, "unknown service: noop") == 0
-                  || strcmp(t - 1, "noop: invalid service") == 0)) {
-           } else {
+           if(!((hostp->features == NULL) && (pkt->type == P_NAK)
+              && ((strcmp(t - 1, "unknown service: noop") == 0)
+                  || (strcmp(t - 1, "noop: invalid service") == 0)))) {
                fprintf(outf, "ERROR: %s%s: %s\n",
                        (pkt->type == P_NAK) ? "NAK " : "",
                        hostp->hostname,
@@ -1548,4 +1786,6 @@ security_handle_t *sech;
        }
     }
     start_host(hostp);
+    if(hostp->up == HOST_DONE)
+       security_close_connection(sech, hostp->hostname);
 }
index cd374aa97d668971f6cab4e213043a583def7098..ff1f63e598277bf4e986067c090e5668b5dc7c75 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! @SHELL@
 #
 # check tapelist against database and vice versa
 #
@@ -32,6 +32,7 @@ if [ "$Config" = "" ]; then
        log "usage: ${Program} <config>"
        exit 1
 fi
+shift;
 
 #
 # Check if the configuration directory exists.  Make sure that the
@@ -51,7 +52,7 @@ fi
 # Get the location and name of the tapelist filename.  If tapelist is not
 # specified in the amanda.conf file, then use tapelist in the config
 # directory.
-TapeList=`amgetconf${SUF} tapelist`
+TapeList=`amgetconf${SUF} $Config tapelist "@$"`
 if [ ! "$TapeList" ]; then
        TapeList="$ConfigDir/$Config/tapelist"
 fi
@@ -66,7 +67,7 @@ Amadmin=$sbindir/amadmin$SUF
        && echo "$Amadmin not found or not executable" >&2 \
        && exit 1
 
-$Amadmin $Config export \
+$Amadmin $Config export "$@"\
        | grep "^stats: " \
        | while read LINE; do
                [ "$LINE" = "" ] && continue
index 5fc55cbfc93618b21d6c10bd1ad89ec33823cbb7..2590932ca0841ff3a5e242260392da00337c70b7 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 #
 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
 # Copyright (c) 1991-1998 University of Maryland at College Park
@@ -47,47 +47,231 @@ else
        SUF=
 fi
 
-if [ $# -ne 1 ]
-then
-        echo "Usage: amcleanup conf"
-        exit 1
+if test -h /proc/1/exe ; then
+       if test $# -eq 1 ; then
+               KILL_ENABLE=0
+               conf=$1
+               shift;
+       elif test $# -eq 2 && test "$1" == "-k" ; then
+               KILL_ENABLE=1
+               conf=$2
+               shift
+               shift
+       else
+               echo "Usage: amcleanup [-k] conf"
+               exit 1
+       fi
+else
+       if test $# -ne 1 ; then
+               echo "Usage: amcleanup conf"
+               exit 1
+       else
+               conf=$1
+               KILL_ENABLE=0
+       fi
 fi
 
-conf=$1
-if [ ! -d $confdir/$conf ]; then
-        echo "amcleanup: could not cd into $confdir/$conf"
-        exit 1
+if test ! -d $confdir/$conf ; then
+       echo "amcleanup: could not cd into $confdir/$conf"
+       exit 1
 fi
 
 cd $confdir/$conf
 
-logdir=`amgetconf$SUF logdir`
-[ $? -ne 0 ]  && exit 1
+logdir=`amgetconf$SUF $conf logdir "$@"`
+rc=$?
+if test $rc -ne 0 ; then
+       echo "amcleanup: 'amgetconf$SUF logdir' exited with status: $rc" 1>&2
+       exit 1
+fi
 logfile=$logdir/log
 errfile=$logdir/amdump
 erramflush=$logdir/amflush
-tapecycle=`amgetconf$SUF tapecycle`
+tapecycle=`amgetconf$SUF $conf tapecycle "$@"`
+rc=$?
+if test $rc -ne 0 ; then
+       echo "amcleanup: 'amgetconf$SUF tapecycle' exited with status: $rc " 1>&2
+       exit 1
+fi
+dumpuser=`amgetconf$SUF $conf dumpuser "$@"`
+rc=$?
+if test $rc -ne 0 ; then
+       echo "amcleanup: 'amgetconf$SUF $conf dumpuser' exited with status: $rc" 1>&2
+       exit 1
+fi
+
+# Check for running processes which should not be
+# running right now.
+if test ${KILL_ENABLE} -eq 1 ; then
+       if test -h /proc/1/exe ; then
+               USER_PROCESS_NAMES="\
+                       @libexecdir@/amandad \
+                       @libexecdir@/amcleanupdisk \
+                       @libexecdir@/amidxtaped \
+                       @libexecdir@/amindexd \
+                       @libexecdir@/amlogroll \
+                       @libexecdir@/amtrmidx \
+                       @libexecdir@/amtrmlog \
+                       @libexecdir@/chg-chio \
+                       @libexecdir@/chg-chs \
+                       @libexecdir@/chg-disk \
+                       @libexecdir@/chg-iomega \
+                       @libexecdir@/chg-juke \
+                       @libexecdir@/chg-manual \
+                       @libexecdir@/chg-mcutil \
+                       @libexecdir@/chg-mtx \
+                       @libexecdir@/chg-multi \
+                       @libexecdir@/chg-null \
+                       @libexecdir@/chg-rait \
+                       @libexecdir@/chg-rth \
+                       @libexecdir@/chg-scsi \
+                       @libexecdir@/chg-zd-mtx \
+                       @libexecdir@/chunker \
+                       @libexecdir@/driver \
+                       @libexecdir@/generic-dumper \
+                       @libexecdir@/gnutar \
+                       @libexecdir@/noop \
+                       @libexecdir@/patch-system \
+                       @libexecdir@/selfcheck \
+                       @libexecdir@/sendbackup \
+                       @libexecdir@/sendsize \
+                       @libexecdir@/star \
+                       @libexecdir@/taper \
+                       @libexecdir@/versionsuffix \
+                       @sbindir@/amaddclient \
+                       @sbindir@/amadmin \
+                       @sbindir@/amaespipe \
+                       @sbindir@/amcheckdb \
+                       @sbindir@/amcrypt \
+                       @sbindir@/amcryptsimple \
+                       @sbindir@/amdd \
+                       @sbindir@/amdump \
+                       @sbindir@/amfetchdump \
+                       @sbindir@/amflush \
+                       @sbindir@/amgetconf \
+                       @sbindir@/amgpgcrypt \
+                       @sbindir@/amlabel \
+                       @sbindir@/ammt \
+                       @sbindir@/amoverview \
+                       @sbindir@/amplot \
+                       @sbindir@/amrecover \
+                       @sbindir@/amreport \
+                       @sbindir@/amrestore \
+                       @sbindir@/amrmtape \
+                       @sbindir@/amserverconfig \
+                       @sbindir@/amstatus \
+                       @sbindir@/amtape \
+                       @sbindir@/amtapetype \
+                       @sbindir@/amtoc \
+                       @sbindir@/amverify \
+                       @sbindir@/amverifyrun"
 
-if [ -f $logfile ]; then
-       lognotfound=0
+               ROOT_PROCESS_NAMES="\
+                       @libexecdir@/calcsize \
+                       @libexecdir@/killpgrp \
+                       @libexecdir@/rundump \
+                       @libexecdir@/runtar \
+                       @libexecdir@/dumper \
+                       @libexecdir@/planner \
+                       @sbindir@/amcheck"
 
+               PREVIOUS_DIR="`pwd`"
+               cd /proc
+               PIDS_FOUND=0
+               KEEP_CHECKING=1
+               while test ${KEEP_CHECKING} -ne 0 ; do
+                       PIDS_THIS_PASS=0
+                       for search_user in ${dumpuser} root ; do
+                               if test "${search_user}" == "${dumpuser}" ; then
+                                       PROCESS_NAMES=${USER_PROCESS_NAMES}
+                               elif test "${search_user}" == "root" ; then
+                                       PROCESS_NAMES=${ROOT_PROCESS_NAMES}
+                               fi
+                               for search_pid in [0-9]* ; do
+                                       for search_name in ${PROCESS_NAMES} ; do
+                                               ls -l /proc/${search_pid}/exe 2>/dev/null | grep ${search_name} >/dev/null
+                                               match_name=$?
+                                               pid_uid="`cat /proc/${search_pid}/status 2>/dev/null | grep Uid | awk '//{split($_,i); print i[2]}'`"
+                                               if test ${match_name} -eq 0  && test "${pid_uid}" == "${search_user}" ; then
+                                                       echo "amcleanup: Process ${search_name} found running at pid #${search_pid}."
+                                                       kill_pid=${search_pid}
+                                                       kill_name=${search_name}
+                                                       PIDS_FOUND=`expr ${PIDS} + 1`
+                                                       PIDS_THIS_PASS=1
+                                                       break
+                                               else
+                                                       kill_pid=""
+                                                       continue
+                                               fi
+                                       done
+                                       if test ! -z "${kill_pid}" ; then
+                                               if test -d /proc/${kill_pid} ; then
+                                                       echo "amcleanup: Sending process ${kill_pid} the TERM signal."
+                                                       kill -15 -- ${kill_pid}
+                                                       sleep 5
+                                                       if test -d /proc/${kill_pid} ; then
+                                                               echo "amcleanup: Sending process  ${kill_pid} the KILL signal."
+                                                               kill -9 -- ${kill_pid}
+                                                       fi
+                                                       sleep 5
+                                                       if test -d /proc/${kill_pid} ; then
+                                                               echo "amcleanup: Process ${kill_pid} did not respond to the KILL signal (and may be hung)!" 1>&2
+                                                               KILL_FAILURES=`expr ${KILL_FAILURES} + 1`
+                                                       fi
+                                               else
+                                                       echo "amcleanup: Process ${kill_pid} no longer running.  Skipping..."
+                                               fi
+                                       fi
+                               done
+                       done
+                       if test ${PIDS_THIS_PASS} -eq 0 ; then
+                               KEEP_CHECKING=0
+                       else
+                               KEEP_CHECKING=1
+                       fi
+               done
+               if test ${PIDS_FOUND} -gt 0 ; then
+                       echo "amcleanup: ${PIDS_FOUND} Amanda processes were found running."
+                       echo "amcleanup: ${KILL_FAILURES} processes failed to terminate."
+               else
+                       echo "amcleanup: No Amanda processes were found running."
+               fi
+               cd "${PREVIOUS_DIR}"
+       fi
+fi
+
+retstatus=0
+if test -f $logfile ; then
        echo "amcleanup: processing outstanding log file."
        exec </dev/null >/dev/null 2>&1
-       amreport$SUF $conf
+       amreport$SUF $conf "$@"
+       rc=$?
+       if test $rc -ne 0 ; then
+               echo "amcleanup: amreport exited with status: $rc" 1>&2
+               retstatus=`expr $retstatus + 1`
+       fi
 
        # Roll the log file to its datestamped name.
-       amlogroll$SUF $conf
+       amlogroll$SUF $conf "$@"
+       rc=$?
+       if test $rc -ne 0 ; then
+               echo "acmleanup: amlogroll exited with status: $rc" 1>&2
+               retstatus=`expr $retstatus + 2`
+       fi
 
        # Trim the index file to those for dumps that still exist.
-       amtrmidx$SUF $conf
+       amtrmidx$SUF $conf "$@"
+       rc=$?
+       if test $rc -ne 0 ; then
+               echo "amcleanup: amtrmidx exited with status: $rc" 1>&2
+               retstatus=`expr $retstatus + 4`
+       fi
 
 else
        echo "amcleanup: no unprocessed logfile to clean up."
-
-       lognotfound=1
 fi
 
-if [ -f $errfile ]; then
+if test -f $errfile ; then
     # if log was found, this will have been directed to /dev/null,
     # which is fine.
     echo "amcleanup: $errfile exists, renaming it."
@@ -98,11 +282,11 @@ if [ -f $errfile ]; then
     days=1
     # First, find out the last existing errfile,
     # to avoid ``infinite'' loops if tapecycle is infinite
-    while [ $days -lt $maxdays ] && [ -f $errfile.$days ]; do
+    while test $days -lt $maxdays  && test -f $errfile.$days ; do
        days=`expr $days + 1`
     done
     # Now, renumber the existing log files
-    while [ $days -ge 2 ]; do
+    while test $days -ge 2 ; do
        ndays=`expr $days - 1`
        mv $errfile.$ndays $errfile.$days
        days=$ndays
@@ -110,7 +294,7 @@ if [ -f $errfile ]; then
     mv $errfile $errfile.1
 fi
 
-if [ -f $erramflush ]; then
+if test -f $erramflush ; then
     # if log was found, this will have been directed to /dev/null,
     # which is fine.
     echo "amcleanup: $erramflush exists, renaming it."
@@ -121,11 +305,11 @@ if [ -f $erramflush ]; then
     days=1
     # First, find out the last existing erramflush,
     # to avoid ``infinite'' loops if tapecycle is infinite
-    while [ $days -lt $maxdays ] && [ -f $erramflush.$days ]; do
+    while test $days -lt $maxdays  && test -f $erramflush.$days ; do
        days=`expr $days + 1`
     done
     # Now, renumber the existing log files
-    while [ $days -ge 2 ]; do
+    while test $days -ge 2 ; do
        ndays=`expr $days - 1`
        mv $erramflush.$ndays $erramflush.$days
        days=$ndays
@@ -133,6 +317,11 @@ if [ -f $erramflush ]; then
     mv $erramflush $erramflush.1
 fi
 
-$libexecdir/amcleanupdisk $conf
+$libexecdir/amcleanupdisk $conf "$@"
+rc=$?
+if test $rc -ne 0 ; then
+       echo "amcleanup: amcleanupdisk exited with status: $rc" 1>&2
+       retstatus=`expr $retstatus + 8`
+fi
 
-exit $lognotfound
+exit $retstatus
index e73af4cd94f3c1ecea55880875b478bc48398af8..9092313c304a6070de14251d43b186903d8f7914 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amcleanupdisk.c,v 1.16 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amcleanupdisk.c,v 1.22 2006/07/25 18:27:57 martinea Exp $
  */
 #include "amanda.h"
 
@@ -40,13 +40,14 @@ sl_t *holding_list;
 char *datestamp;
 
 /* local functions */
-int main P((int argc, char **argv));
-void check_holdingdisk P((char *diskdir, char *datestamp));
-void check_disks P((void));
-
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+int main(int argc, char **argv);
+void check_holdingdisk(char *diskdir, char *datestamp);
+void check_disks(void);
+
+int
+main(
+    int                main_argc,
+    char **    main_argv)
 {
     struct passwd *pw;
     char *dumpuser;
@@ -60,29 +61,39 @@ char **main_argv;
 
     set_pname("amcleanupdisk");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-    if(main_argc != 2)
+    if(main_argc != 2) {
        error("Usage: amcleanupdisk%s <confdir>", versionsuffix());
+       /*NOTREACHED*/
+    }
 
     config_name = main_argv[1];
 
     config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
 
     conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if(read_conffile(conffile))
+    if(read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
+    }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
     conf_diskfile = getconf_str(CNF_DISKFILE);
     if (*conf_diskfile == '/') {
        conf_diskfile = stralloc(conf_diskfile);
     } else {
        conf_diskfile = stralloc2(config_dir, conf_diskfile);
     }
-    if (read_diskfile(conf_diskfile, &diskq) < 0)
+    if (read_diskfile(conf_diskfile, &diskq) < 0) {
        error("could not load disklist %s", conf_diskfile);
+       /*NOTREACHED*/
+    }
     amfree(conf_diskfile);
 
     conf_infofile = getconf_str(CNF_INFOFILE);
@@ -91,17 +102,24 @@ char **main_argv;
     } else {
        conf_infofile = stralloc2(config_dir, conf_infofile);
     }
-    if (open_infofile(conf_infofile) < 0)
+    if (open_infofile(conf_infofile) < 0) {
        error("could not open info db \"%s\"", conf_infofile);
+       /*NOTREACHED*/
+    }
     amfree(conf_infofile);
 
     datestamp = construct_datestamp(NULL);
 
     dumpuser = getconf_str(CNF_DUMPUSER);
-    if((pw = getpwnam(dumpuser)) == NULL)
+    if((pw = getpwnam(dumpuser)) == NULL) {
        error("dumpuser %s not found in password file", dumpuser);
-    if(pw->pw_uid != getuid())
+       /*NOTREACHED*/
+    }
+
+    if(pw->pw_uid != getuid()) {
        error("must run amcleanupdisk as user %s", dumpuser);
+       /*NOTREACHED*/
+    }
 
     holding_list = pick_all_datestamp(1);
 
@@ -116,8 +134,10 @@ char **main_argv;
 }
 
 
-void check_holdingdisk(diskdir, datestamp)
-char *diskdir, *datestamp;
+void
+check_holdingdisk(
+    char *     diskdir,
+    char *     datestamp)
 {
     DIR *workdir;
     struct dirent *entry;
@@ -130,7 +150,7 @@ char *diskdir, *datestamp;
     filetype_t filetype;
     info_t info;
     int level;
-    int dl, l;
+    size_t dl, l;
 
     dirname = vstralloc(diskdir, "/", datestamp, NULL);
     dl = strlen(dirname);
@@ -163,6 +183,7 @@ char *diskdir, *datestamp;
        amfree(hostname);
        amfree(diskname);
        filetype = get_amanda_names(tmpname, &hostname, &diskname, &level);
+       amfree(tmpname);
        if(filetype != F_DUMPFILE) {
            continue;
        }
@@ -184,6 +205,7 @@ char *diskdir, *datestamp;
            if(put_info(dp->host->hostname, dp->name, &info)) {
                error("could not put info record for %s:%s: %s",
                      dp->host->hostname, dp->name, strerror(errno));
+               /*NOTREACHED*/
            }
        } else {
            fprintf(stderr,"rename_tmp_holding(%s) failed\n", destname);
@@ -202,13 +224,14 @@ char *diskdir, *datestamp;
 }
 
 
-void check_disks()
+void
+check_disks(void)
 {
     holdingdisk_t *hdisk;
     sle_t *dir;
 
     for(dir = holding_list->first; dir !=NULL; dir = dir->next) {
        for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
-           check_holdingdisk(hdisk->diskdir, dir->name);
+           check_holdingdisk(holdingdisk_get_diskdir(hdisk), dir->name);
     }
 }
diff --git a/server-src/amcrypt-ossl-asym.sh.in b/server-src/amcrypt-ossl-asym.sh.in
new file mode 100644 (file)
index 0000000..39746d5
--- /dev/null
@@ -0,0 +1,181 @@
+#!@SHELL@
+#
+# amcrypt-ossl-asym.sh - asymmetric crypto helper using OpenSSL
+# Usage: amcrypt-ossl-asym.sh [-d]
+#
+# Copyright © 2006  Ben Slusky <sluskyb@paranoiacs.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+# 
+# Keys can be generated with the standard OpenSSL commands, e.g.:
+#
+# $ openssl genrsa -aes128 -out backup-privkey.pem 1024
+# Generating RSA private key, 1024 bit long modulus
+# [...]
+# Enter pass phrase for backup-privkey.pem: <ENTER YOUR PASS PHRASE>
+# Verifying - Enter pass phrase for backup-privkey.pem: <ENTER YOUR PASS PHRASE>
+#
+# $ openssl rsa -in backup-privkey.pem -pubout -out backup-pubkey.pem
+# Enter pass phrase for backup-privkey.pem: <ENTER YOUR PASS PHRASE>
+# Writing RSA key
+#
+
+# change these as needed
+OPENSSL=                       # whatever's in $PATH
+CIPHER=aes-256-cbc             # see `openssl help` for more ciphers
+AMANDA_HOME=~amandabackup
+RANDFILE=$AMANDA_HOME/.rnd
+export RANDFILE
+PASSPHRASE=$AMANDA_HOME/.am_passphrase # optional
+PRIVKEY=$AMANDA_HOME/backup-privkey.pem
+PUBKEY=$AMANDA_HOME/backup-pubkey.pem
+
+# where might openssl be?
+PATH=/bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin
+export PATH
+MAGIC='AmAnDa+OpEnSsL'
+ME=`basename "$0"`
+WORKDIR="/tmp/.${ME}.$$"
+
+# first things first
+if [ -z "${OPENSSL:=`which openssl`}" ]; then
+       echo "${ME}: openssl not found" >&2
+       exit 1
+elif [ ! -x "${OPENSSL}" ]; then
+       echo "${ME}: can't execute openssl (${OPENSSL})" >&2
+       exit 1
+fi
+
+if [ -n "${PASSPHRASE}" ]; then
+       # check the openssl version. if it's too old, we have to handle
+       # the pass phrase differently.
+       OSSL_VERSION=`eval \"${OPENSSL}\" version |cut -d\  -f2`
+       case "${OSSL_VERSION}" in
+        ''|0.[0-8].*|0.9.[0-6]*|0.9.7|0.9.7[a-c]*)
+               echo "${ME}: ${OPENSSL} is version ${OSSL_VERSION}" >&2
+               echo "${ME}: Using pass phrase kluge for OpenSSL version >=0.9.7d" >&2
+               PASS_FROM_STDIN=yes
+               ;;
+       esac
+fi
+
+mkdir -m 700 "${WORKDIR}"
+if [ $? -ne 0 ]; then
+       echo "${ME}: failed to create temp directory" >&2
+       exit 1
+fi
+# ignore SIGINT
+trap "" 2
+trap "rm -rf \"${WORKDIR}\"" 0 1 3 15
+
+# we'll need to pad the datastream to a multiple of the cipher block size
+# prior to encryption and decryption. 96 bytes (= 768 bits) should be good
+# for any cipher.
+pad() {
+       perl -pe 'BEGIN { $bs = 96; $/ = \8192 } $nbytes = ($nbytes + length) % $bs; END { print "\0" x ($bs - $nbytes) }'
+}
+
+encrypt() {
+       # generate a random printable cipher key (on one line)
+       echo `"${OPENSSL}" rand -base64 80` >"${WORKDIR}/pass"
+
+       # encrypt the cipher key using the RSA public key
+       "${OPENSSL}" rsautl -encrypt -in "${WORKDIR}/pass" -out "${WORKDIR}/pass.ciphertext" -pubin -inkey "${PUBKEY}" -pkcs
+       [ $? -eq 0 ] || return 1
+
+       # print magic
+       printf %s "${MAGIC}"
+
+       # print the encrypted cipher key, preceded by size
+       ls -l "${WORKDIR}/pass.ciphertext" | awk '{ printf("%-10d", $5) }'
+       cat "${WORKDIR}/pass.ciphertext"
+
+       # encrypt data using the cipher key and print
+       pad | "${OPENSSL}" enc "-${CIPHER}" -nopad -e -pass "file:${WORKDIR}/pass" -nosalt
+       [ $? -eq 0 ] || return 1
+}
+
+decrypt() {
+       # read magic
+       magicsize=`printf %s "${MAGIC}" | wc -c | sed 's/^ *//'`
+       magic=`dd bs=$magicsize count=1 2>/dev/null`
+       if [ "$magic" != "${MAGIC}" ]; then
+               echo "${ME}: bad magic" >&2
+               return 1
+       fi
+
+       # read size of encrypted cipher key
+       n=`dd bs=10 count=1 2>/dev/null`
+       [ $n -gt 0 ] 2>/dev/null
+       if [ $? -ne 0 ]; then
+               echo "${ME}: bad header" >&2
+               return 1
+       fi
+
+       # read the encrypted cipher key
+       dd "of=${WORKDIR}/pass.ciphertext" bs=$n count=1 2>/dev/null
+
+       # decrypt the cipher key using the RSA private key
+       if [ "${PASS_FROM_STDIN}" = yes ]; then
+               "${OPENSSL}" rsautl -decrypt -in "${WORKDIR}/pass.ciphertext" -out "${WORKDIR}/pass" -inkey "${PRIVKEY}" -pkcs < "${PASSPHRASE}"
+       else
+               "${OPENSSL}" rsautl -decrypt -in "${WORKDIR}/pass.ciphertext" -out "${WORKDIR}/pass" -inkey "${PRIVKEY}" ${PASSARG} -pkcs 3< "${PASSPHRASE}"
+       fi
+       [ $? -eq 0 ] || return 1
+
+       # use the cipher key to decrypt data
+       pad | "${OPENSSL}" enc "-${CIPHER}" -nopad -d -pass "file:${WORKDIR}/pass" -nosalt
+
+       # N.B.: in the likely event that we're piping to gzip, the above command
+       # may return a spurious error if gzip closes the output stream early.
+       return 0
+}
+
+if [ "$1" = -d ]; then
+       if [ -z "${PRIVKEY}" ]; then
+               echo "${ME}: must specify private key for decryption" >&2
+               exit 1
+       elif [ ! -r "${PRIVKEY}" ]; then
+               echo "${ME}: can't read private key from ${PRIVKEY}" >&2
+               exit 1
+       fi
+
+       if [ -n "${PASSPHRASE}" -a -e "${PASSPHRASE}" -a -r "${PASSPHRASE}" ]; then
+               PASSARG='-passin fd:3'
+       else
+               PASSPHRASE=/dev/null
+       fi
+
+       decrypt
+       if [ $? -ne 0 ]; then
+               echo "${ME}: decryption failed" >&2
+               exit 1
+       fi
+else
+       if [ -z "${PUBKEY}" ]; then
+               echo "${ME}: must specify public key for encryption" >&2
+               exit 1
+       elif [ ! -r "${PUBKEY}" ]; then
+               echo "${ME}: can't read public key from ${PUBKEY}" >&2
+               exit 1
+       fi
+
+       encrypt
+       if [ $? -ne 0 ]; then
+               echo "${ME}: encryption failed" >&2
+               exit 1
+       fi
+fi
diff --git a/server-src/amcrypt-ossl.sh.in b/server-src/amcrypt-ossl.sh.in
new file mode 100644 (file)
index 0000000..0529cab
--- /dev/null
@@ -0,0 +1,41 @@
+#!@SHELL@
+#
+# amcrypt-ossl.sh - crypto helper using OpenSSL
+# Usage: amcrypt-ossl.sh [-d]
+#
+
+# change these as needed
+OPENSSL=                       # whatever's in $PATH
+CIPHER=aes-256-cbc             # see `openssl help` for more ciphers
+AMANDA_HOME=~amandabackup
+RANDFILE=$AMANDA_HOME/.rnd
+export RANDFILE
+PASSPHRASE=$AMANDA_HOME/.am_passphrase # required
+
+# where might openssl be?
+PATH=/bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin
+export PATH
+ME=`basename "$0"`
+
+if [ -z "${OPENSSL:=`which openssl`}" ]; then
+       echo "${ME}: openssl not found" >&2
+       exit 1
+elif [ ! -x "${OPENSSL}" ]; then
+       echo "${ME}: can't execute openssl (${OPENSSL})" >&2
+       exit 1
+fi
+
+# we'll need to pad the datastream to a multiple of the cipher block size prior
+# to encryption. 96 bytes (= 768 bits) should be good for any cipher.
+pad() {
+       perl -pe 'BEGIN { $bs = 96; $/ = \8192 } $nbytes = ($nbytes + length) % $bs; END { print "\0" x ($bs - $nbytes) }'
+}
+
+if [ "$1" = -d ]; then
+       # decrypt
+       "${OPENSSL}" enc -d "-${CIPHER}" -nopad -salt -pass fd:3 3< "${PASSPHRASE}"
+else
+       # encrypt
+       pad | "${OPENSSL}" enc -e "-${CIPHER}" -nopad -salt -pass fd:3 3< "${PASSPHRASE}"
+fi
+
index 8b0616819b40c83e231ff74c4f2ebd1326b8ee30..3fbcf527e538c96e7ba63cfd49fea01dae3eaf8f 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 #
 # Original wrapper by Paul Bijnens
 #
index 28ba2a5ed95ea1c5a73d65bc793ecda9aebf498a..a66e6b2cc4dfd50f720df5ce7a3c644b4244fbbb 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 #
 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
 # Copyright (c) 1991-1998 University of Maryland at College Park
@@ -47,20 +47,28 @@ else
        SUF=
 fi
 
+if [ $# -lt 1 ]
+then
+        echo "Usage: amdump config [host [disk...]...]" 1>&2
+        exit 1
+fi
+
+
 conf=$1
 if [ ! -d $confdir/$conf ]; then
-    echo "amdump$SUF: could not find directory $confdir/$conf"
+    echo "amdump$SUF: could not find directory $confdir/$conf" 1>&2
     exit 1
 fi
+shift
 
 cd $confdir/$conf || exit 1
 
-logdir=`amgetconf$SUF $conf logdir`
+logdir=`amgetconf$SUF $conf logdir "$@"`
 [ $? -ne 0 ]  && exit 1
 errfile=$logdir/amdump
-tapecycle=`amgetconf$SUF $conf tapecycle`
+tapecycle=`amgetconf$SUF $conf tapecycle "$@"`
 [ $? -ne 0 ]  && exit 1
-dumpuser=`amgetconf$SUF $conf dumpuser`
+dumpuser=`amgetconf$SUF $conf dumpuser "$@"`
 [ $? -ne 0 ]  && exit 1
 
 runuser=`{ whoami ; } 2>/dev/null`
@@ -73,20 +81,20 @@ if [ $? -ne 0 ]; then
        fi
 fi
 
-if [ $runuser != $dumpuser ]; then
-       echo "amdump: must be run as user $dumpuser, not $runuser"
-       exit 1
-fi
+#if [ $runuser != $dumpuser ]; then
+#      echo "amdump: must be run as user $dumpuser, not $runuser" 1>&2
+#      exit 1
+#fi
 
 if test -f hold; then
-       echo "amdump: waiting for hold file to be removed" >&2
+       echo "amdump: waiting for hold file to be removed" 1>&2
        while test -f hold; do
                sleep 60
        done
 fi
 
 if test -f $errfile || test -f $logdir/log; then
-       echo "amdump: amdump or amflush is already running, or you must run amcleanup" >&2
+       echo "amdump: amdump or amflush is already running, or you must run amcleanup" 1>&2
        exit 1
 fi
 
@@ -98,20 +106,20 @@ touch $errfile
 exec </dev/null 2>>$errfile 1>&2
 echo "amdump: start at `date`"
 echo "amdump: datestamp `date +%Y%m%d`"
-$libexecdir/planner$SUF "$@" | $libexecdir/driver$SUF $conf
+$libexecdir/planner$SUF $conf "$@" | $libexecdir/driver$SUF $conf "$@"
 echo "amdump: end at `date`"
 
 # Send out a report on the dumps.
-$sbindir/amreport$SUF $conf
+$sbindir/amreport$SUF $conf "$@"
 
 # Roll the log file to its datestamped name.
-$libexecdir/amlogroll$SUF $conf
+$libexecdir/amlogroll$SUF $conf "$@"
 
 # Trim the log file to those for dumps that still exist.
-$libexecdir/amtrmlog$SUF $conf
+$libexecdir/amtrmlog$SUF $conf "$@"
 
 # Trim the index file to those for dumps that still exist.
-$libexecdir/amtrmidx$SUF $conf
+$libexecdir/amtrmidx$SUF $conf "$@"
 
 # Keep a debug log through the tapecycle plus a couple of days.
 maxdays=`expr $tapecycle + 2`
index 1cd9749056612f0d29476a1e2e2a80c303cb137f..32bfe1cafa3b38a798878cccd712288ed93397c8 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amflush.c,v 1.80 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amflush.c,v 1.95 2006/07/25 21:41:24 martinea Exp $
  *
  * write files from work directory onto tape
  */
@@ -46,20 +46,23 @@ char *driver_program;
 char *reporter_program;
 char *logroll_program;
 char *datestamp;
+char *amflush_timestamp;
+char *amflush_datestamp;
 sl_t *datestamp_list;
 
 /* local functions */
-int main P((int main_argc, char **main_argv));
-void flush_holdingdisk P((char *diskdir, char *datestamp));
-void confirm P((void));
-void redirect_stderr P((void));
-void detach P((void));
-void run_dumps P((void));
-static int get_letter_from_user P((void));
-
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+int main(int main_argc, char **main_argv);
+void flush_holdingdisk(char *diskdir, char *datestamp);
+void confirm(void);
+void redirect_stderr(void);
+void detach(void);
+void run_dumps(void);
+static int get_letter_from_user(void);
+
+int
+main(
+    int                main_argc,
+    char **    main_argv)
 {
     int foreground;
     int batch;
@@ -72,6 +75,7 @@ char **main_argv;
     char *conf_diskfile;
     char *conf_tapelist;
     char *conf_logfile;
+    int conf_usetimestamps;
     disklist_t diskq;
     disk_t *dp;
     pid_t pid;
@@ -84,12 +88,18 @@ char **main_argv;
     int driver_pipe[2];
     char date_string[100];
     time_t today;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
+    char *errstr;
+    struct tm *tm;
 
     safe_fd(-1, 0);
     safe_cd();
 
     set_pname("amflush");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -100,7 +110,11 @@ char **main_argv;
 
     /* process arguments */
 
-    while((opt = getopt(main_argc, main_argv, "bfsD:")) != EOF) {
+    parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    while((opt = getopt(my_argc, my_argv, "bfsD:")) != EOF) {
        switch(opt) {
        case 'b': batch = 1;
                  break;
@@ -109,7 +123,7 @@ char **main_argv;
        case 's': redirect = 0;
                  break;
        case 'D': if (datearg == NULL)
-                     datearg = alloc(21*sizeof(char *));
+                     datearg = alloc(21*SIZEOF(char *));
                  if(nb_datearg == 20) {
                      fprintf(stderr,"maximum of 20 -D arguments.\n");
                      exit(1);
@@ -124,29 +138,42 @@ char **main_argv;
        exit(1);
     }
 
-    main_argc -= optind, main_argv += optind;
+    my_argc -= optind, my_argv += optind;
 
-    if(main_argc < 1) {
-       error("Usage: amflush%s [-b] [-f] [-s] [-D date]* <confdir> [host [disk]* ]*", versionsuffix());
+    if(my_argc < 1) {
+       error("Usage: amflush%s [-b] [-f] [-s] [-D date]* <confdir> [host [disk]* ]* [-o configoption]*", versionsuffix());
+       /*NOTREACHED*/
     }
 
-    config_name = main_argv[0];
+    config_name = my_argv[0];
     config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
 
     conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if(read_conffile(conffile))
+    if(read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
+    }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     conf_diskfile = getconf_str(CNF_DISKFILE);
     if (*conf_diskfile == '/') {
        conf_diskfile = stralloc(conf_diskfile);
     } else {
        conf_diskfile = stralloc2(config_dir, conf_diskfile);
     }
-    if (read_diskfile(conf_diskfile, &diskq) < 0)
+    if (read_diskfile(conf_diskfile, &diskq) < 0) {
        error("could not read disklist file \"%s\"", conf_diskfile);
-    match_disklist(&diskq, main_argc-1, main_argv+1);
+       /*NOTREACHED*/
+    }
+    errstr = match_disklist(&diskq, my_argc-1, my_argv+1);
+    if (errstr) {
+       printf("%s",errstr);
+       amfree(errstr);
+    }
     amfree(conf_diskfile);
 
     conf_tapelist = getconf_str(CNF_TAPELIST);
@@ -155,17 +182,31 @@ char **main_argv;
     } else {
        conf_tapelist = stralloc2(config_dir, conf_tapelist);
     }
-    if(read_tapelist(conf_tapelist))
+    if(read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
+    }
     amfree(conf_tapelist);
 
-    datestamp = construct_datestamp(NULL);
+    conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS);
+
+    amflush_datestamp = construct_datestamp(NULL);
+    if(conf_usetimestamps == 0) {
+       amflush_timestamp = stralloc(amflush_datestamp);
+    }
+    else {
+       amflush_timestamp = construct_timestamp(NULL);
+    }
 
     dumpuser = getconf_str(CNF_DUMPUSER);
-    if((pw = getpwnam(dumpuser)) == NULL)
+    if((pw = getpwnam(dumpuser)) == NULL) {
        error("dumpuser %s not found in password file", dumpuser);
-    if(pw->pw_uid != getuid())
+       /*NOTREACHED*/
+    }
+    if(pw->pw_uid != getuid()) {
        error("must run amflush as user %s", dumpuser);
+       /*NOTREACHED*/
+    }
 
     conf_logdir = getconf_str(CNF_LOGDIR);
     if (*conf_logdir == '/') {
@@ -174,8 +215,10 @@ char **main_argv;
        conf_logdir = stralloc2(config_dir, conf_logdir);
     }
     conf_logfile = vstralloc(conf_logdir, "/log", NULL);
-    if (access(conf_logfile, F_OK) == 0)
+    if (access(conf_logfile, F_OK) == 0) {
        error("%s exists: amdump or amflush is already running, or you must run amcleanup", conf_logfile);
+       /*NOTREACHED*/
+    }
     amfree(conf_logfile);
 
     driver_program = vstralloc(libexecdir, "/", "driver", versionsuffix(),
@@ -241,14 +284,19 @@ char **main_argv;
     erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
     set_logerror(logerror);
     today = time(NULL);
-    strftime(date_string, 100, "%a %b %e %H:%M:%S %Z %Y", localtime (&today));
+    tm = localtime(&today);
+    if (tm)
+       strftime(date_string, 100, "%a %b %e %H:%M:%S %Z %Y", tm);
+    else
+       error("BAD DATE"); /* should never happen */
     fprintf(stderr, "amflush: start at %s\n", date_string);
-    fprintf(stderr, "amflush: datestamp %s\n", datestamp);
-    log_add(L_START, "date %s", datestamp);
+    fprintf(stderr, "amflush: datestamp %s\n", amflush_timestamp);
+    log_add(L_START, "date %s", amflush_timestamp);
 
     /* START DRIVER */
     if(pipe(driver_pipe) == -1) {
        error("error [opening pipe to driver: %s]", strerror(errno));
+       /*NOTREACHED*/
     }
     if((driver_pid = fork()) == 0) {
        /*
@@ -260,16 +308,27 @@ char **main_argv;
               "driver", config_name, "nodump", (char *)0,
               safe_env());
        error("cannot exec %s: %s", driver_program, strerror(errno));
+       /*NOTREACHED*/
     } else if(driver_pid == -1) {
        error("cannot fork for %s: %s", driver_program, strerror(errno));
+       /*NOTREACHED*/
     }
     driver_stream = fdopen(driver_pipe[1], "w");
+    if (!driver_stream) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
+    fprintf(driver_stream, "DATE %s\n", amflush_timestamp);
     for(holding_file=holding_list->first; holding_file != NULL;
                                   holding_file = holding_file->next) {
        get_dumpfile(holding_file->name, &file);
 
        dp = lookup_disk(file.name, file.disk);
+       if (!dp) {
+           error("dp == NULL");
+           /*NOTREACHED*/
+       }
        if (dp->todo == 0) continue;
 
        fprintf(stderr,
@@ -298,6 +357,7 @@ char **main_argv;
                continue;
            } else {
                error("wait for %s: %s", driver_program, strerror(errno));
+               /*NOTREACHED*/
            }
        } else if (pid == driver_pid) {
            break;
@@ -344,12 +404,14 @@ char **main_argv;
            if (rename(errfilex, nerrfilex) != 0) {
                error("cannot rename \"%s\" to \"%s\": %s",
                      errfilex, nerrfilex, strerror(errno));
+               /*NOTREACHED*/
            }
        }
        errfilex = newvstralloc(errfilex, errfile, ".1", NULL);
        if (rename(errfile,errfilex) != 0) {
            error("cannot rename \"%s\" to \"%s\": %s",
                  errfilex, nerrfilex, strerror(errno));
+           /*NOTREACHED*/
        }
        amfree(errfile);
        amfree(errfilex);
@@ -370,8 +432,10 @@ char **main_argv;
               "amreport", config_name, (char *)0,
               safe_env());
        error("cannot exec %s: %s", reporter_program, strerror(errno));
+       /*NOTREACHED*/
     } else if(reporter_pid == -1) {
        error("cannot fork for %s: %s", reporter_program, strerror(errno));
+       /*NOTREACHED*/
     }
     while(1) {
        if((pid = wait(&exitcode)) == -1) {
@@ -379,6 +443,7 @@ char **main_argv;
                continue;
            } else {
                error("wait for %s: %s", reporter_program, strerror(errno));
+               /*NOTREACHED*/
            }
        } else if (pid == reporter_pid) {
            break;
@@ -389,27 +454,32 @@ char **main_argv;
      * Call amlogroll to rename the log file to its datestamped version.
      * Since we exec at this point, our exit code will be that of amlogroll.
      */
-
     execle(logroll_program,
           "amlogroll", config_name, (char *)0,
           safe_env());
     error("cannot exec %s: %s", logroll_program, strerror(errno));
+    /*NOTREACHED*/
     return 0;                          /* keep the compiler happy */
 }
 
 
-static int get_letter_from_user()
+static int
+get_letter_from_user(void)
 {
     int r, ch;
 
     fflush(stdout); fflush(stderr);
-    while((ch = getchar()) != EOF && ch != '\n' && isspace(ch)) {}
+    while((ch = getchar()) != EOF && ch != '\n' && isspace(ch)) {
+       (void)ch; /* Quite lint */
+    }
     if(ch == '\n') {
        r = '\0';
     } else if (ch != EOF) {
        r = ch;
        if(islower(r)) r = toupper(r);
-       while((ch = getchar()) != EOF && ch != '\n') {}
+       while((ch = getchar()) != EOF && ch != '\n') { 
+           (void)ch; /* Quite lint */
+       }
     } else {
        r = ch;
        clearerr(stdin);
@@ -418,8 +488,12 @@ static int get_letter_from_user()
 }
 
 
-void confirm()
-/* confirm before detaching and running */
+/*
+ * confirm before detaching and running
+ */
+
+void
+confirm(void)
 {
     tape_t *tp;
     char *tpchanger;
@@ -427,7 +501,7 @@ void confirm()
     int ch;
     char *extra;
 
-    printf("\nToday is: %s\n",datestamp);
+    printf("\nToday is: %s\n",amflush_datestamp);
     printf("Flushing dumps in");
     extra = "";
     for(dir = datestamp_list->first; dir != NULL; dir = dir->next) {
@@ -464,34 +538,43 @@ void confirm()
     exit(1);
 }
 
-void redirect_stderr()
+void
+redirect_stderr(void)
 {
     int fderr;
     char *errfile;
 
     fflush(stdout); fflush(stderr);
     errfile = vstralloc(conf_logdir, "/amflush", NULL);
-    if((fderr = open(errfile, O_WRONLY| O_CREAT | O_TRUNC, 0600)) == -1)
+    if((fderr = open(errfile, O_WRONLY| O_CREAT | O_TRUNC, 0600)) == -1) {
        error("could not open %s: %s", errfile, strerror(errno));
+       /*NOTREACHED*/
+    }
     dup2(fderr,1);
     dup2(fderr,2);
     aclose(fderr);
     amfree(errfile);
 }
 
-void detach()
+void
+detach(void)
 {
     int fd;
 
     fflush(stdout); fflush(stderr);
-    if((fd = open("/dev/null", O_RDWR, 0666)) == -1)
+    if((fd = open("/dev/null", O_RDWR, 0666)) == -1) {
        error("could not open /dev/null: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
     dup2(fd,0);
     aclose(fd);
 
     switch(fork()) {
-    case -1: error("could not fork: %s", strerror(errno));
+    case -1:
+       error("could not fork: %s", strerror(errno));
+       /*NOTREACHED*/
+
     case 0:
        setsid();
        return;
@@ -499,5 +582,3 @@ void detach()
 
     exit(0);
 }
-
-
index 98b78cc8e2915a93f9eddb1f3bcc362dc576afa6..d734d17f20f6ff6dcb49ba7a02db6180d782f6be 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! @SHELL@
 #
 # ICEM internal :-)
 #
index 2e763dc44b88225ae38bb16cce821af42cd149d8..b775c43d2a5b551ad4f943bbcaffcca5cc352f75 100644 (file)
  *                        University of Maryland at College Park
  */
 /*
- * $Id: amindex.c,v 1.13 2001/09/01 03:36:24 jrjackson Exp $
+ * $Id: amindex.c,v 1.15 2006/05/25 01:47:19 johnfranks Exp $
  *
  * index control
  */
 
+#include "amanda.h"
 #include "conffile.h"
 #include "amindex.h"
 
-char *getindexfname(host, disk, date, level)
-char *host, *disk, *date;
-int level;
+char *
+getindexfname(
+    char *     host,
+    char *     disk,
+    char *     date,
+    int                level)
 {
   char *conf_indexdir;
   char *buf;
   char level_str[NUM_STR_SIZE];
-  char datebuf[8 + 1];
+  char datebuf[14 + 1];
   char *dc = NULL;
   char *pc;
   int ch;
@@ -48,17 +52,19 @@ int level;
   if (date != NULL) {
     dc = date;
     pc = datebuf;
-    while (pc < datebuf + sizeof (datebuf)) {
-      if ((*pc++ = ch = *dc++) == '\0') {
+    while (pc < datebuf + SIZEOF(datebuf)) {
+      ch = *dc++;
+      *pc++ = (char)ch;
+      if (ch == '\0') {
         break;
       } else if (! isdigit (ch)) {
         pc--;
       }
     }
-    datebuf[sizeof(datebuf)-1] = '\0';
+    datebuf[SIZEOF(datebuf)-1] = '\0';
     dc = datebuf;
 
-    snprintf(level_str, sizeof(level_str), "%d", level);
+    snprintf(level_str, SIZEOF(level_str), "%d", level);
   }
 
   host = sanitise_filename(host);
index e4722a47efd29136a1c1f291969e8f53f6ecee55..fb8e52641a000c821350f4bb5d6ea676c564e616 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: amindex.h,v 1.7 1999/09/15 00:32:27 jrj Exp $
+ * $Id: amindex.h,v 1.8 2006/05/25 01:47:19 johnfranks Exp $
  *
  * headers for index control
  */
@@ -35,6 +35,6 @@
 #include "amanda.h"
 #include "conffile.h"
 
-char *getindexfname P((char *host, char *disk, char *date, int level));
+char *getindexfname(char *host, char *disk, char *date, int level);
 
 #endif /* AMINDEX_H */
index f721e2cf97bf18115be7d19b1debe43ce8da1cdb..96e2483a575360b7c0c5e32e8aabfdfde10e0311 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amindexd.c,v 1.86 2006/03/09 16:51:41 martinea Exp $
+ * $Id: amindexd.c,v 1.106 2006/07/25 18:27:57 martinea Exp $
  *
  * This is the server daemon part of the index client/server system.
  * It is assumed that this is launched from inetd instead of being
 #include "token.h"
 #include "find.h"
 #include "tapefile.h"
-
-#ifdef HAVE_NETINET_IN_SYSTM_H
-#include <netinet/in_systm.h>
-#endif
-
-#ifdef HAVE_NETINET_IP_H
-#include <netinet/ip.h>
-#endif
+#include "util.h"
+#include "amandad.h"
 
 #include <grp.h>
 
@@ -71,13 +65,17 @@ typedef struct REMOVE_ITEM
 } REMOVE_ITEM;
 
 /* state */
-char local_hostname[MAX_HOSTNAME_LENGTH+1];    /* me! */
-char *remote_hostname = NULL;                  /* the client */
-char *dump_hostname = NULL;                    /* machine we are restoring */
-char *disk_name;                               /* disk we are restoring */
-char *target_date = NULL;
-disklist_t disk_list;                          /* all disks in cur config */
-find_result_t *output_find = NULL;
+static int from_amandad;
+static char local_hostname[MAX_HOSTNAME_LENGTH+1];     /* me! */
+static char *remote_hostname = NULL;                   /* the client */
+static char *dump_hostname = NULL;             /* machine we are restoring */
+static char *disk_name;                                /* disk we are restoring */
+char *qdisk_name = NULL;                       /* disk we are restoring */
+static char *target_date = NULL;
+static disklist_t disk_list;                   /* all disks in cur config */
+static find_result_t *output_find = NULL;
+static g_option_t *g_options = NULL;
+static int cmdfdin, cmdfdout;
 
 static int amindexd_debug = 0;
 
@@ -87,35 +85,38 @@ static REMOVE_ITEM *uncompress_remove = NULL;
 static am_feature_t *our_features = NULL;
 static am_feature_t *their_features = NULL;
 
-static REMOVE_ITEM *remove_files P((REMOVE_ITEM *));
-static char *uncompress_file P((char *, char **));
-static int process_ls_dump P((char *, DUMP_ITEM *, int, char **));
+static REMOVE_ITEM *remove_files(REMOVE_ITEM *);
+static char *uncompress_file(char *, char **);
+static int process_ls_dump(char *, DUMP_ITEM *, int, char **);
 
- /* XXX this is a hack to make sure the printf-ish output buffer
-    for lreply and friends is big enough for long label strings.
-    Should go away if someone institutes a more fundamental fix 
-    for that problem. */
- static int str_buffer_size = STR_SIZE;
+static size_t reply_buffer_size = 1;
+static char *reply_buffer = NULL;
+static char *amandad_auth = NULL;
 
-static void reply P((int, char *, ...))
+static void reply(int, char *, ...)
     __attribute__ ((format (printf, 2, 3)));
-static void lreply P((int, char *, ...))
+static void lreply(int, char *, ...)
     __attribute__ ((format (printf, 2, 3)));
-static void fast_lreply P((int, char *, ...))
+static void fast_lreply(int, char *, ...)
     __attribute__ ((format (printf, 2, 3)));
-static int is_dump_host_valid P((char *));
-static int is_disk_valid P((char *));
-static int is_config_valid P((char *));
-static int build_disk_table P((void));
-static int disk_history_list P((void));
-static int is_dir_valid_opaque P((char *));
-static int opaque_ls P((char *, int));
-static int tapedev_is P((void));
-static int are_dumps_compressed P((void));
-int main P((int, char **));
-
-static REMOVE_ITEM *remove_files(remove)
-REMOVE_ITEM *remove;
+static int is_dump_host_valid(char *);
+static int is_disk_valid(char *);
+static int is_config_valid(char *);
+static int build_disk_table(void);
+static int disk_history_list(void);
+static int is_dir_valid_opaque(char *);
+static int opaque_ls(char *, int);
+static void opaque_ls_one (DIR_ITEM *dir_item, am_feature_e marshall_feature,
+                            int recursive);
+static int tapedev_is(void);
+static int are_dumps_compressed(void);
+static char *amindexd_nicedate (char *datestamp);
+static int cmp_date (const char *date1, const char *date2);
+int main(int, char **);
+
+static REMOVE_ITEM *
+remove_files(
+    REMOVE_ITEM *remove)
 {
     REMOVE_ITEM *prev;
 
@@ -131,15 +132,16 @@ REMOVE_ITEM *remove;
     return remove;
 }
 
-static char *uncompress_file(filename_gz, emsg)
-char *filename_gz;
-char **emsg;
+static char *
+uncompress_file(
+    char *     filename_gz,
+    char **    emsg)
 {
     char *cmd = NULL;
     char *filename = NULL;
     struct stat stat_filename;
     int result;
-    int len;
+    size_t len;
 
     filename = stralloc(filename_gz);
     len = strlen(filename);
@@ -152,21 +154,36 @@ char **emsg;
     /* uncompress the file */
     result=stat(filename,&stat_filename);
     if(result==-1 && errno==ENOENT) {          /* file does not exist */
+       struct stat statbuf;
        REMOVE_ITEM *remove_file;
+
+       /*
+        * Check that compressed file exists manually.
+        */
+       if (stat(filename_gz, &statbuf) < 0) {
+           *emsg = newvstralloc(*emsg, "Compressed file '",
+                               filename_gz,
+                               "' is inaccessable: ",
+                               strerror(errno),
+                               NULL);
+           dbprintf(("%s\n",*emsg));
+           amfree(filename);
+           return NULL;
+       }
+
        cmd = vstralloc(UNCOMPRESS_PATH,
 #ifdef UNCOMPRESS_OPT
                        " ", UNCOMPRESS_OPT,
 #endif
                        " \'", filename_gz, "\'",
                        " 2>/dev/null",
-                       " | sort",
+                       " | (LC_ALL=C; export LC_ALL ; sort) ",
                        " > ", "\'", filename, "\'",
                        NULL);
        dbprintf(("%s: uncompress command: %s\n",
                  debug_prefix_time(NULL), cmd));
-       if (system(cmd)!=0) {
-           amfree(*emsg);
-           *emsg = vstralloc("\"", cmd, "\" failed", NULL);
+       if (system(cmd) != 0) {
+           *emsg = newvstralloc(*emsg, "\"", cmd, "\" failed", NULL);
            unlink(filename);
            errno = -1;
            amfree(filename);
@@ -175,7 +192,7 @@ char **emsg;
        }
 
        /* add at beginning */
-       remove_file = (REMOVE_ITEM *)alloc(sizeof(REMOVE_ITEM));
+       remove_file = (REMOVE_ITEM *)alloc(SIZEOF(REMOVE_ITEM));
        remove_file->filename = stralloc(filename);
        remove_file->next = uncompress_remove;
        uncompress_remove = remove_file;
@@ -186,8 +203,6 @@ char **emsg;
            amfree(filename);
            amfree(cmd);
            return NULL;
-    } else {
-       /* already uncompressed */
     }
     amfree(cmd);
     return filename;
@@ -195,11 +210,12 @@ char **emsg;
 
 /* find all matching entries in a dump listing */
 /* return -1 if error */
-static int process_ls_dump(dir, dump_item, recursive, emsg)
-char *dir;
-DUMP_ITEM *dump_item;
-int  recursive;
-char **emsg;
+static int
+process_ls_dump(
+    char *     dir,
+    DUMP_ITEM *        dump_item,
+    int                recursive,
+    char **    emsg)
 {
     char *line = NULL;
     char *old_line = NULL;
@@ -209,7 +225,7 @@ char **emsg;
     FILE *fp;
     char *s;
     int ch;
-    int len_dir_slash;
+    size_t len_dir_slash;
 
     if (strcmp(dir, "/") == 0) {
        dir_slash = stralloc(dir);
@@ -235,28 +251,31 @@ char **emsg;
 
     len_dir_slash=strlen(dir_slash);
 
-    for(; (line = agets(fp)) != NULL; free(line)) {
-       if(strncmp(dir_slash, line, len_dir_slash) == 0) {
-           if(!recursive) {
-               s = line + len_dir_slash;
-               ch = *s++;
-               while(ch && ch != '/') ch = *s++;/* find end of the file name */
-               if(ch == '/') {
+    while ((line = agets(fp)) != NULL) {
+       if (line[0] != '\0') {
+           if(strncmp(dir_slash, line, len_dir_slash) == 0) {
+               if(!recursive) {
+                   s = line + len_dir_slash;
                    ch = *s++;
+                   while(ch && ch != '/')
+                       ch = *s++;/* find end of the file name */
+                   if(ch == '/') {
+                       ch = *s++;
+                   }
+                   s[-1] = '\0';
+               }
+               if(old_line == NULL || strcmp(line, old_line) != 0) {
+                   add_dir_list_item(dump_item, line);
+                   amfree(old_line);
+                   old_line = line;
+                   line = NULL;
                }
-               s[-1] = '\0';
-           }
-           if(old_line == NULL || strcmp(line, old_line) != 0) {
-               add_dir_list_item(dump_item, line);
-               amfree(old_line);
-               old_line = line;
-               line = NULL;
            }
        }
+       /*@i@*/ amfree(line);
     }
     afclose(fp);
-    amfree(old_line);
-    amfree(line);
+    /*@i@*/ amfree(old_line);
     amfree(filename);
     amfree(dir_slash);
     return 0;
@@ -266,16 +285,25 @@ char **emsg;
 printf_arglist_function1(static void reply, int, n, char *, fmt)
 {
     va_list args;
-    char *buf;
+    int len;
 
-    buf = alloc(str_buffer_size);
+    if(!reply_buffer)
+       reply_buffer = alloc(reply_buffer_size);
 
-    arglist_start(args, fmt);
-    snprintf(buf, str_buffer_size, "%03d ", n);
-    vsnprintf(buf+4, str_buffer_size-4, fmt, args);
-    arglist_end(args);
+    while(1) {
+       arglist_start(args, fmt);
+       len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+       arglist_end(args);
 
-    if (printf("%s\r\n", buf) < 0)
+       if (len > -1 && (size_t)len < reply_buffer_size)
+           break;
+
+       reply_buffer_size *= 2;
+       amfree(reply_buffer);
+       reply_buffer = alloc(reply_buffer_size);
+    }
+
+    if (printf("%03d %s\r\n", n, reply_buffer) < 0)
     {
        dbprintf(("%s: ! error %d (%s) in printf\n",
                  debug_prefix_time(NULL), errno, strerror(errno)));
@@ -289,26 +317,39 @@ printf_arglist_function1(static void reply, int, n, char *, fmt)
        uncompress_remove = remove_files(uncompress_remove);
        exit(1);
     }
-    dbprintf(("%s: < %s\n", debug_prefix_time(NULL), buf));
-    amfree(buf);
+    dbprintf(("%s: < %03d %s\n", debug_prefix_time(NULL), n, reply_buffer));
 }
 
-static void lreply_backend(int flush, int n, char *fmt, va_list args) {
-    char *buf;
+/* send one line of a multi-line response */
+printf_arglist_function1(static void lreply, int, n, char *, fmt)
+{
+    va_list args;
+    int len;
+
+    if(!reply_buffer)
+       reply_buffer = alloc(reply_buffer_size);
 
-    buf = alloc(str_buffer_size);
+    while(1) {
+       arglist_start(args, fmt);
+       len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+       arglist_end(args);
 
-    snprintf(buf, str_buffer_size, "%03d-", n);
-    vsnprintf(buf+4, str_buffer_size-4, fmt, args);
+       if (len > -1 && (size_t)len < reply_buffer_size)
+           break;
 
-    if (printf("%s\r\n", buf) < 0)
+       reply_buffer_size *= 2;
+       amfree(reply_buffer);
+       reply_buffer = alloc(reply_buffer_size);
+    }
+
+    if (printf("%03d-%s\r\n", n, reply_buffer) < 0)
     {
        dbprintf(("%s: ! error %d (%s) in printf\n",
                  debug_prefix_time(NULL), errno, strerror(errno)));
        uncompress_remove = remove_files(uncompress_remove);
        exit(1);
     }
-    if (flush && fflush(stdout) != 0)
+    if (fflush(stdout) != 0)
     {
        dbprintf(("%s: ! error %d (%s) in fflush\n",
                  debug_prefix_time(NULL), errno, strerror(errno)));
@@ -316,30 +357,41 @@ static void lreply_backend(int flush, int n, char *fmt, va_list args) {
        exit(1);
     }
 
-    dbprintf(("%s: < %s\n", debug_prefix_time(NULL), buf));
-    amfree(buf);
+    dbprintf(("%s: < %03d-%s\n", debug_prefix_time(NULL), n, reply_buffer));
+
 }
 
 /* send one line of a multi-line response */
-printf_arglist_function1(static void lreply, int, n, char *, fmt)
+printf_arglist_function1(static void fast_lreply, int, n, char *, fmt)
 {
     va_list args;
+    int len;
 
-    arglist_start(args, fmt);
-    lreply_backend(1, n, fmt, args);
-    arglist_end(args);
+    if(!reply_buffer)
+       reply_buffer = alloc(reply_buffer_size);
 
-}
+    while(1) {
+       arglist_start(args, fmt);
+       len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+       arglist_end(args);
 
-/* send one line of a multi-line response */
-printf_arglist_function1(static void fast_lreply, int, n, char *, fmt)
-{
-    va_list args;
+       if (len > -1 && (size_t)len < reply_buffer_size)
+           break;
 
-    arglist_start(args, fmt);
-    lreply_backend(0, n, fmt, args);
-    arglist_end(args);
+       reply_buffer_size *= 2;
+       amfree(reply_buffer);
+       reply_buffer = alloc(reply_buffer_size);
+    }
 
+    if (printf("%03d-%s\r\n", n, reply_buffer) < 0)
+    {
+       dbprintf(("%s: ! error %d (%s) in printf\n",
+                 debug_prefix_time(NULL), errno, strerror(errno)));
+       uncompress_remove = remove_files(uncompress_remove);
+       exit(1);
+    }
+
+    dbprintf(("%s: < %03d-%s\n", debug_prefix_time(NULL), n, reply_buffer));
 }
 
 /* see if hostname is valid */
@@ -347,8 +399,9 @@ printf_arglist_function1(static void fast_lreply, int, n, char *, fmt)
 /* also do a security check on the requested dump hostname */
 /* to restrict access to index records if required */
 /* return -1 if not okay */
-static int is_dump_host_valid(host)
-char *host;
+static int
+is_dump_host_valid(
+    char *     host)
 {
     struct stat dir_stat;
     char *fn;
@@ -392,30 +445,40 @@ char *host;
 }
 
 
-static int is_disk_valid(disk)
-char *disk;
+static int
+is_disk_valid(
+    char *disk)
 {
     char *fn;
     struct stat dir_stat;
     disk_t *idisk;
+    char *qdisk;
 
-    if (config_name == NULL || dump_hostname == NULL) {
+    if (config_name == NULL) {
        reply(501, "Must set config,host before setting disk.");
        return -1;
     }
+    else if (dump_hostname == NULL) {
+       reply(501, "Must set host before setting disk.");
+       return -1;
+    }
 
     /* check that the config actually handles that disk */
     idisk = lookup_disk(dump_hostname, disk);
     if(idisk == NULL) {
-       reply(501, "Disk %s:%s is not in your disklist.", dump_hostname, disk);
+       qdisk = quote_string(disk);
+       reply(501, "Disk %s:%s is not in your disklist.", dump_hostname, qdisk);
+       amfree(qdisk);
        return -1;
     }
 
     /* assume an index dir already */
     fn = getindexfname(dump_hostname, disk, NULL, 0);
     if (stat (fn, &dir_stat) != 0 || !S_ISDIR(dir_stat.st_mode)) {
-       reply(501, "No index records for disk: %s. Invalid?", disk);
+       qdisk = quote_string(disk);
+       reply(501, "No index records for disk: %s. Invalid?", qdisk);
        amfree(fn);
+       amfree(qdisk);
        return -1;
     }
 
@@ -424,8 +487,9 @@ char *disk;
 }
 
 
-static int is_config_valid(config)
-char *config;
+static int
+is_config_valid(
+    char *     config)
 {
     char *conffile;
     char *conf_diskfile;
@@ -474,6 +538,8 @@ char *config;
     }
     amfree(conf_tapelist);
 
+    dbrename(config, DBG_SUBDIR_SERVER);
+
     output_find = find_dump(1, &disk_list);
     sort_find_result("DLKHpB", &output_find);
 
@@ -494,23 +560,32 @@ char *config;
 }
 
 
-static int build_disk_table()
+static int
+build_disk_table(void)
 {
-    char date[3 * NUM_STR_SIZE + 2 + 1];
-    long last_datestamp;
-    int last_filenum;
+    char *date;
+    char *last_timestamp;
+    off_t last_filenum;
     int last_level;
     int last_partnum;
     find_result_t *find_output;
 
-    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+    if (config_name == NULL) {
        reply(590, "Must set config,host,disk before building disk table");
        return -1;
     }
+    else if (dump_hostname == NULL) {
+       reply(590, "Must set host,disk before building disk table");
+       return -1;
+    }
+    else if (disk_name == NULL) {
+       reply(590, "Must set disk before building disk table");
+       return -1;
+    }
 
     clear_list();
-    last_datestamp = -1;
-    last_filenum = -1;
+    last_timestamp = NULL;
+    last_filenum = (off_t)-1;
     last_level = -1;
     last_partnum = -1;
     for(find_output = output_find;
@@ -529,71 +604,85 @@ static int build_disk_table()
             * for the same datestamp after we see a holding disk entry
             * (as indicated by a filenum of zero).
             */
-           if(find_output->datestamp == last_datestamp &&
+           if(last_timestamp &&
+              strcmp(find_output->timestamp, last_timestamp) == 0 &&
               find_output->level == last_level && 
               partnum == last_partnum && last_filenum == 0) {
                continue;
            }
-           last_datestamp = find_output->datestamp;
+           last_timestamp = find_output->timestamp;
            last_filenum = find_output->filenum;
            last_level = find_output->level;
            last_partnum = partnum;
-           snprintf(date, sizeof(date), "%04d-%02d-%02d",
-                       find_output->datestamp/10000,
-                       (find_output->datestamp/100) %100,
-                       find_output->datestamp %100);
+           date = amindexd_nicedate(find_output->timestamp);
            add_dump(date, find_output->level, find_output->label, 
                     find_output->filenum, partnum);
-           dbprintf(("%s: - %s %d %s %d %d\n",
+           dbprintf(("%s: - %s %d %s " OFF_T_FMT " %d\n",
                     debug_prefix_time(NULL), date, find_output->level, 
-                    find_output->label, find_output->filenum, partnum));
+                    find_output->label,
+                    (OFF_T_FMT_TYPE)find_output->filenum,
+                    partnum));
        }
     }
     return 0;
 }
 
 
-static int disk_history_list()
+static int
+disk_history_list(void)
 {
     DUMP_ITEM *item;
+    char date[20];
 
-    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+    if (config_name == NULL) {
        reply(502, "Must set config,host,disk before listing history");
        return -1;
     }
+    else if (dump_hostname == NULL) {
+       reply(502, "Must set host,disk before listing history");
+       return -1;
+    }
+    else if (disk_name == NULL) {
+       reply(502, "Must set disk before listing history");
+       return -1;
+    }
 
-    lreply(200, " Dump history for config \"%s\" host \"%s\" disk \"%s\"",
-         config_name, dump_hostname, disk_name);
+    lreply(200, " Dump history for config \"%s\" host \"%s\" disk %s",
+         config_name, dump_hostname, qdisk_name);
 
     for (item=first_dump(); item!=NULL; item=next_dump(item)){
         char *tapelist_str = marshal_tapelist(item->tapes, 1);
 
+       strncpy(date, item->date, 20);
+       date[19] = '\0';
+       if(!am_has_feature(their_features,fe_amrecover_timestamp))
+           date[10] = '\0';
+
        if(am_has_feature(their_features, fe_amindexd_marshall_in_DHST)){
-           str_buffer_size = strlen(item->date) + NUM_STR_SIZE +
-                             strlen(tapelist_str) + 9;
-           lreply(201, " %s %d %s", item->date, item->level, tapelist_str);
+           lreply(201, " %s %d %s", date, item->level, tapelist_str);
        }
        else{
-           str_buffer_size = strlen(item->date) + NUM_STR_SIZE +
-                             strlen(tapelist_str) + NUM_STR_SIZE + 9;
-           lreply(201, " %s %d %s %d", item->date, item->level, tapelist_str,
-              item->file);
+           lreply(201, " %s %d %s " OFF_T_FMT, date, item->level,
+               tapelist_str, (OFF_T_FMT_TYPE)item->file);
        }
-       str_buffer_size = STR_SIZE;
+       amfree(tapelist_str);
     }
 
-    reply(200, "Dump history for config \"%s\" host \"%s\" disk \"%s\"",
-         config_name, dump_hostname, disk_name);
+    reply(200, "Dump history for config \"%s\" host \"%s\" disk %s",
+         config_name, dump_hostname, qdisk_name);
 
     return 0;
 }
 
 
-/* is the directory dir backed up - dir assumed complete relative to
-   disk mount point */
+/*
+ * is the directory dir backed up - dir assumed complete relative to
+ * disk mount point
+ */
 /* opaque version of command */
-static int is_dir_valid_opaque(dir)
-char *dir;
+static int
+is_dir_valid_opaque(
+    char *dir)
 {
     DUMP_ITEM *item;
     char *line = NULL;
@@ -602,21 +691,29 @@ char *dir;
     char *ldir = NULL;
     char *filename_gz = NULL;
     char *filename = NULL;
-    int ldir_len;
+    size_t ldir_len;
     static char *emsg = NULL;
 
     if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
        reply(502, "Must set config,host,disk before asking about directories");
        return -1;
     }
-    if (target_date == NULL) {
+    else if (dump_hostname == NULL) {
+       reply(502, "Must set host,disk before asking about directories");
+       return -1;
+    }
+    else if (disk_name == NULL) {
+       reply(502, "Must set disk before asking about directories");
+       return -1;
+    }
+    else if (target_date == NULL) {
        reply(502, "Must set date before asking about directories");
        return -1;
     }
 
     /* scan through till we find first dump on or before date */
     for (item=first_dump(); item!=NULL; item=next_dump(item))
-       if (strcmp(item->date, target_date) <= 0)
+       if (cmp_date(item->date, target_date) <= 0)
            break;
 
     if (item == NULL)
@@ -655,6 +752,8 @@ char *dir;
            return -1;
        }
        for(; (line = agets(fp)) != NULL; free(line)) {
+           if (line[0] == '\0')
+               continue;
            if (strncmp(line, ldir, ldir_len) != 0) {
                continue;                       /* not found yet */
            }
@@ -679,13 +778,14 @@ char *dir;
     return -1;
 }
 
-static int opaque_ls(dir,recursive)
-char *dir;
-int  recursive;
+static int
+opaque_ls(
+    char *     dir,
+    int                recursive)
 {
     DUMP_ITEM *dump_item;
     DIR_ITEM *dir_item;
-    int last_level;
+    int level, last_level;
     static char *emsg = NULL;
     am_feature_e marshall_feature;
 
@@ -697,18 +797,26 @@ int  recursive;
 
     clear_dir_list();
 
-    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+    if (config_name == NULL) {
        reply(502, "Must set config,host,disk before listing a directory");
        return -1;
     }
-    if (target_date == NULL) {
+    else if (dump_hostname == NULL) {
+       reply(502, "Must set host,disk before listing a directory");
+       return -1;
+    }
+    else if (disk_name == NULL) {
+       reply(502, "Must set disk before listing a directory");
+       return -1;
+    }
+    else if (target_date == NULL) {
        reply(502, "Must set date before listing a directory");
        return -1;
     }
 
     /* scan through till we find first dump on or before date */
     for (dump_item=first_dump(); dump_item!=NULL; dump_item=next_dump(dump_item))
-       if (strcmp(dump_item->date, target_date) <= 0)
+       if (cmp_date(dump_item->date, target_date) <= 0)
            break;
 
     if (dump_item == NULL)
@@ -742,49 +850,23 @@ int  recursive;
 
     /* return the information to the caller */
     lreply(200, " Opaque list of %s", dir);
-        for (dir_item = get_dir_list(); dir_item != NULL; 
-             dir_item = dir_item->next) {
-            char *tapelist_str;
-
-            if (!am_has_feature(their_features, marshall_feature) &&
-                (num_entries(dir_item->dump->tapes) > 1 ||
-                dir_item->dump->tapes->numfiles > 1)) {
-                fast_lreply(501, " ERROR: Split dumps not supported"
-                            " with old version of amrecover.");
-                break;
-            } else {
-                if (am_has_feature(their_features, marshall_feature)) {
-                    tapelist_str = marshal_tapelist(dir_item->dump->tapes, 1);
-                } else {
-                    tapelist_str = dir_item->dump->tapes->label;
-                }
-                
-                if((!recursive && am_has_feature(their_features,
-                                                 fe_amindexd_fileno_in_OLSD))
-                   ||
-                   (recursive && am_has_feature(their_features,
-                                                fe_amindexd_fileno_in_ORLD))) {
-                    str_buffer_size = strlen(dir_item->dump->date) +
-                        NUM_STR_SIZE + strlen(tapelist_str) + 
-                        strlen(dir_item->path) + NUM_STR_SIZE + 9;
-                    fast_lreply(201, " %s %d %s %d %s",
-                                dir_item->dump->date, dir_item->dump->level,
-                                tapelist_str, dir_item->dump->file,
-                                dir_item->path);
-                }
-                else {
-                    str_buffer_size = strlen(dir_item->dump->date) +
-                        NUM_STR_SIZE + strlen(tapelist_str) +
-                        strlen(dir_item->path) + 9;
-                    fast_lreply(201, " %s %d %s %s",
-                                dir_item->dump->date, dir_item->dump->level,
-                                tapelist_str, dir_item->path);
-                }
-               if(am_has_feature(their_features, marshall_feature)) {
-                   amfree(tapelist_str);
+    for(level=0; level<=9; level++) {
+       for (dir_item = get_dir_list(); dir_item != NULL; 
+            dir_item = dir_item->next) {
+
+           if(dir_item->dump->level == level) {
+               if (!am_has_feature(their_features, marshall_feature) &&
+                   (num_entries(dir_item->dump->tapes) > 1 ||
+                   dir_item->dump->tapes->numfiles > 1)) {
+                   fast_lreply(501, " ERROR: Split dumps not supported"
+                               " with old version of amrecover.");
+                   break;
                }
-                str_buffer_size = STR_SIZE;
-            }
+               else {
+                   opaque_ls_one(dir_item, marshall_feature, recursive);
+               }
+           }
+       }
     }
     reply(200, " Opaque list of %s", dir);
 
@@ -792,10 +874,57 @@ int  recursive;
     return 0;
 }
 
+void opaque_ls_one(
+    DIR_ITEM *  dir_item,
+    am_feature_e marshall_feature,
+    int                 recursive)
+{
+   char date[20];
+   char *tapelist_str;
+    char *qpath;
 
-/* returns the value of changer or tapedev from the amanda.conf file if set,
-   otherwise reports an error */
-static int tapedev_is()
+    if (am_has_feature(their_features, marshall_feature)) {
+       tapelist_str = marshal_tapelist(dir_item->dump->tapes, 1);
+    } else {
+       tapelist_str = dir_item->dump->tapes->label;
+    }
+
+    strncpy(date, dir_item->dump->date, 20);
+    date[19] = '\0';
+    if(!am_has_feature(their_features,fe_amrecover_timestamp))
+       date[10] = '\0';
+
+    qpath = quote_string(dir_item->path);
+    if((!recursive && am_has_feature(their_features,
+                                    fe_amindexd_fileno_in_OLSD)) ||
+       (recursive && am_has_feature(their_features,
+                                   fe_amindexd_fileno_in_ORLD))) {
+       fast_lreply(201, " %s %d %s " OFF_T_FMT " %s",
+                   date,
+                   dir_item->dump->level,
+                   tapelist_str,
+                   (OFF_T_FMT_TYPE)dir_item->dump->file,
+                   qpath);
+    }
+    else {
+
+       fast_lreply(201, " %s %d %s %s",
+                   date, dir_item->dump->level,
+                   tapelist_str, qpath);
+    }
+    amfree(qpath);
+    if(am_has_feature(their_features, marshall_feature)) {
+       amfree(tapelist_str);
+    }
+}
+
+/*
+ * returns the value of changer or tapedev from the amanda.conf file if set,
+ * otherwise reports an error
+ */
+
+static int
+tapedev_is(void)
 {
     char *result;
 
@@ -838,24 +967,34 @@ static int tapedev_is()
 
 
 /* returns YES if dumps for disk are compressed, NO if not */
-static int are_dumps_compressed()
+static int
+are_dumps_compressed(void)
 {
     disk_t *diskp;
 
     /* check state okay to do this */
-    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+    if (config_name == NULL) {
        reply(501, "Must set config,host,disk name before asking about dumps.");
        return -1;
     }
+    else if (dump_hostname == NULL) {
+       reply(501, "Must set host,disk name before asking about dumps.");
+       return -1;
+    }
+    else if (disk_name == NULL) {
+       reply(501, "Must set disk name before asking about dumps.");
+       return -1;
+    }
 
     /* now go through the list of disks and find which have indexes */
-    for (diskp = disk_list.head; diskp != NULL; diskp = diskp->next)
+    for (diskp = disk_list.head; diskp != NULL; diskp = diskp->next) {
        if ((strcasecmp(diskp->host->hostname, dump_hostname) == 0)
-           && (strcmp(diskp->name, disk_name) == 0))
+               && (strcmp(diskp->name, disk_name) == 0)) {
            break;
+       }
+    }
 
-    if (diskp == NULL)
-    {
+    if (diskp == NULL) {
        reply(501, "Couldn't find host/disk in disk file.");
        return -1;
     }
@@ -869,9 +1008,10 @@ static int are_dumps_compressed()
     return 0;
 }
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     char *line = NULL, *part = NULL;
     char *s, *fp;
@@ -880,14 +1020,14 @@ char **argv;
     socklen_t socklen;
     struct sockaddr_in his_addr;
     struct hostent *his_name;
-    char *arg;
+    char *arg = NULL;
     char *cmd;
-    int len;
+    size_t len;
     int user_validated = 0;
     char *errstr = NULL;
-    char *pgm = "amindexd";                    /* in case argv[0] is not set */
+    char *pgm = "amindexd";            /* in case argv[0] is not set */
 
-    safe_fd(-1, 0);
+    safe_fd(DATA_FD_OFFSET, 2);
     safe_cd();
 
     /*
@@ -916,16 +1056,19 @@ char **argv;
     if(geteuid() == 0) {
        if(client_uid == (uid_t) -1) {
            error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+           /*NOTREACHED*/
        }
 
+       /*@ignore@*/
        initgroups(CLIENT_LOGIN, client_gid);
+       /*@end@*/
        setgid(client_gid);
        setuid(client_uid);
     }
 
 #endif /* FORCE_USERID */
 
-    dbopen();
+    dbopen(DBG_SUBDIR_SERVER);
     dbprintf(("%s: version %s\n", get_pname(), version()));
 
     if(argv == NULL) {
@@ -955,6 +1098,21 @@ char **argv;
        argv++;
     }
 
+    if(argc > 0 && strcmp(*argv, "amandad") == 0) {
+       from_amandad = 1;
+       argc--;
+       argv++;
+       if(argc > 0) {
+           amandad_auth = *argv;
+           argc--;
+           argv++;
+       }
+    }
+    else {
+       from_amandad = 0;
+       safe_fd(-1, 0);
+    }
+
     if (argc > 0) {
        config_name = stralloc(*argv);
        config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
@@ -962,9 +1120,11 @@ char **argv;
        argv++;
     }
 
-    if(gethostname(local_hostname, sizeof(local_hostname)-1) == -1)
+    if(gethostname(local_hostname, SIZEOF(local_hostname)-1) == -1) {
        error("gethostname: %s", strerror(errno));
-    local_hostname[sizeof(local_hostname)-1] = '\0';
+       /*NOTREACHED*/
+    }
+    local_hostname[SIZEOF(local_hostname)-1] = '\0';
 
     /* now trim domain off name */
     s = local_hostname;
@@ -972,47 +1132,95 @@ char **argv;
     while(ch && ch != '.') ch = *s++;
     s[-1] = '\0';
 
-    if(amindexd_debug) {
-       /*
-        * Fake the remote address as the local address enough to get
-        * through the security check.
-        */
-       his_name = gethostbyname(local_hostname);
-       if(his_name == NULL) {
-           error("gethostbyname(%s) failed\n", local_hostname);
+
+    if(from_amandad == 0) {
+       if(amindexd_debug) {
+           /*
+            * Fake the remote address as the local address enough to get
+            * through the security check.
+            */
+           his_name = gethostbyname(local_hostname);
+           if(his_name == NULL) {
+               error("gethostbyname(%s) failed\n", local_hostname);
+                /*NOTREACHED*/
+           }
+           assert((sa_family_t)his_name->h_addrtype == (sa_family_t)AF_INET);
+           his_addr.sin_family = (sa_family_t)his_name->h_addrtype;
+           his_addr.sin_port = (in_port_t)htons(0);
+           memcpy((void *)&his_addr.sin_addr.s_addr,
+                  (void *)his_name->h_addr_list[0], 
+                   (size_t)his_name->h_length);
+       } else {
+           /* who are we talking to? */
+           socklen = sizeof (his_addr);
+           if (getpeername(0, (struct sockaddr *)&his_addr, &socklen) == -1)
+               error("getpeername: %s", strerror(errno));
        }
-       assert(his_name->h_addrtype == AF_INET);
-       his_addr.sin_family = his_name->h_addrtype;
-       his_addr.sin_port = htons(0);
-       memcpy((char *)&his_addr.sin_addr.s_addr,
-              (char *)his_name->h_addr_list[0], his_name->h_length);
-    } else {
-       /* who are we talking to? */
-       socklen = sizeof (his_addr);
-       if (getpeername(0, (struct sockaddr *)&his_addr, &socklen) == -1)
-           error("getpeername: %s", strerror(errno));
-    }
-    if (his_addr.sin_family != AF_INET || ntohs(his_addr.sin_port) == 20)
-    {
-       error("connection rejected from %s family %d port %d",
-             inet_ntoa(his_addr.sin_addr), his_addr.sin_family,
-             htons(his_addr.sin_port));
+       if ((his_addr.sin_family != (sa_family_t)AF_INET)
+               || (ntohs(his_addr.sin_port) == 20)) {
+           error("connection rejected from %s family %d port %d",
+                 inet_ntoa(his_addr.sin_addr), his_addr.sin_family,
+                 htons(his_addr.sin_port));
+           /*NOTREACHED*/
+       }
+       if ((his_name = gethostbyaddr((char *)&(his_addr.sin_addr),
+                                     sizeof(his_addr.sin_addr),
+                                     AF_INET)) == NULL) {
+           error("gethostbyaddr(%s): hostname lookup failed",
+                 inet_ntoa(his_addr.sin_addr));
+           /*NOTREACHED*/
+       }
+       fp = s = stralloc(his_name->h_name);
+       ch = *s++;
+       while(ch && ch != '.') ch = *s++;
+       s[-1] = '\0';
+       remote_hostname = newstralloc(remote_hostname, fp);
+       s[-1] = (char)ch;
+       amfree(fp);
     }
-    if ((his_name = gethostbyaddr((char *)&(his_addr.sin_addr),
-                                 sizeof(his_addr.sin_addr),
-                                 AF_INET)) == NULL) {
-       error("gethostbyaddr(%s): hostname lookup failed",
-             inet_ntoa(his_addr.sin_addr));
+    else {
+       cmdfdout  = DATA_FD_OFFSET + 0;
+       cmdfdin   = DATA_FD_OFFSET + 1;
+
+       /* read the REQ packet */
+       for(; (line = agets(stdin)) != NULL; free(line)) {
+#define sc "OPTIONS "
+           if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+#undef sc
+               g_options = parse_g_options(line+8, 1);
+               if(!g_options->hostname) {
+                   g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1);
+                   gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH);
+                   g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0';
+               }
+           }
+       }
+       amfree(line);
+
+       if(amandad_auth && g_options->auth) {
+           if(strcasecmp(amandad_auth, g_options->auth) != 0) {
+               printf("ERROR recover program ask for auth=%s while amindexd is configured for '%s'\n",
+                      g_options->auth, amandad_auth);
+               error("amindexd: ERROR recover program ask for auth=%s while amindexd is configured for '%s'",
+                     g_options->auth, amandad_auth);
+               /*NOTREACHED*/
+           }
+       }
+       /* send the REP packet */
+       printf("CONNECT MESG %d\n", DATA_FD_OFFSET);
+       printf("\n");
+       fflush(stdin);
+       fflush(stdout);
+       if ((dup2(cmdfdout, fileno(stdout)) < 0)
+                || (dup2(cmdfdin, fileno(stdin)) < 0)) {
+           error("amandad: Failed to setup stdin or stdout");
+           /*NOTREACHED*/
+       }
     }
-    fp = s = his_name->h_name;
-    ch = *s++;
-    while(ch && ch != '.') ch = *s++;
-    s[-1] = '\0';
-    remote_hostname = newstralloc(remote_hostname, fp);
-    s[-1] = ch;
 
     /* clear these so we can detect when the have not been set by the client */
     amfree(dump_hostname);
+    amfree(qdisk_name);
     amfree(disk_name);
     amfree(target_date);
 
@@ -1026,11 +1234,12 @@ char **argv;
     reply(220, "%s AMANDA index server (%s) ready.", local_hostname,
          version());
 
+    user_validated = from_amandad;
+
     /* a real simple parser since there are only a few commands */
     while (1)
     {
        /* get a line from the client */
-       amfree(line);
        while(1) {
            if((part = agets(stdin)) == NULL) {
                if(errno != 0) {
@@ -1053,13 +1262,9 @@ char **argv;
                dbclose();
                return 1;               /* they hung up? */
            }
-           if(line) {
-               strappend(line, part);
-               amfree(part);
-           } else {
-               line = part;
-               part = NULL;
-           }
+           strappend(line, part);      /* Macro: line can be null */
+           amfree(part);
+
            if(amindexd_debug) {
                break;                  /* we have a whole line */
            }
@@ -1077,13 +1282,15 @@ char **argv;
 
        dbprintf(("%s: > %s\n", debug_prefix_time(NULL), line));
 
-       arg = NULL;
+       if (arg != NULL)
+           amfree(arg);
        s = line;
        ch = *s++;
 
        skip_whitespace(s, ch);
        if(ch == '\0') {
            reply(500, "Command not recognised/incorrect: %s", line);
+           amfree(line);
            continue;
        }
        cmd = s - 1;
@@ -1096,7 +1303,8 @@ char **argv;
            skip_whitespace(s, ch);             /* find the argument */
            if (ch) {
                arg = s-1;
-               skip_non_whitespace(s, ch);
+               skip_quoted_string(s, ch);
+               arg = unquote_string(arg);
            }
        }
 
@@ -1105,6 +1313,7 @@ char **argv;
            user_validated = check_security(&his_addr, arg, 0, &errstr);
            if(user_validated) {
                reply(200, "Access OK");
+               amfree(line);
                continue;
            }
        }
@@ -1117,6 +1326,7 @@ char **argv;
        }
 
        if (strcmp(cmd, "QUIT") == 0) {
+           amfree(line);
            break;
        } else if (strcmp(cmd, "HOST") == 0 && arg) {
            /* set host we are restoring */
@@ -1125,33 +1335,74 @@ char **argv;
            {
                dump_hostname = newstralloc(dump_hostname, arg);
                reply(200, "Dump host set to %s.", dump_hostname);
+               amfree(qdisk_name);             /* invalidate any value */
                amfree(disk_name);              /* invalidate any value */
            }
-           s[-1] = ch;
+           s[-1] = (char)ch;
+       } else if (strcmp(cmd, "LISTHOST") == 0) {
+           disk_t *disk, 
+                   *diskdup;
+           int nbhost = 0,
+                found = 0;
+           s[-1] = '\0';
+           if (config_name == NULL) {
+               reply(501, "Must set config before listhost");
+           }
+           else {
+               lreply(200, " List hosts for config %s", config_name);
+               for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
+                    found = 0;
+                   for (diskdup = disk_list.head; diskdup!=disk; diskdup = diskdup->next) {
+                       if(strcmp(diskdup->host->hostname, disk->host->hostname) == 0) {
+                          found = 1;
+                          break;
+                       }
+                    }
+                    if(!found){
+                       fast_lreply(201, " %s", disk->host->hostname);
+                        nbhost++;
+                    }
+               }
+               if(nbhost > 0) {
+                   reply(200, " List hosts for config %s", config_name);
+               }
+               else {
+                   reply(200, "No hosts for config %s", config_name);
+               }
+           }
+           s[-1] = (char)ch;
        } else if (strcmp(cmd, "DISK") == 0 && arg) {
            s[-1] = '\0';
            if (is_disk_valid(arg) != -1) {
                disk_name = newstralloc(disk_name, arg);
+               qdisk_name = quote_string(disk_name);
                if (build_disk_table() != -1) {
-                   reply(200, "Disk set to %s.", disk_name);
+                   reply(200, "Disk set to %s.", qdisk_name);
                }
            }
-           s[-1] = ch;
+           s[-1] = (char)ch;
        } else if (strcmp(cmd, "LISTDISK") == 0) {
+           char *qname;
            disk_t *disk;
            int nbdisk = 0;
            s[-1] = '\0';
-           if (config_name == NULL || dump_hostname == NULL) {
+           if (config_name == NULL) {
                reply(501, "Must set config, host before listdisk");
            }
+           else if (dump_hostname == NULL) {
+               reply(501, "Must set host before listdisk");
+           }
            else if(arg) {
                lreply(200, " List of disk for device %s on host %s", arg,
                       dump_hostname);
                for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
-                   if(strcmp(disk->host->hostname, dump_hostname) == 0 &&
-                      ((disk->device && strcmp(disk->device, arg) == 0) ||
-                       (!disk->device && strcmp(disk->name, arg) == 0))) {
-                       fast_lreply(201, " %s", disk->name);
+
+                   if (strcmp(disk->host->hostname, dump_hostname) == 0 &&
+                     ((disk->device && strcmp(disk->device, arg) == 0) ||
+                     (!disk->device && strcmp(disk->name, arg) == 0))) {
+                       qname = quote_string(disk->name);
+                       fast_lreply(201, " %s", qname);
+                       amfree(qname);
                        nbdisk++;
                    }
                }
@@ -1168,7 +1419,9 @@ char **argv;
                lreply(200, " List of disk for host %s", dump_hostname);
                for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
                    if(strcmp(disk->host->hostname, dump_hostname) == 0) {
-                       fast_lreply(201, " %s", disk->name);
+                       qname = quote_string(disk->name);
+                       fast_lreply(201, " %s", qname);
+                       amfree(qname);
                        nbdisk++;
                    }
                }
@@ -1179,7 +1432,7 @@ char **argv;
                    reply(200, "No disk for host %s", dump_hostname);
                }
            }
-           s[-1] = ch;
+           s[-1] = (char)ch;
        } else if (strcmp(cmd, "SCNF") == 0 && arg) {
            s[-1] = '\0';
            amfree(config_name);
@@ -1188,13 +1441,14 @@ char **argv;
            config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
            if (is_config_valid(arg) != -1) {
                amfree(dump_hostname);          /* invalidate any value */
+               amfree(qdisk_name);             /* invalidate any value */
                amfree(disk_name);              /* invalidate any value */
                reply(200, "Config set to %s.", config_name);
            } else {
                amfree(config_name);
                amfree(config_dir);
            }
-           s[-1] = ch;
+           s[-1] = (char)ch;
        } else if (strcmp(cmd, "FEATURES") == 0 && arg) {
            char *our_feature_string = NULL;
            char *their_feature_string = NULL;
@@ -1203,17 +1457,17 @@ char **argv;
            am_release_feature_set(their_features);
            our_features = am_init_feature_set();
            our_feature_string = am_feature_to_string(our_features);
-           their_feature_string = newstralloc(target_date, arg);
+           their_feature_string = newstralloc(their_feature_string, arg);
            their_features = am_string_to_feature(their_feature_string);
            reply(200, "FEATURES %s", our_feature_string);
            amfree(our_feature_string);
            amfree(their_feature_string);
-           s[-1] = ch;
+           s[-1] = (char)ch;
        } else if (strcmp(cmd, "DATE") == 0 && arg) {
            s[-1] = '\0';
            target_date = newstralloc(target_date, arg);
            reply(200, "Working date set to %s.", target_date);
-           s[-1] = ch;
+           s[-1] = (char)ch;
        } else if (strcmp(cmd, "DHST") == 0) {
            (void)disk_history_list();
        } else if (strcmp(cmd, "OISD") == 0 && arg) {
@@ -1223,7 +1477,7 @@ char **argv;
        } else if (strcmp(cmd, "OLSD") == 0 && arg) {
            (void)opaque_ls(arg,0);
        } else if (strcmp(cmd, "ORLD") == 0 && arg) {
-           (void)opaque_ls(arg,1);
+           (void)opaque_ls(arg, 1);
        } else if (strcmp(cmd, "TAPE") == 0) {
            (void)tapedev_is();
        } else if (strcmp(cmd, "DCMP") == 0) {
@@ -1232,12 +1486,57 @@ char **argv;
            *cmd_undo = cmd_undo_ch;    /* restore the command line */
            reply(500, "Command not recognised/incorrect: %s", cmd);
        }
+       amfree(line);
     }
-    amfree(line);
-
+    amfree(arg);
+    
     uncompress_remove = remove_files(uncompress_remove);
     free_find_result(&output_find);
     reply(200, "Good bye.");
     dbclose();
     return 0;
 }
+
+static char *
+amindexd_nicedate(
+    char *     datestamp)
+{
+    static char nice[20];
+    int year, month, day;
+    int hours, minutes, seconds;
+    char date[9], atime[7];
+    int  numdate, numtime;
+
+    strncpy(date, datestamp, 8);
+    date[8] = '\0';
+    numdate = atoi(date);
+    year  = numdate / 10000;
+    month = (numdate / 100) % 100;
+    day   = numdate % 100;
+
+    if(strlen(datestamp) <= 8) {
+       snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d",
+               year, month, day);
+    }
+    else {
+       strncpy(atime, &(datestamp[8]), 6);
+       atime[6] = '\0';
+       numtime = atoi(atime);
+       hours = numtime / 10000;
+       minutes = (numtime / 100) % 100;
+       seconds = numtime % 100;
+
+       snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d-%02d-%02d-%02d",
+               year, month, day, hours, minutes, seconds);
+    }
+
+    return nice;
+}
+
+static int
+cmp_date(
+    const char *       date1,
+    const char *       date2)
+{
+    return strncmp(date1, date2, strlen(date2));
+}
index b7bdc4ca04bfd00f805a306c409418ff385f1af6..ab5169bbc937819e6cd35c52aa5754ab7b65f962 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amlabel.c,v 1.43 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amlabel.c,v 1.53 2006/07/25 18:27:57 martinea Exp $
  *
  * write an Amanda label on a tape
  */
 
 /* local functions */
 
-int main P((int, char **));
-void usage P((char *argv0));
+int main(int argc, char **argv);
+void usage(void);
 
-void usage(argv0)
-char *argv0;
+void
+usage(void)
 {
-    fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>]\n",
-           argv0);
+    fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>] [-o configoption]*\n",
+           get_pname());
     exit(1);
 }
 
-int main(argc, argv)
-    int argc;
-    char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     char *conffile;
     char *conf_tapelist;
@@ -70,14 +71,15 @@ int main(argc, argv)
 #endif /* HAVE_LINUX_ZFTAPE_H */
     int have_changer;
     int force, tape_ok;
-    tape_t *tp;
     tapetype_t *tape;
-    long tt_blocksize_kb;
+    size_t tt_blocksize_kb;
     int slotcommand;
     uid_t uid_me;
     uid_t uid_dumpuser;
     char *dumpuser;
     struct passwd *pw;
+    int    new_argc;
+    char **new_argv;
 
 #ifdef HAVE_LIBVTBLC
     int vtbl_no      = -1;
@@ -91,6 +93,8 @@ int main(argc, argv)
 
     set_pname("amlabel");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -98,20 +102,22 @@ int main(argc, argv)
 
     erroutput_type = ERR_INTERACTIVE;
 
-    if(argc > 1 && strcmp(argv[1],"-f") == 0)
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+
+    if(new_argc > 1 && strcmp(new_argv[1],"-f") == 0)
         force=1;
     else force=0;
 
-    if(argc != 3+force && argc != 5+force)
-       usage(argv[0]);
+    if(new_argc != 3+force && new_argc != 5+force)
+       usage();
 
-    config_name = argv[1+force];
-    label = argv[2+force];
+    config_name = new_argv[1+force];
+    label = new_argv[2+force];
 
-    if(argc == 5+force) {
-       if(strcmp(argv[3+force], "slot"))
-           usage(argv[0]);
-       slotstr = argv[4+force];
+    if(new_argc == 5+force) {
+       if(strcmp(new_argv[3+force], "slot"))
+           usage();
+       slotstr = new_argv[4+force];
        slotcommand = 1;
     } else {
        slotstr = "current";
@@ -122,8 +128,13 @@ int main(argc, argv)
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if (read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     conf_tapelist = getconf_str(CNF_TAPELIST);
     if (*conf_tapelist == '/') {
        conf_tapelist = stralloc(conf_tapelist);
@@ -132,6 +143,7 @@ int main(argc, argv)
     }
     if (read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
     }
 
     uid_me = getuid();
@@ -140,37 +152,41 @@ int main(argc, argv)
 
     if ((pw = getpwnam(dumpuser)) == NULL) {
        error("cannot look up dump user \"%s\"", dumpuser);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
     uid_dumpuser = pw->pw_uid;
     if ((pw = getpwuid(uid_me)) == NULL) {
        error("cannot look up my own uid %ld", (long)uid_me);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
     if (uid_me != uid_dumpuser) {
        error("running as user \"%s\" instead of \"%s\"",
              pw->pw_name, dumpuser);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     labelstr = getconf_str(CNF_LABELSTR);
 
-    if(!match(labelstr, label))
+    if(!match(labelstr, label)) {
        error("label %s doesn't match labelstr \"%s\"", label, labelstr);
+       /*NOTREACHED*/
+    }
 
-    if((tp = lookup_tapelabel(label))!=NULL) {
-       if(!force)
+    if((lookup_tapelabel(label))!=NULL) {
+       if(!force) {
            error("label %s already on a tape\n",label);
+           /*NOTREACHED*/
+       }
     }
     tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
-    tt_blocksize_kb = tape->blocksize;
+    tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape);
 
     if((have_changer = changer_init()) == 0) {
        if(slotcommand) {
            fprintf(stderr,
             "%s: no tpchanger specified in \"%s\", so slot command invalid\n",
-                   argv[0], conffile);
-           usage(argv[0]);
+                   new_argv[0], conffile);
+           usage();
        }
        tapename = stralloc(getconf_str(CNF_TAPEDEV));
 #ifdef HAVE_LIBVTBLC
@@ -178,9 +194,11 @@ int main(argc, argv)
 #endif /* HAVE_LIBVTBLC */
     } else if(have_changer != 1) {
        error("changer initialization failed: %s", strerror(errno));
+       /*NOTREACHED*/
     } else {
        if(changer_loadslot(slotstr, &outslot, &tapename)) {
            error("could not load slot \"%s\": %s", slotstr, changer_resultstr);
+           /*NOTREACHED*/
        }
 
        printf("labeling tape in slot %s (%s):\n", outslot, tapename);
@@ -194,6 +212,7 @@ int main(argc, argv)
                                  (errno == EACCES) ? "tape is write-protected"
                                  : strerror(errno));
            error(errstr);
+           /*NOTREACHED*/
        }
     }
 #endif /* HAVE_LINUX_ZFTAPE_H */
@@ -205,6 +224,7 @@ int main(argc, argv)
        if(tapefd_rewind(fd) == -1) {
            putchar('\n');
            error(strerror(errno));
+           /*NOTREACHED*/
        }
     }
     else
@@ -212,6 +232,7 @@ int main(argc, argv)
     if((errstr = tape_rewind(tapename)) != NULL) {
        putchar('\n');
        error(errstr);
+       /*NOTREACHED*/
     }
 
     tape_ok=1;
@@ -230,7 +251,7 @@ int main(argc, argv)
                tape_ok=0;
        }
        else {
-           if((tp = lookup_tapelabel(oldlabel)) != NULL) {
+           if((lookup_tapelabel(oldlabel)) != NULL) {
                printf(", tape is active");
                if(!force)
                    tape_ok=0;
@@ -248,6 +269,7 @@ int main(argc, argv)
        if(tapefd_rewind(fd) == -1) {
            putchar('\n');
            error(strerror(errno));
+           /*NOTREACHED*/
        }
     }
     else
@@ -255,6 +277,7 @@ int main(argc, argv)
     if((errstr = tape_rewind(tapename)) != NULL) {
        putchar('\n');
        error(errstr);
+       /*NOTREACHED*/
     }
 
     if(tape_ok) {
@@ -262,51 +285,60 @@ int main(argc, argv)
 
 #ifdef HAVE_LINUX_ZFTAPE_H
        if (isa_zftape) {
-           errstr = tapefd_wrlabel(fd, "X", label, tt_blocksize_kb * 1024);
+           errstr = tapefd_wrlabel(fd, "X", label,
+                                   (tt_blocksize_kb * 1024));
            if(errstr != NULL) {
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }
        }
        else
 #endif /* HAVE_LINUX_ZFTAPE_H */
-       errstr = tape_wrlabel(tapename, "X", label, tt_blocksize_kb * 1024);
+       errstr = tape_wrlabel(tapename, "X", label,
+                             (tt_blocksize_kb * 1024));
        if(errstr != NULL) {
            putchar('\n');
            error(errstr);
+           /*NOTREACHED*/
        }
 
 #ifdef HAVE_LINUX_ZFTAPE_H
        if (isa_zftape) {
-           tapefd_weof(fd, 1);
+           tapefd_weof(fd, (off_t)1);
        }
 #endif /* HAVE_LINUX_ZFTAPE_H */
 
 #ifdef HAVE_LINUX_ZFTAPE_H
        if (isa_zftape) {
-           errstr = tapefd_wrendmark(fd, "X", tt_blocksize_kb * 1024);
+           errstr = tapefd_wrendmark(fd, "X",
+                                     (tt_blocksize_kb * 1024));
            if(errstr != NULL) {
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }
        }
        else
 #endif /* HAVE_LINUX_ZFTAPE_H */
-       errstr = tape_wrendmark(tapename, "X", tt_blocksize_kb * 1024);
+       errstr = tape_wrendmark(tapename, "X",
+                               (tt_blocksize_kb * 1024));
        if(errstr != NULL) {
            putchar('\n');
            error(errstr);
+           /*NOTREACHED*/
        }
 
 #ifdef HAVE_LINUX_ZFTAPE_H
        if (isa_zftape) {
-           tapefd_weof(fd, 1);
+           tapefd_weof(fd, (off_t)1);
 
            printf(",\nrewinding"); fflush(stdout); 
      
            if(tapefd_rewind(fd) == -1) { 
                putchar('\n'); 
                error(strerror(errno)); 
+               /*NOTREACHED*/
            } 
            close(fd);
 #ifdef HAVE_LIBVTBLC
@@ -323,6 +355,7 @@ int main(argc, argv)
                }
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }
            /* read volume table */
            if ((num_volumes = read_vtbl(fd, volumes, vtbl_buffer,
@@ -331,6 +364,7 @@ int main(argc, argv)
                                      "reading volume table: ", strerror(errno));
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }
            /* set date and volume label for first entry */
            vtbl_no = 0;
@@ -340,12 +374,14 @@ int main(argc, argv)
                                      "setting date for entry 1: ", strerror(errno));
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }
            if(set_label(label, volumes, num_volumes, vtbl_no)){
                errstr = newstralloc2(errstr,
                                      "setting label for entry 1: ", strerror(errno));
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }
            /* set date and volume label for last entry */
            vtbl_no = 1;
@@ -355,12 +391,14 @@ int main(argc, argv)
                                      "setting date for entry 2: ", strerror(errno));
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }
            if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
                errstr = newstralloc2(errstr,
                                      "setting label for entry 2: ", strerror(errno));
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }
            /* write volume table back */
            if (write_vtbl(fd, volumes, vtbl_buffer, num_volumes, first_seg,
@@ -369,6 +407,7 @@ int main(argc, argv)
                                      "writing volume table: ", strerror(errno));
                putchar('\n');
                error(errstr);
+               /*NOTREACHED*/
            }  
            close(fd);
 #endif /* HAVE_LIBVTBLC */
@@ -380,10 +419,13 @@ int main(argc, argv)
 
            if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
                putchar('\n');
-               if (strcmp(errstr, "not an amanda tape") != 0)
+               if (strcmp(errstr, "not an amanda tape") != 0) {
                    error(errstr);
+                   /*NOTREACHED*/
+               }
                error("no label found, are you sure %s is non-rewinding?",
                      tapename);
+               /*NOTREACHED*/
            }
 
            if (strcmp("X", olddatestamp) != 0 ||
@@ -392,6 +434,7 @@ int main(argc, argv)
                putchar('\n');
                error("read label %s back, timestamp %s (expected X), what now?",
                      oldlabel, olddatestamp);
+               /*NOTREACHED*/
            }
            amfree(oldlabel);
            amfree(olddatestamp);
@@ -402,32 +445,33 @@ int main(argc, argv)
                    conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
            if(write_tapelist(conf_tapelist_old)) {
                error("couldn't write tapelist: %s", strerror(errno));
+               /*NOTREACHED*/
            }
            amfree(conf_tapelist_old);
 
            /* XXX add cur_tape number to tape list structure */
            remove_tapelabel(label);
-           add_tapelabel(0, label);
+           add_tapelabel("0", label);
            if(write_tapelist(conf_tapelist)) {
                error("couldn't write tapelist: %s", strerror(errno));
+               /*NOTREACHED*/
            }
        } /* write tape list */
-
-        if(have_changer) {
-           /*  Now we try to inform the changer, about the new label */
-           /* changer_label(outslot,label); */
-       }
        printf(", done.\n");
     } else {
        printf("\ntape not labeled\n");
     }
 
+    clear_tapelist();
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
     amfree(outslot);
     amfree(tapename);
     amfree(conffile);
     amfree(conf_tapelist);
     amfree(config_dir);
     config_name=NULL;
+    dbclose();
 
     malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
index 35e504d72ae4bdcb86f4aaa8c4280d76fca591ab..f00c348e482f1d839027bcd931f2bd2649261f60 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: amlogroll.c,v 1.7 2005/09/20 21:32:26 jrjackson Exp $
+ * $Id: amlogroll.c,v 1.14 2006/07/25 18:27:57 martinea Exp $
  *
  * rename a live log file to the datestamped name.
  */
 
 char *datestamp;
 
-void handle_start P((void));
+void handle_start(void);
+int main(int argc, char **argv);
 
-int main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv)
 {
     char *conffile;
     char *logfname;
@@ -50,28 +49,37 @@ char **argv;
     unsigned long malloc_hist_1, malloc_size_1;
     unsigned long malloc_hist_2, malloc_size_2;
     char my_cwd[STR_SIZE];
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
 
     set_pname("amlogroll");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
     /* Process options */
     
     erroutput_type = ERR_INTERACTIVE;
 
-    if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+    if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
        error("cannot determine current working directory");
+       /*NOTREACHED*/
     }
 
-    if (argc < 2) {
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if (my_argc < 2) {
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
            config_name = stralloc(config_name + 1);
        }
     } else {
-       config_name = stralloc(argv[1]);
+       config_name = stralloc(my_argv[1]);
        config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     }
 
@@ -82,9 +90,14 @@ char **argv;
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if(read_conffile(conffile)) {
         error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     conf_logdir = getconf_str(CNF_LOGDIR);
     if (*conf_logdir == '/') {
         conf_logdir = stralloc(conf_logdir);
@@ -96,6 +109,7 @@ char **argv;
 
     if((logfile = fopen(logfname, "r")) == NULL) {
        error("could not open log %s: %s", logfname, strerror(errno));
+       /*NOTREACHED*/
     }
     amfree(logfname);
 
@@ -117,6 +131,8 @@ char **argv;
     amfree(datestamp);
     amfree(config_dir);
     amfree(config_name);
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
 
     malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
@@ -124,10 +140,12 @@ char **argv;
        malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
     }
 
+    dbclose();
+
     return 0;
 }
 
-void handle_start()
+void handle_start(void)
 {
     static int started = 0;
     char *s, *fp;
@@ -139,10 +157,10 @@ void handle_start()
 
        skip_whitespace(s, ch);
 #define sc "date"
-       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
            return;                             /* ignore bogus line */
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc) - 1;
        ch = s[-1];
 #undef sc
        skip_whitespace(s, ch);
@@ -153,7 +171,7 @@ void handle_start()
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        datestamp = newstralloc(datestamp, fp);
-       s[-1] = ch;
+       s[-1] = (char)ch;
 
        started = 1;
     }
index 300f7ddd1c2e1ad3790ad890a0f0c7af51b088ff..9f4ce99b71864faa3abe4fe4321d6e62d8cb81c4 100644 (file)
@@ -9,6 +9,7 @@ require 5.001;
 
 use FileHandle;
 use Getopt::Long;
+use Text::ParseWords;
 use Carp;
 use POSIX;
 
@@ -120,11 +121,12 @@ my $fh = new FileHandle "$amadmin $opt_config find|" or
     die "$0: error in opening `$amadmin $opt_config find' pipe: $!\n";
 <$fh>;
 while (<$fh>) {
+print "'$_'\n";
     chomp;
     next if /found Amanda directory/;
     next if /skipping cruft directory/;
     next if /skip-incr/;
-    ($date, $host, $disk, $level, $tape, $file, $part, $status) = split ' ', $_;
+    ($date, $host, $disk, $level, $tape, $file, $part, $status) = quotewords(" ", 0, $_);
     next if $date eq 'date';
     next if $date eq 'Warning:';
     next if $date eq 'Scanning';
index b0becf1878a513918546d2c0914cfe0cf91348c2..1f18ebaabadad97389a0c1353eb74891db38da52 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 #
 # amrmtape.sh
 # Time-stamp: <96/10/23 12:07:21 adrian>
index 79fe172a2be9d1a6809d81bc97d702f370a813f8..e4ad2aa1de07a0d4275923c94fa51f5fe4a1996c 100644 (file)
@@ -179,6 +179,13 @@ while(<AMDUMP>) {
                        push @datestamp, $gdatestamp;
                }
        }
+       elsif(/planner: timestamp (\S+)/) {
+               $gdatestamp = $1;
+               if(!defined $datestamp{$gdatestamp}) {
+                       $datestamp{$gdatestamp} = 1;
+                       push @datestamp, $gdatestamp;
+               }
+       }
        elsif(/setup_estimate: ([_\-\d\.A-Za-z]*):(\S+): command .*, options: *(\S+) *last_level -?\d+ next_level0 -?\d+ level_days \d+ *getting estimates (-?\d) \(-2\) (-?\d) \(-2\) (-?\d) \(-2\)/) {
                $host=$1;
                $partition=$2;
@@ -369,6 +376,7 @@ while(<AMDUMP>) {
                }
                $running_dumper{$2} = $hostpart;
                $error{$hostpart}="";
+               $size{$hostpart} = 0;
                $dumpers_active++;
                if(! defined($dumpers_active[$dumpers_active])) {
                        $dumpers_active[$dumpers_active]=0;
@@ -426,6 +434,7 @@ while(<AMDUMP>) {
                }
                $running_dumper{$2} = $hostpart;
                $error{$hostpart}="";
+               $size{$hostpart} = 0;
                $dumpers_active++;
                if(! defined($dumpers_active[$dumpers_active])) {
                        $dumpers_active[$dumpers_active]=0;
@@ -459,6 +468,7 @@ while(<AMDUMP>) {
                }
                $running_dumper{$2} = $hostpart;
                $error{$hostpart}="";
+               $size{$hostpart} = 0;
                $dumpers_active++;
                if(! defined($dumpers_active[$dumpers_active])) {
                        $dumpers_active[$dumpers_active]=0;
@@ -501,7 +511,7 @@ while(<AMDUMP>) {
                $error{$hostpart}="driver: (aborted:$error)";
                $dumpers_active--;
        }
-       elsif(/driver: result time (\S+) from (dumper\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) (\d+) (\d+) \[.*\]/) {
+       elsif(/driver: result time (\S+) from (dumper\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) (\d+) (\d+) "?\[.*\]"?/) {
                $current_time=$1;
                $serial=$4;
                $origsize=$5 / $unitdivisor;
@@ -514,9 +524,14 @@ while(<AMDUMP>) {
                $dump_time{$hostpart}=$1;
                $error{$hostpart}="";
                $dumpers_active--;
-               $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
+               if ($3 eq "PARTIAL") {
+                       $partial{$hostpart} = 1;
+               }
+               else {
+                       $partial{$hostpart} = 0;
+               }
        }
-       elsif(/driver: result time (\S+) from (chunker\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) \[.*\]/) {
+       elsif(/driver: result time (\S+) from (chunker\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) "?\[.*\]"?/) {
                $current_time=$1;
                $serial=$4;
                $outputsize=$5 / $unitdivisor;
@@ -527,7 +542,12 @@ while(<AMDUMP>) {
                $running_dumper{$2} = "0";
                $dump_time{$hostpart}=$1;
                $error{$hostpart}="";
-               $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
+               if ($3 eq "PARTIAL") {
+                       $partial{$hostpart} = 1;
+               }
+               else {
+                       $partial{$hostpart} = 0;
+               }
        }
        elsif(/driver: result time (\S+) from (dumper\d+): ABORT-FINISHED (\d+-\d+)/) {
                $current_time=$1;
@@ -576,7 +596,6 @@ while(<AMDUMP>) {
                if(!defined $level{$hostpart}) {
                        $level{$hostpart} = $level;
                }
-               $serial{$serial}=$hostpart;
                $taper_started{$hostpart}=1;
                $taper_finished{$hostpart}=0;
                $taper_time{$hostpart}=$1;
@@ -600,7 +619,6 @@ while(<AMDUMP>) {
                if(!defined $level{$hostpart}) {
                        $level{$hostpart} = $level;
                }
-               $serial{$serial}=$hostpart;
                $taper_started{$hostpart}=1;
                $taper_finished{$hostpart}=0;
                $taper_time{$hostpart}=$1;
@@ -628,7 +646,7 @@ while(<AMDUMP>) {
                $taper_finished{$hostpart}=0;
                $taper_time{$hostpart}=$1;
        }
-       elsif(/driver: result time (\S+) from taper: (DONE|PARTIAL) (\d+-\d+) (\S+) (\d+) \[sec (\S+) kb (\d+) kps/) {
+       elsif(/driver: result time (\S+) from taper: (DONE|PARTIAL) (\d+-\d+) (\S+) (\d+) "?\[sec (\S+) kb (\d+) kps/) {
                $current_time=$1;
                $serial=$3;
                $label=$4;
@@ -648,7 +666,12 @@ while(<AMDUMP>) {
                else {
                        $ntesize{$nb_tape} += $size{$hostpart};
                }
-               $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
+               if ($3 eq "PARTIAL") {
+                       $partial{$hostpart} = 1;
+               }
+               else {
+                       $partial{$hostpart} = 0;
+               }
        }
        elsif(/driver: result time (\S+) from taper: (TRY-AGAIN|TAPE-ERROR) (\d+-\d+) (.+)/) {
                $current_time=$1;
@@ -788,7 +811,8 @@ foreach $host (sort @hosts) {
                        $hostpart=&make_hostpart($host,$partition,$datestamp);
                        next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
                        $nb_partition++;
-                       if( !defined $size{$hostpart} && defined $holding_file{$hostpart}) {
+                       if( (!defined $size{$hostpart} || $size{$hostpart} == 0) &&
+                                defined $holding_file{$hostpart}) {
                                $size{$hostpart} = &dump_size($holding_file{$hostpart}) / (1024 * $unitdivisor);
                        }
                        $in_flush=0;
@@ -957,7 +981,8 @@ foreach $host (sort @hosts) {
                                                        if( defined $starttime ) {
                                                                print " (", &showtime($taper_time{$hostpart}), ")";
                                                        }
-                                                       print ", PARTIAL" if defined $partial{$hostpart};
+                                                       print ", PARTIAL" if defined $partial{$hostpart} &&
+                                                                                                          $partial{$hostpart} == 1;
                                                        print "\n";
                                                }
                                                $tpartition++;
@@ -1044,7 +1069,8 @@ foreach $host (sort @hosts) {
                                                                print " (", &showtime($dump_time{$hostpart}), ")";
                                                        }
                                                        print ", wait for writing to tape";
-                                                  print ", PARTIAL" if defined $partial{$hostpart};
+                                                  print ", PARTIAL" if defined $partial{$hostpart} &&
+                                                                                                               $partial{$hostpart} == 1;;
                                                        print "\n";
                                                }
                                                $dpartition++;
@@ -1066,7 +1092,8 @@ foreach $host (sort @hosts) {
                                                printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
                                                printf "%9d$unit", $size{$hostpart};
                                                print " waiting to flush";
-                                               print ", PARTIAL" if defined $partial{$hostpart};
+                                               print ", PARTIAL" if defined $partial{$hostpart} &&
+                                                                                                  $partial{$hostpart} == 1;
                                                print "\n";
                                        }
                                        $wfpartition++;
index c52cfdd5f7044ceebf2d285de052530caba23d46..72dcf17125de2fa3d960bbc72163e08bf9f72c16 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amtape.c,v 1.40.2.1 2006/04/14 11:32:07 martinea Exp $
+ * $Id: amtape.c,v 1.47 2006/07/25 18:27:57 martinea Exp $
  *
  * tape changer interface program
  */
 #include "version.h"
 
 /* local functions */
-void usage P((void));
-int main P((int argc, char **argv));
-void reset_changer P((int argc, char **argv));
-void eject_tape P((int argc, char **argv));
-void clean_tape P((int argc, char **argv));
-void load_slot P((int argc, char **argv));
-void load_label P((int argc, char **argv));
-void show_slots P((int argc, char **argv));
-void show_current P((int argc, char **argv));
-void update_labeldb P((int argc, char **argv));
-void amtape_taper_scan P((int argc, char **argv));
-void show_device P((int argc, char **argv));
-int update_one_slot P((void *ud, int rc, char *slotstr, char *device));
-int loadlabel_slot P((void *ud, int rc, char *slotstr, char *device));
-int show_init P((void *ud, int rc, int ns, int bk, int s));
-int show_init_all P((void *ud, int rc, int ns, int bk, int s));
-int show_init_current P((void *ud, int rc, int ns, int bk, int s));
-int show_slot P((void *ud, int rc, char *slotstr, char *device));
+void usage(void);
+int main(int argc, char **argv);
+void reset_changer(int argc, char **argv);
+void eject_tape(int argc, char **argv);
+void clean_tape(int argc, char **argv);
+void load_slot(int argc, char **argv);
+void load_label(int argc, char **argv);
+void show_slots(int argc, char **argv);
+void show_current(int argc, char **argv);
+void update_labeldb (int argc, char **argv);
+void amtape_taper_scan(int argc, char **argv);
+void show_device(int argc, char **argv);
+int update_one_slot (void *ud, int rc, char *slotstr, char *device);
+int loadlabel_slot(void *ud, int rc, char *slotstr, char *device);
+int show_init(void *ud, int rc, int ns, int bk, int s);
+int show_init_all(void *ud, int rc, int ns, int bk, int s);
+int show_init_current(void *ud, int rc, int ns, int bk, int s);
+int show_slot(void *ud, int rc, char *slotstr, char *device);
 
 static const struct {
     const char *name;
-    void (*fn) P((int, char **));
+    void (*fn)(int, char **);
     const char *usage;
 } cmdtab[] = {
     { "reset", reset_changer,
@@ -95,9 +95,10 @@ static const struct {
     { "update", update_labeldb,
        "update               update the label matchingdatabase"},
 };
-#define        NCMDS   (sizeof(cmdtab) / sizeof(cmdtab[0]))
+#define        NCMDS   (int)(sizeof(cmdtab) / sizeof(cmdtab[0]))
 
-void usage()
+void
+usage(void)
 {
     int i;
 
@@ -108,9 +109,10 @@ void usage()
     exit(1);
 }
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     char *conffile;
     char *conf_tapelist;
@@ -132,6 +134,8 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
     erroutput_type = ERR_INTERACTIVE;
@@ -144,8 +148,11 @@ char **argv;
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if (read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
     conf_tapelist = getconf_str(CNF_TAPELIST);
     if (*conf_tapelist == '/') {
        conf_tapelist = stralloc(conf_tapelist);
@@ -154,6 +161,7 @@ char **argv;
     }
     if (read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
     }
     amfree(conf_tapelist);
 
@@ -163,23 +171,25 @@ char **argv;
 
     if ((pw = getpwnam(dumpuser)) == NULL) {
        error("cannot look up dump user \"%s\"", dumpuser);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
     uid_dumpuser = pw->pw_uid;
     if ((pw = getpwuid(uid_me)) == NULL) {
        error("cannot look up my own uid %ld", (long)uid_me);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
     if (uid_me != uid_dumpuser) {
        error("running as user \"%s\" instead of \"%s\"",
              pw->pw_name, dumpuser);
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     if((have_changer = changer_init()) == 0) {
        error("no tpchanger specified in \"%s\"", conffile);
+       /*NOTREACHED*/
     } else if (have_changer != 1) {
        error("changer initialization failed: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 
     /* switch on command name */
@@ -205,17 +215,22 @@ char **argv;
        malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
     }
 
+    dbclose();
     return 0;
 }
 
 /* ---------------------------- */
 
-void reset_changer(argc, argv)
-int argc;
-char **argv;
+void
+reset_changer(
+    int                argc,
+    char **    argv)
 {
     char *slotstr = NULL;
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
+
     switch(changer_reset(&slotstr)) {
     case 0:
        fprintf(stderr, "%s: changer is reset, slot %s is loaded.\n",
@@ -227,18 +242,23 @@ char **argv;
        break;
     default:
        error("could not reset changer: %s", changer_resultstr);
+       /*NOTREACHED*/
     }
     amfree(slotstr);
 }
 
 
 /* ---------------------------- */
-void clean_tape(argc, argv)
-int argc;
-char **argv;
+void
+clean_tape(
+    int                argc,
+    char **    argv)
 {
     char *devstr = NULL;
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
+
     if(changer_clean(&devstr) == 0) {
        fprintf(stderr, "%s: device %s is clean.\n", get_pname(), devstr);
     } else {
@@ -250,12 +270,16 @@ char **argv;
 
 
 /* ---------------------------- */
-void eject_tape(argc, argv)
-int argc;
-char **argv;
+void
+eject_tape(
+    int                argc,
+    char **    argv)
 {
     char *slotstr = NULL;
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
+
     if(changer_eject(&slotstr) == 0) {
        fprintf(stderr, "%s: slot %s is ejected.\n", get_pname(), slotstr);
     } else {
@@ -268,9 +292,10 @@ char **argv;
 
 /* ---------------------------- */
 
-void load_slot(argc, argv)
-int argc;
-char **argv;
+void
+load_slot(
+    int                argc,
+    char **    argv)
 {
     char *slotstr = NULL, *devicename = NULL;
     char *errstr;
@@ -282,6 +307,7 @@ char **argv;
     is_advance = (strcmp(argv[1], "advance") == 0);
     if(changer_loadslot(argv[1], &slotstr, &devicename)) {
        error("could not load slot %s: %s", slotstr, changer_resultstr);
+       /*NOTREACHED*/
     }
     if(! is_advance && (errstr = tape_rewind(devicename)) != NULL) {
        fprintf(stderr,
@@ -306,14 +332,23 @@ char *datestamp;
 char *label = NULL, *first_match_label = NULL, *first_match = NULL;
 char *searchlabel, *labelstr;
 tape_t *tp;
+static int scan_init(void *ud, int rc, int ns, int bk, int s);
 
 static int 
-scan_init(ud, rc, ns, bk, s)
-     void *ud;
-     int rc, ns, bk, s;
+scan_init(
+    void *     ud,
+    int                rc,
+    int                ns,
+    int                bk,
+    int                s)
 {
-    if(rc)
+    (void)ud;  /* Quiet unused parameter warning */
+    (void)s;   /* Quiet unused parameter warning */
+
+    if(rc) {
        error("could not get changer info: %s", changer_resultstr);
+       /*NOTREACHED*/
+    }
 
     nslots = ns;
     backwards = bk;
@@ -321,16 +356,21 @@ scan_init(ud, rc, ns, bk, s)
     return 0;
 }
 
-int loadlabel_slot(ud, rc, slotstr, device)
-     void *ud;
-int rc;
-char *slotstr;
-char *device;
+int
+loadlabel_slot(
+    void *     ud,
+    int                rc,
+    char *     slotstr,
+    char *     device)
 {
     char *errstr;
 
-    if(rc > 1)
+    (void)ud;  /* Quiet unused parameter warning */
+
+    if(rc > 1) {
        error("could not load slot %s: %s", slotstr, changer_resultstr);
+       /*NOTREACHED*/
+    }
     else if(rc == 1)
        fprintf(stderr, "%s: slot %s: %s\n",
                get_pname(), slotstr, changer_resultstr);
@@ -361,9 +401,10 @@ char *device;
     return 0;
 }
 
-void load_label(argc, argv)
-int argc;
-char **argv;
+void
+load_label(
+    int                argc,
+    char **    argv)
 {
     if(argc != 2)
        usage();
@@ -388,52 +429,83 @@ char **argv;
 
 /* ---------------------------- */
 
-int show_init(ud, rc, ns, bk, s)
-     void *ud;
-int rc, ns, bk, s;
+int
+show_init(
+    void *     ud,
+    int                rc,
+    int                ns,
+    int                bk,
+    int                s)
 {
-    if(rc)
+    (void)ud;  /* Quiet unused parameter warning */
+    (void)s;   /* Quiet unused parameter warning */
+
+    if(rc) {
        error("could not get changer info: %s", changer_resultstr);
+       /*NOTREACHED*/
+    }
 
     nslots = ns;
     backwards = bk;
     return 0;
 }
 
-int show_init_all(ud, rc, ns, bk, s)
-     void *ud;
-int rc, ns, bk, s;
+int
+show_init_all(
+    void *     ud,
+    int                rc,
+    int                ns,
+    int                bk,
+    int                s)
 {
     int ret = show_init(NULL, rc, ns, bk, s);
+
+    (void)ud;  /* Quiet unused parameter warning */
+
     fprintf(stderr, "%s: scanning all %d slots in tape-changer rack:\n",
            get_pname(), nslots);
     return ret;
 }
 
-int show_init_current(ud, rc, ns, bk, s)
-     void *ud;
-int rc, ns, bk, s;
+int
+show_init_current(
+    void *     ud,
+    int                rc,
+    int                ns,
+    int                bk,
+    int                s)
 {
     int ret = show_init(NULL, rc, ns, bk, s);
+
+    (void)ud;  /* Quiet unused parameter warning */
+
     fprintf(stderr, "%s: scanning current slot in tape-changer rack:\n",
            get_pname());
     return ret;
 }
 
-int show_slot(ud, rc, slotstr, device)
-     void *ud;
-int rc;
-char *slotstr, *device;
+int
+show_slot(
+    void *     ud,
+    int                rc,
+    char *     slotstr,
+    char *     device)
 {
     char *errstr;
 
-    if(rc > 1)
+    (void)ud;  /* Quiet unused parameter warning */
+
+    if(rc > 1) {
        error("could not load slot %s: %s", slotstr, changer_resultstr);
-    else if(rc == 1)
+       /*NOTREACHED*/
+    }
+    else if(rc == 1) {
        fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
-    else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
+    }
+    else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL) {
        fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
-    else {
+       amfree(errstr);
+    } else {
        fprintf(stderr, "slot %s: date %-8s label %s\n",
                slotstr, datestamp, label);
     }
@@ -442,20 +514,26 @@ char *slotstr, *device;
     return 0;
 }
 
-void show_current(argc, argv)
-int argc;
-char **argv;
+void
+show_current(
+    int                argc,
+    char **    argv)
 {
+    (void)argv;        /* Quiet unused parameter warning */
+
     if(argc != 1)
        usage();
 
     changer_current(NULL, show_init_current, show_slot);
 }
 
-void show_slots(argc, argv)
-int argc;
-char **argv;
+void
+show_slots(
+    int                argc,
+    char **    argv)
 {
+    (void)argv;        /* Quiet unused parameter warning */
+
     if(argc != 1)
        usage();
 
@@ -464,12 +542,17 @@ char **argv;
 
 
 /* ---------------------------- */
-void amtape_taper_scan(argc, argv)
-int argc;
-char **argv;
+
+void
+amtape_taper_scan(
+    int                argc,
+    char **    argv)
 {
     char *device = NULL;
-    char *label = NULL, *errmsg = NULL;
+    char *label = NULL;
+
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
 
     if((tp = lookup_last_reusable_tape(0)) == NULL)
        searchlabel = NULL;
@@ -485,29 +568,32 @@ char **argv;
     if(searchlabel) fprintf(stderr, "tape label %s or ", searchlabel);
     fprintf(stderr, "a new tape.\n");
 
-    if (taper_scan(searchlabel, &label, &datestamp, &errmsg, &device) <= 0) {
-        fprintf(stderr, "%s\n", errmsg);
-    }
+    taper_scan(searchlabel, &label, &datestamp,&device, FILE_taperscan_output_callback, stderr);
 
     fprintf(stderr, "%s: label %s is now loaded.\n",
             get_pname(), label);
 
     amfree(label);
     amfree(datestamp);
-    amfree(errmsg);
     amfree(device);
 }
 
 /* ---------------------------- */
 
-void show_device(argc, argv)
-int argc;
-char **argv;
+void
+show_device(
+    int                argc,
+    char **    argv)
 {
     char *slot = NULL, *device = NULL;
 
-    if(changer_loadslot("current", &slot, &device))
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
+
+    if(changer_loadslot("current", &slot, &device)) {
        error("Could not load current slot.\n");
+       /*NOTREACHED*/
+    }
 
     printf("%s\n", device);
     amfree(slot);
@@ -516,16 +602,19 @@ char **argv;
 
 /* ---------------------------- */
 
-int update_one_slot(ud, rc, slotstr, device)
-    void *ud;
-    int rc;
-    char *slotstr;
-    char *device;
+int
+update_one_slot(
+    void *     ud,
+    int                rc,
+    char *     slotstr,
+    char *     device)
 {
     char *errstr = NULL;
     char *datestamp = NULL;
     char *label = NULL;
 
+    (void)ud;  /* Quiet unused parameter warning */
+
     if(rc > 1)
        error("could not load slot %s: %s", slotstr, changer_resultstr);
     else if(rc == 1)
@@ -543,13 +632,15 @@ int update_one_slot(ud, rc, slotstr, device)
     return 0;
 }
 
-void update_labeldb(argc, argv)
-int argc;
-char **argv;
+void
+update_labeldb(
+    int                argc,
+    char **    argv)
 {
+    (void)argv;        /* Quiet unused parameter warning */
+
     if(argc != 1)
        usage();
 
     changer_find(NULL, show_init_all, update_one_slot, NULL);
 }
-
index 681e4ab088ad11eedc33e033a9d69d3faf878d18..c3e511cf3b68eac7d631bb8d902b80d2c3237849 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amtrmidx.c,v 1.34 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amtrmidx.c,v 1.42 2006/07/25 18:27:57 martinea Exp $
  *
  * trims number of index files to only those still in system.  Well
  * actually, it keeps a few extra, plus goes back to the last level 0
 #include "tapefile.h"
 #include "find.h"
 #include "version.h"
+#include "util.h"
 
-static int sort_by_name_reversed(a, b)
-    const void *a;
-    const void *b;
+static int sort_by_name_reversed(const void *a, const void *b);
+
+int main(int argc, char **argv);
+
+static int sort_by_name_reversed(
+    const void *a,
+    const void *b)
 {
     char **ap = (char **) a;
     char **bp = (char **) b;
@@ -52,15 +57,12 @@ static int sort_by_name_reversed(a, b)
     return -1 * strcmp(*ap, *bp);
 }
 
-int main P((int, char **));
 
-int main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv)
 {
     disk_t *diskp;
     disklist_t diskl;
-    int i;
+    size_t i;
     char *conffile;
     char *conf_diskfile;
     char *conf_tapelist;
@@ -68,6 +70,8 @@ char **argv;
     find_result_t *output_find;
     time_t tmp_time;
     int amtrmidx_debug = 0;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
     safe_cd();
@@ -77,36 +81,48 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-    dbopen();
+    dbopen(DBG_SUBDIR_SERVER);
     dbprintf(("%s: version %s\n", argv[0], version()));
 
-    if (argc > 1 && strcmp(argv[1], "-t") == 0) {
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if (my_argc > 1 && strcmp(my_argv[1], "-t") == 0) {
        amtrmidx_debug = 1;
-       argc--;
-       argv++;
+       my_argc--;
+       my_argv++;
     }
 
-    if (argc < 2) {
-       fprintf(stderr, "Usage: %s [-t] <config>\n", argv[0]);
+    if (my_argc < 2) {
+       fprintf(stderr, "Usage: %s [-t] <config> [-o configoption]*\n", my_argv[0]);
        return 1;
     }
 
-    config_name = argv[1];
+    config_name = my_argv[1];
 
     config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if (read_conffile(conffile))
+    if (read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
+    }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     conf_diskfile = getconf_str(CNF_DISKFILE);
     if(*conf_diskfile == '/') {
        conf_diskfile = stralloc(conf_diskfile);
     } else {
        conf_diskfile = stralloc2(config_dir, conf_diskfile);
     }
-    if (read_diskfile(conf_diskfile, &diskl) < 0)
+    if (read_diskfile(conf_diskfile, &diskl) < 0) {
        error("could not load disklist \"%s\"", conf_diskfile);
+       /*NOTREACHED*/
+    }
     amfree(conf_diskfile);
 
     conf_tapelist = getconf_str(CNF_TAPELIST);
@@ -115,8 +131,10 @@ char **argv;
     } else {
        conf_tapelist = stralloc2(config_dir, conf_tapelist);
     }
-    if(read_tapelist(conf_tapelist))
+    if(read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
+    }
     amfree(conf_tapelist);
 
     output_find = find_dump(1, &diskl);
@@ -135,114 +153,145 @@ char **argv;
     {
        if (diskp->index)
        {
-           char *indexdir;
+           char *indexdir, *qindexdir;
            DIR *d;
            struct dirent *f;
            char **names;
-           int name_length;
-           int name_count;
+           size_t name_length;
+           size_t name_count;
            char *host;
-           char *disk;
+           char *disk, *qdisk;
+           size_t len_date;
 
-           dbprintf(("%s %s\n", diskp->host->hostname, diskp->name));
 
            /* get listing of indices, newest first */
            host = sanitise_filename(diskp->host->hostname);
            disk = sanitise_filename(diskp->name);
+           qdisk = quote_string(diskp->name);
            indexdir = vstralloc(conf_indexdir, "/",
                                 host, "/",
                                 disk, "/",
                                 NULL);
+           qindexdir = quote_string(indexdir);
+
+           dbprintf(("%s %s -> %s\n", diskp->host->hostname,
+                       qdisk, qindexdir));
            amfree(host);
+           amfree(qdisk);
            amfree(disk);
            if ((d = opendir(indexdir)) == NULL) {
-               dbprintf(("could not open index directory \"%s\"\n", indexdir));
+               dbprintf(("could not open index directory %s\n", qindexdir));
                amfree(indexdir);
+               amfree(qindexdir);
                continue;
            }
            name_length = 100;
-           names = (char **)alloc(name_length * sizeof(char *));
+           names = (char **)alloc(name_length * SIZEOF(char *));
            name_count = 0;
            while ((f = readdir(d)) != NULL) {
-               int l;
+               size_t l;
 
                if(is_dot_or_dotdot(f->d_name)) {
                    continue;
                }
-               for(i = 0; i < sizeof("YYYYMMDD")-1; i++) {
+               for(i = 0; i < SIZEOF("YYYYMMDDHHMMSS")-1; i++) {
                    if(! isdigit((int)(f->d_name[i]))) {
                        break;
                    }
                }
-               if(i < sizeof("YYYYMMDD")-1
-                   || f->d_name[i] != '_'
-                   || ! isdigit((int)(f->d_name[i+1]))) {
+               len_date = i;
+               /* len_date=8  for YYYYMMDD       */
+               /* len_date=14 for YYYYMMDDHHMMSS */
+               if((len_date != 8 && len_date != 14)
+                   || f->d_name[len_date] != '_'
+                   || ! isdigit((int)(f->d_name[len_date+1]))) {
                    continue;                   /* not an index file */
                }
                /*
                 * Clear out old index temp files.
                 */
-               l = strlen(f->d_name) - (sizeof(".tmp")-1);
-               if(l > sizeof("YYYYMMDD_L")-1
-                   && strcmp (f->d_name + l, ".tmp") == 0) {
+               l = strlen(f->d_name) - (SIZEOF(".tmp")-1);
+               if ((l > (len_date + 1))
+                       && (strcmp(f->d_name + l, ".tmp")==0)) {
                    struct stat sbuf;
-                   char *path;
+                   char *path, *qpath;
 
                    path = stralloc2(indexdir, f->d_name);
+                   qpath = quote_string(path);
                    if(lstat(path, &sbuf) != -1
-                       && (sbuf.st_mode & S_IFMT) == S_IFREG
-                       && sbuf.st_mtime < tmp_time) {
-                       dbprintf(("rm %s\n", path));
+                       && ((sbuf.st_mode & S_IFMT) == S_IFREG)
+                       && ((time_t)sbuf.st_mtime < tmp_time)) {
+                       dbprintf(("rm %s\n", qpath));
                        if(amtrmidx_debug == 0 && unlink(path) == -1) {
-                           dbprintf(("Error removing \"%s\": %s\n",
-                                     path, strerror(errno)));
+                           dbprintf(("Error removing %s: %s\n",
+                                     qpath, strerror(errno)));
                        }
                    }
+                   amfree(qpath);
                    amfree(path);
                    continue;
                }
                if(name_count >= name_length) {
                    char **new_names;
 
-                   new_names = alloc((name_length + 100) * sizeof(char *));
-                   memcpy(new_names, names, name_length * sizeof(char *));
-                   name_length += 100;
+                   new_names = alloc((name_length * 2) * SIZEOF(char *));
+                   memcpy(new_names, names, name_length * SIZEOF(char *));
                    amfree(names);
                    names = new_names;
+                   name_length *= 2;
                }
                names[name_count++] = stralloc(f->d_name);
            }
            closedir(d);
-           qsort(names, name_count, sizeof(char *), sort_by_name_reversed);
+           qsort(names, name_count, SIZEOF(char *), sort_by_name_reversed);
 
            /*
             * Search for the first full dump past the minimum number
             * of index files to keep.
             */
            for(i = 0; i < name_count; i++) {
-               if(!dump_exist(output_find,
-                                        diskp->host->hostname,diskp->name,
-                                        atoi(names[i]),
-                                        names[i][sizeof("YYYYMMDD_L")-1-1] - '0')) {
-                   char *path;
+               char *datestamp;
+               int level;
+               size_t len_date;
+
+               for(len_date = 0; len_date < SIZEOF("YYYYMMDDHHMMSS")-1; len_date++) {
+                    if(! isdigit((int)(names[i][len_date]))) {
+                        break;
+                    }
+                }
+
+               datestamp = stralloc(names[i]);
+               datestamp[len_date] = '\0';
+               level = names[i][len_date+1] - '0';
+               if(!dump_exist(output_find, diskp->host->hostname,
+                               diskp->name, datestamp, level)) {
+                   char *path, *qpath;
                    path = stralloc2(indexdir, names[i]);
-                   dbprintf(("rm %s\n", path));
+                   qpath = quote_string(path);
+                   dbprintf(("rm %s\n", qpath));
                    if(amtrmidx_debug == 0 && unlink(path) == -1) {
-                       dbprintf(("Error removing \"%s\": %s\n",
-                                 path, strerror(errno)));
+                       dbprintf(("Error removing %s: %s\n",
+                                 qpath, strerror(errno)));
                    }
+                   amfree(qpath);
                    amfree(path);
                }
+               amfree(datestamp);
                amfree(names[i]);
            }
            amfree(names);
            amfree(indexdir);
+           amfree(qindexdir);
        }
     }
 
     amfree(conf_indexdir);
     amfree(config_dir);
     free_find_result(&output_find);
+    clear_tapelist();
+    free_disklist(&diskl);
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
 
     dbclose();
 
index f075ca92f99867386740b5af6fa19f3966a81d91..5afef3b0028714cd3b825baa6928ddc5b6213c93 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amtrmlog.c,v 1.10 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amtrmlog.c,v 1.17 2006/07/25 18:27:57 martinea Exp $
  *
  * trims number of index files to only those still in system.  Well
  * actually, it keeps a few extra, plus goes back to the last level 0
 #include "find.h"
 #include "version.h"
 
-int main P((int, char **));
+int amtrmidx_debug = 0;
 
-int main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv);
+
+int
+main(
+    int                argc,
+    char **    argv)
 {
     disklist_t diskl;
     int no_keep;                       /* files per system to keep */
@@ -65,7 +68,9 @@ char **argv;
     char *conf_diskfile;
     char *conf_tapelist;
     char *conf_logdir;
-    int amtrmidx_debug = 0;
+    int dumpcycle;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
     safe_cd();
@@ -75,36 +80,48 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-    if (argc > 1 && strcmp(argv[1], "-t") == 0) {
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if (my_argc > 1 && strcmp(my_argv[1], "-t") == 0) {
        amtrmidx_debug = 1;
-       argc--;
-       argv++;
+       my_argc--;
+       my_argv++;
     }
 
-    if (argc < 2) {
-       fprintf(stderr, "Usage: %s [-t] <config>\n", argv[0]);
+    if (my_argc < 2) {
+       fprintf(stderr, "Usage: %s [-t] <config> [-o configoption]*\n", my_argv[0]);
        return 1;
     }
 
-    dbopen();
-    dbprintf(("%s: version %s\n", argv[0], version()));
+    dbopen(DBG_SUBDIR_SERVER);
+    dbprintf(("%s: version %s\n", my_argv[0], version()));
 
-    config_name = argv[1];
+    config_name = my_argv[1];
 
     config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if (read_conffile(conffile))
+    if (read_conffile(conffile)) {
        error("errors processing amanda config file \"%s\"", conffile);
+       /*NOTREACHED*/
+    }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     conf_diskfile = getconf_str(CNF_DISKFILE);
     if (*conf_diskfile == '/') {
        conf_diskfile = stralloc(conf_diskfile);
     } else {
        conf_diskfile = stralloc2(config_dir, conf_diskfile);
     }
-    if (read_diskfile(conf_diskfile, &diskl) < 0)
+    if (read_diskfile(conf_diskfile, &diskl) < 0) {
        error("could not load disklist \"%s\"", conf_diskfile);
+       /*NOTREACHED*/
+    }
     amfree(conf_diskfile);
 
     conf_tapelist = getconf_str(CNF_TAPELIST);
@@ -113,12 +130,17 @@ char **argv;
     } else {
        conf_tapelist = stralloc2(config_dir, conf_tapelist);
     }
-    if (read_tapelist(conf_tapelist))
+    if (read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
+    }
     amfree(conf_tapelist);
 
     today = time((time_t *)NULL);
-    date_keep = today - (getconf_int(CNF_DUMPCYCLE)*86400);
+    dumpcycle = getconf_int(CNF_DUMPCYCLE);
+    if(dumpcycle > 5000)
+       dumpcycle = 5000;
+    date_keep = today - (dumpcycle * 86400);
 
     output_find_log = find_log();
 
@@ -133,33 +155,46 @@ char **argv;
        conf_logdir = stralloc2(config_dir, conf_logdir);
     }
     olddir = vstralloc(conf_logdir, "/oldlog", NULL);
-    if (mkpdir(olddir, 02700, (uid_t)-1, (gid_t)-1) != 0)
+    if (mkpdir(olddir, 02700, (uid_t)-1, (gid_t)-1) != 0) {
        error("could not create parents of %s: %s", olddir, strerror(errno));
-    if (mkdir(olddir, 02700) != 0 && errno != EEXIST)
+       /*NOTREACHED*/
+    }
+    if (mkdir(olddir, 02700) != 0 && errno != EEXIST) {
        error("could not create %s: %s", olddir, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     if (stat(olddir,&stat_old) == -1) {
        error("can't stat oldlog directory \"%s\": %s", olddir, strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (!S_ISDIR(stat_old.st_mode)) {
        error("Oldlog directory \"%s\" is not a directory", olddir);
+       /*NOTREACHED*/
     }
 
-    if ((dir = opendir(conf_logdir)) == NULL)
+    if ((dir = opendir(conf_logdir)) == NULL) {
        error("could not open log directory \"%s\": %s", conf_logdir,strerror(errno));
+       /*NOTREACHED*/
+    }
     while ((adir=readdir(dir)) != NULL) {
        if(strncmp(adir->d_name,"log.",4)==0) {
            useful=0;
            for (name=output_find_log;*name !=NULL; name++) {
-               if(strncmp(adir->d_name,*name,12)==0) {
+               if((strlen(adir->d_name) >= 13 &&
+                   strlen(*name) >= 13 &&
+                   adir->d_name[12] == '.' && (*name)[12] == '.' &&
+                   strncmp(adir->d_name,*name,12)==0) ||
+                  strncmp(adir->d_name,*name,18)==0) {
                    useful=1;
+                   break;
                }
            }
            logname=newvstralloc(logname,
                                 conf_logdir, "/" ,adir->d_name, NULL);
            if(stat(logname,&stat_log)==0) {
-               if(stat_log.st_mtime > date_keep) {
+               if((time_t)stat_log.st_mtime > date_keep) {
                    useful = 1;
                }
            }
@@ -168,9 +203,11 @@ char **argv;
                                       conf_logdir, "/", adir->d_name, NULL);
                newfile = newvstralloc(newfile,
                                       olddir, "/", adir->d_name, NULL);
-               if (rename(oldfile,newfile) != 0)
+               if (rename(oldfile,newfile) != 0) {
                    error("could not rename \"%s\" to \"%s\": %s",
                          oldfile, newfile, strerror(errno));
+                   /*NOTREACHED*/
+               }
            }
        }
     }
@@ -185,6 +222,10 @@ char **argv;
     amfree(olddir);
     amfree(config_dir);
     amfree(conf_logdir);
+    clear_tapelist();
+    free_disklist(&diskl);
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
 
     dbclose();
 
index 809445131593747b6d1147af25b251694c928ff9..451da620e326402a210325a1c8bc8021def936b8 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#! @SHELL@
 #
-#      $Id: amverify.sh.in,v 1.35 2006/03/16 17:32:32 ktill Exp $
+#      $Id: amverify.sh.in,v 1.38 2006/07/25 19:00:56 martinea Exp $
 #
 # (C) 1996 by ICEM Systems GmbH
 # Author: Axel Zinser (fifi@icem.de)
@@ -64,7 +64,7 @@ report() {
 }
 
 getparm() {
-       $AMGETCONF $CONFIG $1 2>/dev/null | grep -v BUGGY
+       $AMGETCONF $CONFIG $1 2>/dev/null
 }
 
 sendreport() {
index 55735934925a1fac690f25263b87385d4ad74708..eeaebf6b11613617d604789cc7e225b9a75d89e0 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!@SHELL@
 #
 
 prefix=@prefix@
@@ -17,7 +17,7 @@ else
 fi
 
 getparm() {
-        $AMGETCONF $CONFIG $1 2>/dev/null | grep -v BUGGY
+        $AMGETCONF $CONFIG $1 2>/dev/null
 }
 
 CONFIG=$1
index 54bfb8fad41e385f292b4de75cab07cc12bffea6..02519c543aa47ea450ac3dc21c62058ac1987d1c 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: changer.c,v 1.29.2.1 2006/04/24 14:43:01 martinea Exp $
+ * $Id: changer.c,v 1.36 2006/08/24 01:57:16 paddy_s Exp $
  *
  * interface routines for tape changers
  */
@@ -56,16 +56,20 @@ char *changer_resultstr = NULL;
 static char *tapechanger = NULL;
 
 /* local functions */
-static int changer_command P((char *cmd, char *arg));
+static int changer_command(char *cmd, char *arg);
+static int report_bad_resultstr(void);
+static int run_changer_command(char *cmd, char *arg, char **slotstr, char **rest);
 
-int changer_init()
+int
+changer_init(void)
 {
     tapechanger = getconf_str(CNF_TPCHANGER);
     return strcmp(tapechanger, "") != 0;
 }
 
 
-static int report_bad_resultstr()
+static int
+report_bad_resultstr(void)
 {
     char *s;
 
@@ -77,11 +81,12 @@ static int report_bad_resultstr()
     return 2;
 }
 
-static int run_changer_command(cmd, arg, slotstr, rest)
-char *cmd;
-char *arg;
-char **slotstr;
-char **rest;
+static int
+run_changer_command(
+    char *     cmd,
+    char *     arg,
+    char **    slotstr,
+    char **    rest)
 {
     int exitcode;
     char *result_copy;
@@ -90,10 +95,10 @@ char **rest;
     int ch;
 
     if (slotstr) {
-       *slotstr = NULL;
+        *slotstr = NULL;
     }
     if (rest) {
-       *rest = NULL;
+        *rest = NULL;
     }
     exitcode = changer_command(cmd, arg);
     s = changer_resultstr;
@@ -105,13 +110,13 @@ char **rest;
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     if (slotstr) {
-       *slotstr = newstralloc(*slotstr, slot);
+        *slotstr = newstralloc(*slotstr, slot);
     }
-    s[-1] = ch;
+    s[-1] = (char)ch;
 
     skip_whitespace(s, ch);
-    if(rest) {
-       *rest = s - 1;
+    if (rest) {
+        *rest = s - 1;
     }
 
     if(exitcode) {
@@ -124,32 +129,38 @@ char **rest;
     return 0;
 }
 
-int changer_reset(slotstr)
-char **slotstr;
+int
+changer_reset(
+    char **    slotstr)
 {
     char *rest;
 
     return run_changer_command("-reset", (char *) NULL, slotstr, &rest);
 }
 
-int changer_clean(slotstr)
-char **slotstr;
+int
+changer_clean(
+    char **    slotstr)
 {
     char *rest;
 
     return run_changer_command("-clean", (char *) NULL, slotstr, &rest);
 }
 
-int changer_eject(slotstr)
-char **slotstr;
+int
+changer_eject(
+    char **    slotstr)
 {
     char *rest;
 
     return run_changer_command("-eject", (char *) NULL, slotstr, &rest);
 }
 
-int changer_loadslot(inslotstr, outslotstr, devicename)
-char *inslotstr, **outslotstr, **devicename;
+int
+changer_loadslot(
+    char *inslotstr,
+    char **outslotstr,
+    char **devicename)
 {
     char *rest;
     int rc;
@@ -163,17 +174,23 @@ char *inslotstr, **outslotstr, **devicename;
     return 0;
 }
 
-/* This function is somewhat equal to changer_info with one additional
-   parameter, to get information, if the changer is able to search for
-   tapelabels himself. E.g. Barcodereader
-   The changer_script answers with an additional parameter, if it is able
-   to search. This one should be 1, if it is able to search, and 0 if it
-   knows about the extension. If the additional answer is omitted, the
-   changer is not able to search for a tape. 
-*/
-int changer_query(nslotsp, curslotstr, backwardsp, searchable)
-int *nslotsp, *backwardsp, *searchable;
-char **curslotstr;
+
+/*
+ * This function is somewhat equal to changer_info with one additional
+ * parameter, to get information, if the changer is able to search for
+ * tapelabels himself. E.g. Barcodereader
+ * The changer_script answers with an additional parameter, if it is able
+ * to search. This one should be 1, if it is able to search, and 0 if it
+ * knows about the extension. If the additional answer is omitted, the
+ * changer is not able to search for a tape. 
+ */
+
+int
+changer_query(
+    int *      nslotsp,
+    char **    curslotstr,
+    int *      backwardsp,
+    int *      searchable)
 {
     char *rest;
     int rc;
@@ -193,9 +210,11 @@ char **curslotstr;
     return 0;
 }
 
-int changer_info(nslotsp, curslotstr, backwardsp)
-int *nslotsp, *backwardsp;
-char **curslotstr;
+int
+changer_info(
+    int *      nslotsp,
+    char **    curslotstr,
+    int *      backwardsp)
 {
     char *rest;
     int rc;
@@ -212,24 +231,32 @@ char **curslotstr;
 
 /* ---------------------------- */
 
-/* This function first uses searchlabel and changer_search, if
-   the library is able to find a tape itself. If it is not, or if 
-   the tape could not be found, then the normal scan is done.
-   See interface documentation in changer.h.
-*/
-void changer_find(user_data, user_init, user_slot, searchlabel)
-     void *user_data;
-     int (*user_init) P((void *user_data, int rc, int nslots, int backwards,
-                         int searchable));
-     int (*user_slot) P((void *user_data, int rc, char *slotstr,
-                         char *device));
-     char *searchlabel;
+/*
+ * This function first uses searchlabel and changer_search, if
+ * the library is able to find a tape itself. If it is not, or if 
+ * the tape could not be found, then the normal scan is done.
+ *
+ * See interface documentation in changer.h.
+ */
+
+void
+changer_find(
+     void *    user_data,
+     int       (*user_init)(void *, int, int, int, int),
+     int       (*user_slot)(void *, int, char *, char *),
+     char *    searchlabel)
 {
     char *slotstr, *device = NULL, *curslotstr = NULL;
     int nslots, checked, backwards, rc, done, searchable;
 
     rc = changer_query(&nslots, &curslotstr, &backwards, &searchable);
+
+    if (rc != 0) {
+        /* Problem with the changer script. Bail. */
+        fprintf(stderr, "Changer problem: %s\n", changer_resultstr);
+        return;
+    }
+
     done = user_init(user_data, rc, nslots, backwards, searchable);
     amfree(curslotstr);
    
@@ -243,9 +270,9 @@ void changer_find(user_data, user_init, user_slot, searchlabel)
     }
 
     if ((searchlabel!=NULL) && searchable && !done){
-      rc=changer_search(searchlabel,&curslotstr,&device);
+      rc=changer_search(searchlabel, &curslotstr, &device);
       if(rc == 0)
-        done = user_slot(user_data, rc,curslotstr,device);
+        done = user_slot(user_data, rc, curslotstr, device);
     }
  
     slotstr = "current";
@@ -267,10 +294,11 @@ void changer_find(user_data, user_init, user_slot, searchlabel)
 
 /* ---------------------------- */
 
-void changer_current(user_data, user_init, user_slot)
-     void *user_data;
-int (*user_init) P((void *ud, int rc, int nslots, int backwards, int searchable));
-int (*user_slot) P((void *ud, int rc, char *slotstr, char *device));
+void
+changer_current(
+    void *     user_data,
+    int                (*user_init)(void *, int, int, int, int),
+    int                (*user_slot)(void *, int, char *, char *))
 {
     char *device = NULL, *curslotstr = NULL;
     int nslots, backwards, rc, done, searchable;
@@ -291,12 +319,13 @@ int (*user_slot) P((void *ud, int rc, char *slotstr, char *device));
 
 /* ---------------------------- */
 
-static int changer_command(cmd, arg)
-     char *cmd;
-     char *arg;
+static int
+changer_command(
+     char *cmd,
+     char *arg)
 {
     int fd[2];
-    amwait_t wait_exitcode;
+    amwait_t wait_exitcode = 1;
     int exitcode;
     char num1[NUM_STR_SIZE];
     char num2[NUM_STR_SIZE];
@@ -330,9 +359,17 @@ static int changer_command(cmd, arg)
        exitcode = 2;
        goto failed;
     }
-    if(fd[0] < 0 || fd[0] >= FD_SETSIZE) {
-       snprintf(num1, sizeof(num1), "%d", fd[0]);
-       snprintf(num2, sizeof(num2), "%d", FD_SETSIZE-1);
+
+    /* make sure fd[0] != 1 */
+    if(fd[0] == 1) {
+       int a = dup(fd[0]);
+       close(fd[0]);
+       fd[0] = a;
+    }
+
+    if(fd[0] < 0 || fd[0] >= (int)FD_SETSIZE) {
+       snprintf(num1, SIZEOF(num1), "%d", fd[0]);
+       snprintf(num2, SIZEOF(num2), "%d", FD_SETSIZE-1);
        changer_resultstr = vstralloc ("<error> ",
                                       "could not create pipe for \"",
                                       cmdstr,
@@ -346,9 +383,9 @@ static int changer_command(cmd, arg)
        exitcode = 2;
        goto done;
     }
-    if(fd[1] < 0 || fd[1] >= FD_SETSIZE) {
-       snprintf(num1, sizeof(num1), "%d", fd[1]);
-       snprintf(num2, sizeof(num2), "%d", FD_SETSIZE-1);
+    if(fd[1] < 0 || fd[1] >= (int)FD_SETSIZE) {
+       snprintf(num1, SIZEOF(num1), "%d", fd[1]);
+       snprintf(num2, SIZEOF(num2), "%d", FD_SETSIZE-1);
        changer_resultstr = vstralloc ("<error> ",
                                       "could not create pipe for \"",
                                       cmdstr,
@@ -397,9 +434,10 @@ static int changer_command(cmd, arg)
            exit(1);
        }
        if(arg) {
-           execle(tapechanger, tapechanger, cmd, arg, NULL, safe_env());
+           execle(tapechanger, tapechanger, cmd, arg, (char *)NULL,
+                  safe_env());
        } else {
-           execle(tapechanger, tapechanger, cmd, NULL, safe_env());
+           execle(tapechanger, tapechanger, cmd, (char *)NULL, safe_env());
        }
        changer_resultstr = vstralloc ("<error> ",
                                       "could not exec \"",
@@ -437,7 +475,7 @@ static int changer_command(cmd, arg)
                goto done;
            }
        } else if (pid != changer_pid) {
-           snprintf(num1, sizeof(num1), "%ld", (long)pid);
+           snprintf(num1, SIZEOF(num1), "%ld", (long)pid);
            changer_resultstr = vstralloc ("<error> ",
                                           "wait for \"",
                                           tapechanger,
@@ -453,7 +491,7 @@ static int changer_command(cmd, arg)
 
     /* mark out-of-control changers as fatal error */
     if(WIFSIGNALED(wait_exitcode)) {
-       snprintf(num1, sizeof(num1), "%d", WTERMSIG(wait_exitcode));
+       snprintf(num1, SIZEOF(num1), "%d", WTERMSIG(wait_exitcode));
        changer_resultstr = newvstralloc (changer_resultstr,
                                          "<error> ",
                                          changer_resultstr,
@@ -469,19 +507,27 @@ done:
     aclose(fd[1]);
 
 failed:
-    dbprintf(("changer: got exit: %d str: %s\n", exitcode, changer_resultstr)); 
+    if (exitcode != 0) {
+        dbprintf(("changer: got exit: %d str: %s\n", exitcode, changer_resultstr)); 
+    }
 
     amfree(cmdstr);
 
     return exitcode;
 }
 
-/* This function commands the changerscript to look for a tape named
-   searchlabel. If is found, the changerscript answers with the device,
-   in which the tape can be accessed.
-*/
-int changer_search(searchlabel, outslotstr, devicename)
-char *searchlabel, **outslotstr, **devicename;
+
+/*
+ * This function commands the changerscript to look for a tape named
+ * searchlabel. If is found, the changerscript answers with the device,
+ * in which the tape can be accessed.
+ */
+
+int
+changer_search(
+    char *     searchlabel,
+    char **    outslotstr,
+    char **    devicename)
 {
     char *rest;
     int rc;
@@ -496,15 +542,19 @@ char *searchlabel, **outslotstr, **devicename;
     return 0;
 }
 
-/* Because barcodelabel are short, and may not be the same as the 
-   amandalabels, the changerscript should be informed, which tapelabel
-   is associated with a tape. This function should be called after 
-   giving a label for a tape. (Maybe also, when the label and the associated
-   slot is known. e.g. during library scan.
-*/
-int changer_label (slotsp,labelstr)
-char *slotsp; 
-char *labelstr;
+
+/*
+ * Because barcodelabel are short, and may not be the same as the 
+ * amandalabels, the changerscript should be informed, which tapelabel
+ * is associated with a tape. This function should be called after 
+ * giving a label for a tape. (Maybe also, when the label and the associated
+ * slot is known. e.g. during library scan.
+ */
+
+int
+changer_label(
+    char *     slotsp, 
+    char *     labelstr)
 {
     int rc;
     char *rest=NULL;
index 19734080b84abaf0adca71b3d1cd68ebd78015ef..ba5b73aa010642943071dbb6e01e9281a53e50ef 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: changer.h,v 1.12 2005/12/21 19:07:50 paddy_s Exp $
+ * $Id: changer.h,v 1.13 2006/05/25 01:47:19 johnfranks Exp $
  *
  * interface routines for tape changers
  */
+#ifndef CHANGER_H
+#define CHANGER_H
+
 #include "amanda.h"
 
 extern int changer_debug;
 extern char *changer_resultstr;
 
-int changer_init P((void));
-int changer_reset P((char **slotstr));
-int changer_clean P((char **slotstr));
-int changer_eject P((char **slotstr));
-int changer_label P((char *slotsp, char *labelstr));
-int changer_info P((int *nslotsp, char **curslotstr, int *backwards));
-int changer_query P((int *nslotsp, char **curslotstr, int *backwards,
-                    int *searchable));
-int changer_search P((char *searchlabel, char **outslotstr, char **devicename));
-int changer_loadslot P((char *inslotstr, char **outslotstr, char **devicename));
-void changer_current P((void *user_data,
+int changer_init(void);
+int changer_reset(char **slotstr);
+int changer_clean(char **slotstr);
+int changer_eject(char **slotstr);
+int changer_label(char *slotsp, char *labelstr);
+int changer_info(int *nslotsp, char **curslotstr, int *backwards);
+int changer_query(int *nslotsp, char **curslotstr, int *backwards,
+                    int *searchable);
+int changer_search(char *searchlabel, char **outslotstr, char **devicename);
+int changer_loadslot(char *inslotstr, char **outslotstr, char **devicename);
+void changer_current(void *user_data,
                         int (*user_init)(void *user_data,
                                          int rc, int nslots, int backwards,
                                          int searchable),
                     int (*user_slot)(void *user_data,
-                                      int rc, char *slotstr, char *device)));
+                                      int rc, char *slotstr, char *device));
 
 
 /* USAGE: changer_find(user_data, init_fxn, slot_fxn, searchlabel)
@@ -88,10 +91,12 @@ void changer_current P((void *user_data,
 
 
 
-void changer_find P((void *user_data,
+void changer_find(void *user_data,
                      int (*user_init)(void *user_data, int rc,
                                       int nslots, int backwards,
                                       int searchable),
                     int (*user_slot)(void *user_data, int rc,
                                       char *slotstr, char *device),
-                     char *searchlabel));
+                     char *searchlabel);
+
+#endif /* !CHANGER_H */
index e9e5392af061620ceeaaec02b00ca3926af3d323..8d89fd74d08da3e70c9735e9d13d4c5b85e80aaa 100644 (file)
@@ -23,7 +23,7 @@
  * Authors: the Amanda Development Team.  Its members are listed in a
  * file named AUTHORS, in the root directory of this distribution.
  */
-/* $Id: chunker.c,v 1.25.2.1 2006/04/23 18:52:04 martinea Exp $
+/* $Id: chunker.c,v 1.36 2006/08/24 11:23:32 martinea Exp $
  *
  * requests remote amandad processes to dump filesystems
  */
@@ -61,9 +61,9 @@ struct databuf {
     int fd;                    /* file to flush to */
     char *filename;            /* name of what fd points to */
     int filename_seq;          /* for chunking */
-    long split_size;           /* when to chunk */
-    long chunk_size;           /* size of each chunk */
-    long use;                  /* size to use on this disk */
+    off_t split_size;          /* when to chunk */
+    off_t chunk_size;          /* size of each chunk */
+    off_t use;                 /* size to use on this disk */
     char buf[DISK_BLOCK_BYTES];
     char *datain;              /* data buffer markers */
     char *dataout;
@@ -74,35 +74,37 @@ static char *handle = NULL;
 
 static char *errstr = NULL;
 static int abort_pending;
-static long dumpsize, headersize;
-static long dumpbytes;
-static long filesize;
+static off_t dumpsize;
+static unsigned long headersize;
+static off_t dumpbytes;
+static off_t filesize;
 
 static char *hostname = NULL;
 static char *diskname = NULL;
+static char *qdiskname = NULL;
 static char *options = NULL;
 static char *progname = NULL;
 static int level;
 static char *dumpdate = NULL;
-static char *datestamp = NULL;
 static int command_in_transit;
+static char *chunker_timestamp = NULL;
 
 static dumpfile_t file;
 
 /* local functions */
-int main P((int, char **));
-static int write_tapeheader P((int, dumpfile_t *));
-static void databuf_init P((struct databuf *, int, char *, long, long));
-static int databuf_flush P((struct databuf *));
+int main(int, char **);
+static ssize_t write_tapeheader(int, dumpfile_t *);
+static void databuf_init(struct databuf *, int, char *, off_t, off_t);
+static int databuf_flush(struct databuf *);
 
-static int startup_chunker P((char *, long, long, struct databuf *));
-static int do_chunk P((int, struct databuf *));
+static int startup_chunker(char *, off_t, off_t, struct databuf *);
+static int do_chunk(int, struct databuf *);
 
 
 int
-main(main_argc, main_argv)
-    int main_argc;
-    char **main_argv;
+main(
+    int                main_argc,
+    char **    main_argv)
 {
     static struct databuf db;
     struct cmdargs cmdargs;
@@ -112,16 +114,21 @@ main(main_argc, main_argv)
     unsigned long malloc_hist_2, malloc_size_2;
     char *conffile;
     char *q = NULL;
-    char *filename;
-    long chunksize, use;
+    char *filename = NULL;
+    char *qfilename = NULL;
+    off_t chunksize, use;
     times_t runtime;
     am_feature_t *their_features = NULL;
     int a;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
 
     set_pname("chunker");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -130,14 +137,19 @@ main(main_argc, main_argv)
     erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
     set_logerror(logerror);
 
-    if (main_argc > 1) {
-       config_name = stralloc(main_argv[1]);
+    parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if (my_argc > 1) {
+       config_name = stralloc(my_argv[1]);
        config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     } else {
        char my_cwd[STR_SIZE];
 
-       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
            error("cannot determine current working directory");
+           /*NOTREACHED*/
        }
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
@@ -150,19 +162,26 @@ main(main_argc, main_argv)
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if(read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     fprintf(stderr,
            "%s: pid %ld executable %s version %s\n",
            get_pname(), (long) getpid(),
-           main_argv[0], version());
+           my_argv[0], version());
     fflush(stderr);
 
     /* now, make sure we are a valid user */
 
-    if (getpwuid(getuid()) == NULL)
+    if (getpwuid(getuid()) == NULL) {
        error("can't get login name for my uid %ld", (long)getuid());
+       /*NOTREACHED*/
+    }
 
     signal(SIGPIPE, SIG_IGN);
     signal(SIGCHLD, SIG_IGN);
@@ -170,8 +189,8 @@ main(main_argc, main_argv)
     cmd = getcmd(&cmdargs);
     if(cmd == START) {
        if(cmdargs.argc <= 1)
-           error("error [dumper START: not enough args: datestamp]");
-       datestamp = newstralloc(datestamp, cmdargs.argv[2]);
+           error("error [dumper START: not enough args: timestamp]");
+       chunker_timestamp = newstralloc(chunker_timestamp, cmdargs.argv[2]);
     }
     else {
        error("Didn't get START command");
@@ -204,64 +223,83 @@ main(main_argc, main_argv)
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: handle]");
+               /*NOTREACHED*/
            }
            handle = newstralloc(handle, cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: filename]");
+               /*NOTREACHED*/
            }
-           filename = cmdargs.argv[a++];
+           qfilename = newstralloc(qfilename, cmdargs.argv[a++]);
+           if (filename != NULL)
+               amfree(filename);
+           filename = unquote_string(qfilename);
+           amfree(qfilename);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: hostname]");
+               /*NOTREACHED*/
            }
            hostname = newstralloc(hostname, cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: features]");
+               /*NOTREACHED*/
            }
            am_release_feature_set(their_features);
            their_features = am_string_to_feature(cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: diskname]");
+               /*NOTREACHED*/
            }
-           diskname = newstralloc(diskname, cmdargs.argv[a++]);
+           qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]);
+           if (diskname != NULL)
+               amfree(diskname);
+           diskname = unquote_string(qdiskname);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: level]");
+               /*NOTREACHED*/
            }
            level = atoi(cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: dumpdate]");
+               /*NOTREACHED*/
            }
            dumpdate = newstralloc(dumpdate, cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: chunksize]");
+               /*NOTREACHED*/
            }
-           chunksize = atoi(cmdargs.argv[a++]);
-           chunksize = am_floor(chunksize, DISK_BLOCK_KB);
+           chunksize = OFF_T_ATOI(cmdargs.argv[a++]);
+           chunksize = am_floor(chunksize, (off_t)DISK_BLOCK_KB);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: progname]");
+               /*NOTREACHED*/
            }
            progname = newstralloc(progname, cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: use]");
+               /*NOTREACHED*/
            }
-           use = am_floor(atoi(cmdargs.argv[a++]), DISK_BLOCK_KB);
+           use = am_floor(OFF_T_ATOI(cmdargs.argv[a++]), DISK_BLOCK_KB);
 
            if(a >= cmdargs.argc) {
                error("error [chunker PORT-WRITE: not enough args: options]");
+               /*NOTREACHED*/
            }
            options = newstralloc(options, cmdargs.argv[a++]);
 
            if(a != cmdargs.argc) {
                error("error [chunker PORT-WRITE: too many args: %d != %d]",
                      cmdargs.argc, a);
+               /*NOTREACHED*/
            }
 
            if((infd = startup_chunker(filename, use, chunksize, &db)) < 0) {
@@ -276,10 +314,12 @@ main(main_argc, main_argv)
                double rt;
 
                runtime = stopclock();
-               rt = runtime.r.tv_sec+runtime.r.tv_usec/1000000.0;
-               snprintf(kb_str, sizeof(kb_str), "%ld", dumpsize - headersize);
-               snprintf(kps_str, sizeof(kps_str), "%3.1f",
-                               rt ? dumpsize / rt : 0.0);
+               rt = (double)(runtime.r.tv_sec) +
+                    ((double)(runtime.r.tv_usec) / 1000000.0);
+               snprintf(kb_str, SIZEOF(kb_str), OFF_T_FMT,
+                        (OFF_T_FMT_TYPE)(dumpsize - (off_t)headersize));
+               snprintf(kps_str, SIZEOF(kps_str), "%3.1lf",
+                               isnormal(rt) ? (double)dumpsize / rt : 0.0);
                errstr = newvstralloc(errstr,
                                      "sec ", walltime_str(runtime),
                                      " kb ", kb_str,
@@ -292,20 +332,21 @@ main(main_argc, main_argv)
                    cmd = getcmd(&cmdargs);
                switch(cmd) {
                case DONE:
-                   putresult(DONE, "%s %ld %s\n",
-                             handle, dumpsize - headersize, q);
+                   putresult(DONE, "%s " OFF_T_FMT " %s\n", handle,
+                            (OFF_T_FMT_TYPE)(dumpsize - (off_t)headersize), q);
                    log_add(L_SUCCESS, "%s %s %s %d [%s]",
-                           hostname, diskname, datestamp, level, errstr);
+                           hostname, qdiskname, chunker_timestamp, level, errstr);
                    break;
                case BOGUS:
                case TRYAGAIN:
                case FAILED:
                case ABORT_FINISHED:
-                   if(dumpsize > DISK_BLOCK_KB) {
-                       putresult(PARTIAL, "%s %ld %s\n",
-                                 handle, dumpsize - headersize, q);
+                   if(dumpsize > (off_t)DISK_BLOCK_KB) {
+                       putresult(PARTIAL, "%s " OFF_T_FMT " %s\n", handle,
+                                (OFF_T_FMT_TYPE)(dumpsize - (off_t)headersize),
+                                q);
                        log_add(L_PARTIAL, "%s %s %s %d [%s]",
-                               hostname, diskname, datestamp, level, errstr);
+                               hostname, qdiskname, chunker_timestamp, level, errstr);
                    }
                    else {
                        errstr = newvstralloc(errstr,
@@ -316,7 +357,7 @@ main(main_argc, main_argv)
                        q = squotef("[%s]",errstr);
                        putresult(FAILED, "%s %s\n", handle, q);
                        log_add(L_FAIL, "%s %s %s %d [%s]",
-                               hostname, diskname, datestamp, level, errstr);
+                               hostname, qdiskname, chunker_timestamp, level, errstr);
                    }
                default: break;
                }
@@ -328,10 +369,12 @@ main(main_argc, main_argv)
                    }
                    putresult(FAILED, "%s %s\n", handle, q);
                    log_add(L_FAIL, "%s %s %s %d [%s]",
-                           hostname, diskname, datestamp, level, errstr);
+                           hostname, qdiskname, chunker_timestamp, level, errstr);
                    amfree(q);
                }
            }
+           amfree(filename);
+           amfree(db.filename);
            break;
 
        default:
@@ -349,11 +392,14 @@ main(main_argc, main_argv)
 
 /*    } while(cmd != QUIT); */
 
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
     amfree(errstr);
-    amfree(datestamp);
+    amfree(chunker_timestamp);
     amfree(handle);
     amfree(hostname);
     amfree(diskname);
+    amfree(qdiskname);
     amfree(dumpdate);
     amfree(progname);
     amfree(options);
@@ -367,7 +413,9 @@ main(main_argc, main_argv)
     if (malloc_size_1 != malloc_size_2)
        malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
 
-    exit(0);
+    dbclose();
+
+    return (0); /* exit */
 }
 
 /*
@@ -375,18 +423,19 @@ main(main_argc, main_argv)
  * on success, or -1 on error.
  */
 static int
-startup_chunker(filename, use, chunksize, db)
-    char *filename;
-    long use;
-    long chunksize;
-    struct databuf *db;
+startup_chunker(
+    char *             filename,
+    off_t              use,
+    off_t              chunksize,
+    struct databuf *   db)
 {
     int infd, outfd;
     char *tmp_filename, *pc;
-    int data_port, data_socket;
+    in_port_t data_port;
+    int data_socket;
 
     data_port = 0;
-    data_socket = stream_server(&data_port, -1, STREAM_BUFSIZE);
+    data_socket = stream_server(&data_port, 0, STREAM_BUFSIZE, 0);
 
     if(data_socket < 0) {
        errstr = stralloc2("error creating stream server: ", strerror(errno));
@@ -395,7 +444,7 @@ startup_chunker(filename, use, chunksize, db)
 
     putresult(PORT, "%d\n", data_port);
 
-    infd = stream_accept(data_socket, CONNECT_TIMEOUT, -1, NETWORK_BLOCK_BYTES);
+    infd = stream_accept(data_socket, CONNECT_TIMEOUT, 0, STREAM_BUFSIZE);
     if(infd == -1) {
        errstr = stralloc2("error accepting stream: ", strerror(errno));
        return -1;
@@ -415,7 +464,8 @@ startup_chunker(filename, use, chunksize, db)
        amfree(tmp_filename);
        aclose(infd);
        if(save_errno == ENOSPC) {
-           putresult(NO_ROOM, "%s %lu", handle, use);
+           putresult(NO_ROOM, "%s " OFF_T_FMT "\n",
+                     handle, (OFF_T_FMT_TYPE)use);
            return -2;
        } else {
            return -1;
@@ -428,23 +478,25 @@ startup_chunker(filename, use, chunksize, db)
 }
 
 static int
-do_chunk(infd, db)
-    int infd;
-    struct databuf *db;
+do_chunk(
+    int                        infd,
+    struct databuf *   db)
 {
-    int nread;
+    ssize_t nread;
     char header_buf[DISK_BLOCK_BYTES];
 
     startclock();
 
-    dumpsize = headersize = dumpbytes = filesize = 0;
+    dumpsize = dumpbytes = filesize = (off_t)0;
+    headersize = 0;
+    memset(header_buf, 0, sizeof(header_buf));
 
     /*
      * The first thing we should receive is the file header, which we
      * need to save into "file", as well as write out.  Later, the
      * chunk code will rewrite it.
      */
-    nread = fullread(infd, header_buf, sizeof(header_buf));
+    nread = fullread(infd, header_buf, SIZEOF(header_buf));
     if (nread != DISK_BLOCK_BYTES) {
        char number1[NUM_STR_SIZE];
        char number2[NUM_STR_SIZE];
@@ -452,8 +504,9 @@ do_chunk(infd, db)
        if(nread < 0) {
            errstr = stralloc2("cannot read header: ", strerror(errno));
        } else {
-           snprintf(number1, sizeof(number1), "%d", nread);
-           snprintf(number2, sizeof(number2), "%d", DISK_BLOCK_BYTES);
+           snprintf(number1, SIZEOF(number1), SSIZE_T_FMT,
+                       (SSIZE_T_FMT_TYPE)nread);
+           snprintf(number2, SIZEOF(number2), "%d", DISK_BLOCK_BYTES);
            errstr = vstralloc("cannot read header: got ",
                               number1,
                               " instead of ",
@@ -462,27 +515,28 @@ do_chunk(infd, db)
        }
        return 0;
     }
-    parse_file_header(header_buf, &file, nread);
+    parse_file_header(header_buf, &file, (size_t)nread);
     if(write_tapeheader(db->fd, &file)) {
        int save_errno = errno;
 
-       errstr = squotef("write_tapeheader file \"%s\": %s",
+       errstr = squotef("write_tapeheader file %s: %s",
                         db->filename, strerror(errno));
        if(save_errno == ENOSPC) {
-           putresult(NO_ROOM, "%s %lu\n", handle, 
-                     db->use+db->split_size-dumpsize);
+           putresult(NO_ROOM, "%s " OFF_T_FMT "\n", handle, 
+                     (OFF_T_FMT_TYPE)(db->use+db->split_size-dumpsize));
        }
        return 0;
     }
-    dumpsize += DISK_BLOCK_KB;
-    filesize = DISK_BLOCK_KB;
+    dumpsize += (off_t)DISK_BLOCK_KB;
+    filesize = (off_t)DISK_BLOCK_KB;
     headersize += DISK_BLOCK_KB;
 
     /*
      * We've written the file header.  Now, just write data until the
      * end.
      */
-    while ((nread = fullread(infd, db->buf, db->datalimit - db->datain)) > 0) {
+    while ((nread = fullread(infd, db->buf,
+                            (size_t)(db->datalimit - db->datain))) > 0) {
        db->datain += nread;
        while(db->dataout < db->datain) {
            if(!databuf_flush(db)) {
@@ -495,9 +549,9 @@ do_chunk(infd, db)
            return 0;
        }
     }
-    if(dumpbytes > 0) {
-       dumpsize++;                     /* count partial final KByte */
-       filesize++;
+    if(dumpbytes > (off_t)0) {
+       dumpsize += (off_t)1;                   /* count partial final KByte */
+       filesize += (off_t)1;
     }
     return 1;
 }
@@ -506,21 +560,21 @@ do_chunk(infd, db)
  * Initialize a databuf.  Takes a writeable file descriptor.
  */
 static void
-databuf_init(db, fd, filename, use, chunk_size)
-    struct databuf *db;
-    int fd;
-    char *filename;
-    long use;
-    long chunk_size;
+databuf_init(
+    struct databuf *   db,
+    int                        fd,
+    char *             filename,
+    off_t              use,
+    off_t              chunk_size)
 {
     db->fd = fd;
     db->filename = stralloc(filename);
-    db->filename_seq = 0;
+    db->filename_seq = (off_t)0;
     db->chunk_size = chunk_size;
     db->split_size = (db->chunk_size > use) ? use : db->chunk_size;
-    db->use = (use>db->split_size) ? use - db->split_size : 0;
+    db->use = (use > db->split_size) ? use - db->split_size : (off_t)0;
     db->datain = db->dataout = db->buf;
-    db->datalimit = db->buf + sizeof(db->buf);
+    db->datalimit = db->buf + SIZEOF(db->buf);
 }
 
 
@@ -528,14 +582,15 @@ databuf_init(db, fd, filename, use, chunk_size)
  * Write out the buffer to the backing file
  */
 static int
-databuf_flush(db)
-    struct databuf *db;
+databuf_flush(
+    struct databuf *   db)
 {
     struct cmdargs cmdargs;
     int rc = 1;
-    int written;
-    long left_in_chunk;
+    ssize_t written;
+    off_t left_in_chunk;
     char *arg_filename = NULL;
+    char *qarg_filename = NULL;
     char *new_filename = NULL;
     char *tmp_filename = NULL;
     char sequence[NUM_STR_SIZE];
@@ -555,8 +610,8 @@ databuf_flush(db)
     /*
      * See if we need to split this file.
      */
-    while (db->split_size > 0 && dumpsize >= db->split_size) {
-       if( db->use == 0 ) {
+    while (db->split_size > (off_t)0 && dumpsize >= db->split_size) {
+       if( db->use == (off_t)0 ) {
            /*
             * Probably no more space on this disk.  Request some more.
             */
@@ -582,23 +637,30 @@ databuf_flush(db)
 
                if(a >= cmdargs.argc) {
                    error("error [chunker CONTINUE: not enough args: filename]");
+                   /*NOTREACHED*/
                }
-               arg_filename = newstralloc(arg_filename, cmdargs.argv[a++]);
+               qarg_filename = newstralloc(qarg_filename, cmdargs.argv[a++]);
+               if (arg_filename != NULL)
+                   amfree(arg_filename);
+               arg_filename = unquote_string(qarg_filename);
 
                if(a >= cmdargs.argc) {
                    error("error [chunker CONTINUE: not enough args: chunksize]");
+                   /*NOTREACHED*/
                }
-               db->chunk_size = atoi(cmdargs.argv[a++]);
-               db->chunk_size = am_floor(db->chunk_size, DISK_BLOCK_KB);
+               db->chunk_size = OFF_T_ATOI(cmdargs.argv[a++]);
+               db->chunk_size = am_floor(db->chunk_size, (off_t)DISK_BLOCK_KB);
 
                if(a >= cmdargs.argc) {
                    error("error [chunker CONTINUE: not enough args: use]");
+                   /*NOTREACHED*/
                }
-               db->use = atoi(cmdargs.argv[a++]);
+               db->use = OFF_T_ATOI(cmdargs.argv[a++]);
 
                if(a != cmdargs.argc) {
                    error("error [chunker CONTINUE: too many args: %d != %d]",
                          cmdargs.argc, a);
+                   /*NOTREACHED*/
                }
 
                if(strcmp(db->filename, arg_filename) == 0) {
@@ -610,12 +672,12 @@ databuf_flush(db)
                    left_in_chunk = db->chunk_size - filesize;
                    if(left_in_chunk > db->use) {
                        db->split_size += db->use;
-                       db->use = 0;
+                       db->use = (off_t)0;
                    } else {
                        db->split_size += left_in_chunk;
                        db->use -= left_in_chunk;
                    }
-                   if(left_in_chunk > 0) {
+                   if(left_in_chunk > (off_t)0) {
                        /*
                         * We still have space in this chunk.
                         */
@@ -642,6 +704,7 @@ databuf_flush(db)
                    q = stralloc("(no input?)");
                }
                error("error [bad command after RQ-MORE-DISK: \"%s\"]", q);
+               /*NOTREACHED*/
            }
        }
 
@@ -653,7 +716,7 @@ databuf_flush(db)
         * First, open the new chunk file, and give it a new header
         * that has no cont_filename pointer.
         */
-       snprintf(sequence, sizeof(sequence), "%d", db->filename_seq);
+       snprintf(sequence, SIZEOF(sequence), "%d", db->filename_seq);
        new_filename = newvstralloc(new_filename,
                                    db->filename,
                                    ".",
@@ -672,10 +735,9 @@ databuf_flush(db)
            int save_errno = errno;
 
            if(save_errno == ENOSPC) {
-               putresult(NO_ROOM, "%s %lu\n",
-                         handle, 
-                         db->use+db->split_size-dumpsize);
-               db->use = 0;                    /* force RQ_MORE_DISK */
+               putresult(NO_ROOM, "%s " OFF_T_FMT "\n", handle, 
+                         (OFF_T_FMT_TYPE)(db->use+db->split_size-dumpsize));
+               db->use = (off_t)0;                     /* force RQ_MORE_DISK */
                db->split_size = dumpsize;
                continue;
            }
@@ -694,14 +756,13 @@ databuf_flush(db)
 
            aclose(newfd);
            if(save_errno == ENOSPC) {
-               putresult(NO_ROOM, "%s %lu\n",
-                         handle, 
-                         db->use+db->split_size-dumpsize);
-               db->use = 0;                    /* force RQ_MORE DISK */
+               putresult(NO_ROOM, "%s " OFF_T_FMT "\n", handle, 
+                         (OFF_T_FMT_TYPE)(db->use+db->split_size-dumpsize));
+               db->use = (off_t)0;                     /* force RQ_MORE DISK */
                db->split_size = dumpsize;
                continue;
            }
-           errstr = squotef("write_tapeheader file \"%s\": %s",
+           errstr = squotef("write_tapeheader file %s: %s",
                             tmp_filename,
                             strerror(errno));
            rc = 0;
@@ -712,8 +773,8 @@ databuf_flush(db)
         * Now, update the header of the current file to point
         * to the next chunk, and then close it.
         */
-       if (lseek(db->fd, (off_t)0, SEEK_SET) < 0) {
-           errstr = squotef("lseek holding file \"%s\": %s",
+       if (lseek(db->fd, (off_t)0, SEEK_SET) < (off_t)0) {
+           errstr = squotef("lseek holding file %s: %s",
                             db->filename,
                             strerror(errno));
            aclose(newfd);
@@ -722,8 +783,8 @@ databuf_flush(db)
        }
 
        file.type = save_type;
-       strncpy(file.cont_filename, new_filename, sizeof(file.cont_filename));
-       file.cont_filename[sizeof(file.cont_filename)] = '\0';
+       strncpy(file.cont_filename, new_filename, SIZEOF(file.cont_filename));
+       file.cont_filename[SIZEOF(file.cont_filename)] = '\0';
        if(write_tapeheader(db->fd, &file)) {
            errstr = squotef("write_tapeheader file \"%s\": %s",
                             db->filename,
@@ -745,16 +806,16 @@ databuf_flush(db)
        /*
         * Update when we need to chunk again
         */
-       if(db->use <= DISK_BLOCK_KB) {
+       if(db->use <= (off_t)DISK_BLOCK_KB) {
            /*
             * Cheat and use one more block than allowed so we can make
             * some progress.
             */
-           db->split_size += 2 * DISK_BLOCK_KB;
-           db->use = 0;
+           db->split_size += (off_t)(2 * DISK_BLOCK_KB);
+           db->use = (off_t)0;
        } else if(db->chunk_size > db->use) {
            db->split_size += db->use;
-           db->use = 0;
+           db->use = (off_t)0;
        } else {
            db->split_size += db->chunk_size;
            db->use -= db->chunk_size;
@@ -763,8 +824,8 @@ databuf_flush(db)
 
        amfree(tmp_filename);
        amfree(new_filename);
-       dumpsize += DISK_BLOCK_KB;
-       filesize = DISK_BLOCK_KB;
+       dumpsize += (off_t)DISK_BLOCK_KB;
+       filesize = (off_t)DISK_BLOCK_KB;
        headersize += DISK_BLOCK_KB;
        db->filename_seq++;
     }
@@ -772,13 +833,14 @@ databuf_flush(db)
     /*
      * Write out the buffer
      */
-    written = fullwrite(db->fd, db->dataout, db->datain - db->dataout);
+    written = fullwrite(db->fd, db->dataout,
+                       (size_t)(db->datain - db->dataout));
     if (written > 0) {
        db->dataout += written;
-       dumpbytes += written;
+       dumpbytes += (off_t)written;
     }
-    dumpsize += (dumpbytes / 1024);
-    filesize += (dumpbytes / 1024);
+    dumpsize += (dumpbytes / (off_t)1024);
+    filesize += (dumpbytes / (off_t)1024);
     dumpbytes %= 1024;
     if (written < 0) {
        if (errno != ENOSPC) {
@@ -791,8 +853,9 @@ databuf_flush(db)
         * NO-ROOM is informational only.  Later, RQ_MORE_DISK will be
         * issued to use another holding disk.
         */
-       putresult(NO_ROOM, "%s %lu\n", handle, db->use+db->split_size-dumpsize);
-       db->use = 0;                            /* force RQ_MORE_DISK */
+       putresult(NO_ROOM, "%s " OFF_T_FMT "\n", handle,
+                 (OFF_T_FMT_TYPE)(db->use+db->split_size-dumpsize));
+       db->use = (off_t)0;                             /* force RQ_MORE_DISK */
        db->split_size = dumpsize;
        goto common_exit;
     }
@@ -806,8 +869,9 @@ databuf_flush(db)
 common_exit:
 
     amfree(new_filename);
-    amfree(tmp_filename);
+    /*@i@*/ amfree(tmp_filename);
     amfree(arg_filename);
+    amfree(qarg_filename);
     return rc;
 }
 
@@ -815,20 +879,24 @@ common_exit:
 /*
  * Send an Amanda dump header to the output file.
  */
-static int
-write_tapeheader(outfd, file)
-    int outfd;
-    dumpfile_t *file;
+static ssize_t
+write_tapeheader(
+    int                outfd,
+    dumpfile_t *file)
 {
     char buffer[DISK_BLOCK_BYTES];
-    int written;
+    ssize_t written;
 
     file->blocksize = DISK_BLOCK_BYTES;
-    build_header(buffer, file, sizeof(buffer));
+    build_header(buffer, file, SIZEOF(buffer));
+
+    written = fullwrite(outfd, buffer, SIZEOF(buffer));
+    if(written == (ssize_t)sizeof(buffer))
+       return 0;
+
+    if(written < 0)
+       return written;
 
-    written = fullwrite(outfd, buffer, sizeof(buffer));
-    if(written == sizeof(buffer)) return 0;
-    if(written < 0) return written;
     errno = ENOSPC;
-    return -1;
+    return (ssize_t)-1;
 }
index f80137263e7113ce14f64f53eeacce33b2efb846..502287d05ceec8a9f9f156b1e971a5089446b662 100644 (file)
  *                        University of Maryland at College Park
  */
 /*
- * $Id: conffile.c,v 1.127 2006/03/15 16:26:13 martinea Exp $
+ * $Id: conffile.c,v 1.156 2006/07/26 15:17:37 martinea Exp $
  *
  * read configuration file
  */
-/*
- *
- * XXX - I'm not happy *at all* with this implementation, but I don't
- * think YACC would be any easier.  A more table based implementation
- * would be better.  Also clean up memory leaks.
- */
+
 #include "amanda.h"
 #include "arglist.h"
-
+#include "util.h"
 #include "conffile.h"
 #include "diskfile.h"
 #include "driverio.h"
 #define INT_MAX 2147483647
 #endif
 
-#define BIGINT 1000000000              /* 2 million yrs @ 1 per day */
-
-/* internal types and variables */
-
-typedef enum {
-    UNKNOWN, ANY, COMMA, LBRACE, RBRACE, NL, END,
-    IDENT, INT, LONG, AM64, BOOL, REAL, STRING, TIME,
-
-    /* config parameters */
-    INCLUDEFILE,
-    ORG, MAILTO, DUMPUSER,
-    TAPECYCLE, TAPEDEV, CHNGRDEV, CHNGRFILE, LABELSTR,
-    BUMPPERCENT, BUMPSIZE, BUMPDAYS, BUMPMULT, ETIMEOUT, DTIMEOUT, CTIMEOUT,
-    TAPEBUFS, TAPELIST, DISKFILE, INFOFILE, LOGDIR, LOGFILE,
-    DISKDIR, DISKSIZE, INDEXDIR, NETUSAGE, INPARALLEL, DUMPORDER, TIMEOUT,
-    TPCHANGER, RUNTAPES,
-    DEFINE, DUMPTYPE, TAPETYPE, INTERFACE,
-    PRINTER, AUTOFLUSH, RESERVE, MAXDUMPSIZE,
-    COLUMNSPEC, 
-    AMRECOVER_DO_FSF, AMRECOVER_CHECK_LABEL, AMRECOVER_CHANGER,
-    LABEL_NEW_TAPES,
-
-    TAPERALGO, FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST, LAST,
-    DISPLAYUNIT,
-
-    /* kerberos 5 */
-    KRB5KEYTAB, KRB5PRINCIPAL, 
-
-    /* holding disk */
-    COMMENT, DIRECTORY, USE, CHUNKSIZE,
-
-    /* dump type */
-    /*COMMENT,*/ PROGRAM, DUMPCYCLE, RUNSPERCYCLE, MAXCYCLE, MAXDUMPS,
-    OPTIONS, PRIORITY, FREQUENCY, INDEX, MAXPROMOTEDAY,
-    STARTTIME, COMPRESS, ENCRYPT, AUTH, STRATEGY, ESTIMATE,
-    SKIP_INCR, SKIP_FULL, RECORD, HOLDING,
-    EXCLUDE, INCLUDE, KENCRYPT, IGNORE, COMPRATE, TAPE_SPLITSIZE,
-    SPLIT_DISKBUFFER, FALLBACK_SPLITSIZE, SRVCOMPPROG, CLNTCOMPPROG,
-    SRV_ENCRYPT, CLNT_ENCRYPT, SRV_DECRYPT_OPT, CLNT_DECRYPT_OPT,
-
-    /* tape type */
-    /*COMMENT,*/ BLOCKSIZE, FILE_PAD, LBL_TEMPL, FILEMARK, LENGTH, SPEED,
-
-    /* network interface */
-    /*COMMENT, USE,*/
-
-    /* dump options (obsolete) */
-    EXCLUDE_FILE, EXCLUDE_LIST,
-
-    /* compress, estimate, encryption */
-    NONE, FAST, BEST, SERVER, CLIENT, CALCSIZE, CUSTOM,
-
-    /* priority */
-    LOW, MEDIUM, HIGH,
-
-    /* dump strategy */
-    SKIP, STANDARD, NOFULL, NOINC, HANOI, INCRONLY,
-
-    /* exclude list */
-    LIST, EFILE, APPEND, OPTIONAL,
-
-    /* numbers */
-    INFINITY, MULT1, MULT7, MULT1K, MULT1M, MULT1G,
-
-    /* boolean */
-    ATRUE, AFALSE,
-
-    RAWTAPEDEV
-} tok_t;
-
-typedef struct {       /* token table entry */
-    char *keyword;
-    tok_t token;
-} keytab_t;
-
-keytab_t *keytable;
-
-typedef union {
-    int i;
-    long l;
-    am64_t am64;
-    double r;
-    char *s;
-} val_t;
-
 /* this corresponds to the normal output of amanda, but may
  * be adapted to any spacing as you like.
  */
@@ -143,13 +53,13 @@ ColumnInfo ColumnData[] = {
     { "HostName",   0, 12, 12, 0, "%-*.*s", "HOSTNAME" },
     { "Disk",       1, 11, 11, 0, "%-*.*s", "DISK" },
     { "Level",      1, 1,  1,  0, "%*.*d",  "L" },
-    { "OrigKB",     1, 7,  0,  0, "%*.*f",  "ORIG-KB" },
-    { "OutKB",      1, 7,  0,  0, "%*.*f",  "OUT-KB" },
-    { "Compress",   1, 6,  1,  0, "%*.*f",  "COMP%" },
+    { "OrigKB",     1, 7,  0,  0, "%*.*lf", "ORIG-KB" },
+    { "OutKB",      1, 7,  0,  0, "%*.*lf", "OUT-KB" },
+    { "Compress",   1, 6,  1,  0, "%*.*lf", "COMP%" },
     { "DumpTime",   1, 7,  7,  0, "%*.*s",  "MMM:SS" },
-    { "DumpRate",   1, 6,  1,  0, "%*.*f",  "KB/s" },
+    { "DumpRate",   1, 6,  1,  0, "%*.*lf", "KB/s" },
     { "TapeTime",   1, 6,  6,  0, "%*.*s",  "MMM:SS" },
-    { "TapeRate",   1, 6,  1,  0, "%*.*f",  "KB/s" },
+    { "TapeRate",   1, 6,  1,  0, "%*.*lf", "KB/s" },
     { NULL,         0, 0,  0,  0, NULL,     NULL }
 };
 
@@ -165,59 +75,9 @@ long int unit_divisor = 1;
 
 /* configuration parameters */
 
-/* strings */
-static val_t conf_org;
-static val_t conf_mailto;
-static val_t conf_dumpuser;
-static val_t conf_printer;
-static val_t conf_tapedev;
-static val_t conf_rawtapedev;
-static val_t conf_tpchanger;
-static val_t conf_chngrdev;
-static val_t conf_chngrfile;
-static val_t conf_labelstr;
-static val_t conf_tapelist;
-static val_t conf_infofile;
-static val_t conf_logdir;
-static val_t conf_diskfile;
-static val_t conf_diskdir;
-static val_t conf_tapetype;
-static val_t conf_indexdir;
-static val_t conf_columnspec;
-static val_t conf_dumporder;
-static val_t conf_amrecover_changer;
-
-/* ints */
-static val_t conf_dumpcycle;
-static val_t conf_runspercycle;
-static val_t conf_maxcycle;
-static val_t conf_tapecycle;
-static val_t conf_runtapes;
-static val_t conf_disksize;
-static val_t conf_netusage;
-static val_t conf_inparallel;
-static val_t conf_timeout;
-static val_t conf_maxdumps;
-static val_t conf_bumppercent;
-static val_t conf_bumpsize;
-static val_t conf_bumpdays;
-static val_t conf_etimeout;
-static val_t conf_dtimeout;
-static val_t conf_ctimeout;
-static val_t conf_tapebufs;
-static val_t conf_autoflush;
-static val_t conf_reserve;
-static val_t conf_maxdumpsize;
-static val_t conf_amrecover_do_fsf;
-static val_t conf_amrecover_check_label;
-static val_t conf_taperalgo;
-static val_t conf_displayunit;
-static val_t conf_krb5keytab;
-static val_t conf_krb5principal;
-static val_t conf_label_new_tapes;
-
-/* reals */
-static val_t conf_bumpmult;
+val_t server_conf[CNF_CNF];
+
+command_option_t *server_options = NULL;
 
 /* other internal variables */
 static holdingdisk_t hdcur;
@@ -228,150 +88,272 @@ static dumptype_t dpcur;
 
 static interface_t ifcur;
 
-static int seen_org;
-static int seen_mailto;
-static int seen_dumpuser;
-static int seen_rawtapedev;
-static int seen_printer;
-static int seen_tapedev;
-static int seen_tpchanger;
-static int seen_chngrdev;
-static int seen_chngrfile;
-static int seen_labelstr;
-static int seen_runtapes;
-static int seen_maxdumps;
-static int seen_tapelist;
-static int seen_infofile;
-static int seen_diskfile;
-static int seen_diskdir;
-static int seen_logdir;
-static int seen_bumppercent;
-static int seen_bumpsize;
-static int seen_bumpmult;
-static int seen_bumpdays;
-static int seen_tapetype;
-static int seen_dumpcycle;
-static int seen_runspercycle;
-static int seen_maxcycle;
-static int seen_tapecycle;
-static int seen_disksize;
-static int seen_netusage;
-static int seen_inparallel;
-static int seen_dumporder;
-static int seen_timeout;
-static int seen_indexdir;
-static int seen_etimeout;
-static int seen_dtimeout;
-static int seen_ctimeout;
-static int seen_tapebufs;
-static int seen_autoflush;
-static int seen_reserve;
-static int seen_maxdumpsize;
-static int seen_columnspec;
-static int seen_amrecover_do_fsf;
-static int seen_amrecover_check_label;
-static int seen_amrecover_changer;
-static int seen_taperalgo;
-static int seen_displayunit;
-static int seen_krb5keytab;
-static int seen_krb5principal;
-static int seen_label_new_tapes;
-
-static int allow_overwrites;
-static int token_pushed;
-
-static tok_t tok, pushed_tok;
-static val_t tokenval;
-
-static int line_num, got_parserror;
 static dumptype_t *dumplist = NULL;
 static tapetype_t *tapelist = NULL;
 static interface_t *interface_list = NULL;
-static FILE *conf = (FILE *)NULL;
-static char *confname = NULL;
 
 /* predeclare local functions */
 
-static void init_defaults P((void));
-static void read_conffile_recursively P((char *filename));
-
-static int read_confline P((void));
-static void get_holdingdisk P((void));
-static void init_holdingdisk_defaults P((void));
-static void save_holdingdisk P((void));
-static void get_dumptype P((void));
-static void init_dumptype_defaults P((void));
-static void save_dumptype P((void));
-static void copy_dumptype P((void));
-static void get_tapetype P((void));
-static void init_tapetype_defaults P((void));
-static void save_tapetype P((void));
-static void copy_tapetype P((void));
-static void get_interface P((void));
-static void init_interface_defaults P((void));
-static void save_interface P((void));
-static void copy_interface P((void));
-static void get_dumpopts P((void));
-static void get_comprate P((void));
-static void get_compress P((void));
-static void get_encrypt P((void));
-static void get_priority P((void));
-static void get_strategy P((void));
-static void get_estimate P((void));
-static void get_exclude P((void));
-static void get_include P((void));
-static void get_taperalgo P((val_t *c_taperalgo, int *s_taperalgo));
-
-static void get_simple P((val_t *var, int *seen, tok_t type));
-static int get_time P((void));
-static int get_int P((void));
-static long get_long P((void));
-static am64_t get_am64_t P((void));
-static int get_bool P((void));
-static void ckseen P((int *seen));
-static void parserror P((char *format, ...))
-    __attribute__ ((format (printf, 1, 2)));
-static tok_t lookup_keyword P((char *str));
-static void unget_conftoken P((void));
-static void get_conftoken P((tok_t exp));
+char *get_token_name(tok_t);
+
+
+void validate_positive0   (t_conf_var *, val_t *);
+void validate_positive1   (t_conf_var *, val_t *);
+void validate_runspercycle(t_conf_var *, val_t *);
+void validate_bumppercent (t_conf_var *, val_t *);
+void validate_bumpmult    (t_conf_var *, val_t *);
+void validate_inparallel  (t_conf_var *, val_t *);
+void validate_displayunit (t_conf_var *, val_t *);
+void validate_reserve     (t_conf_var *, val_t *);
+void validate_use         (t_conf_var *, val_t *);
+void validate_chunksize   (t_conf_var *, val_t *);
+void validate_blocksize   (t_conf_var *, val_t *);
+
+static void init_defaults(void);
+static void read_conffile_recursively(char *filename);
+
+static int read_confline(void);
+static void get_holdingdisk(void);
+static void init_holdingdisk_defaults(void);
+static void save_holdingdisk(void);
+static void get_dumptype(void);
+static void init_dumptype_defaults(void);
+static void save_dumptype(void);
+static void copy_dumptype(void);
+static void get_tapetype(void);
+static void init_tapetype_defaults(void);
+static void save_tapetype(void);
+static void copy_tapetype(void);
+static void get_interface(void);
+static void init_interface_defaults(void);
+static void save_interface(void);
+static void copy_interface(void);
+static void get_comprate(t_conf_var *, val_t *);
+static void get_compress(t_conf_var *, val_t *);
+static void get_encrypt (t_conf_var *, val_t *);
+static void get_holding (t_conf_var *, val_t *);
+static void get_priority(t_conf_var *, val_t *);
+static void get_strategy(t_conf_var *, val_t *);
+static void get_estimate(t_conf_var *, val_t *);
+static void get_exclude (t_conf_var *, val_t *);
+/*static void get_include(t_conf_var *, val_t *);*/
+static void get_taperalgo(t_conf_var *, val_t *);
+
+keytab_t server_keytab[] = {
+    { "AMANDAD_PATH", CONF_AMANDAD_PATH },
+    { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER },
+    { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL },
+    { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF },
+    { "APPEND", CONF_APPEND },
+    { "AUTH", CONF_AUTH },
+    { "AUTO", CONF_AUTO },
+    { "AUTOFLUSH", CONF_AUTOFLUSH },
+    { "BEST", CONF_BEST },
+    { "BLOCKSIZE", CONF_BLOCKSIZE },
+    { "BUMPDAYS", CONF_BUMPDAYS },
+    { "BUMPMULT", CONF_BUMPMULT },
+    { "BUMPPERCENT", CONF_BUMPPERCENT },
+    { "BUMPSIZE", CONF_BUMPSIZE },
+    { "CALCSIZE", CONF_CALCSIZE },
+    { "CHANGERDEV", CONF_CHNGRDEV },
+    { "CHANGERFILE", CONF_CHNGRFILE },
+    { "CHUNKSIZE", CONF_CHUNKSIZE },
+    { "CLIENT", CONF_CLIENT },
+    { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG },
+    { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT },
+    { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT },
+    { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
+    { "COLUMNSPEC", CONF_COLUMNSPEC },
+    { "COMMENT", CONF_COMMENT },
+    { "COMPRATE", CONF_COMPRATE },
+    { "COMPRESS", CONF_COMPRESS },
+    { "CTIMEOUT", CONF_CTIMEOUT },
+    { "CUSTOM", CONF_CUSTOM },
+    { "DEFINE", CONF_DEFINE },
+    { "DIRECTORY", CONF_DIRECTORY },
+    { "DISKFILE", CONF_DISKFILE },
+    { "DISPLAYUNIT", CONF_DISPLAYUNIT },
+    { "DTIMEOUT", CONF_DTIMEOUT },
+    { "DUMPCYCLE", CONF_DUMPCYCLE },
+    { "DUMPORDER", CONF_DUMPORDER },
+    { "DUMPTYPE", CONF_DUMPTYPE },
+    { "DUMPUSER", CONF_DUMPUSER },
+    { "ENCRYPT", CONF_ENCRYPT },
+    { "ESTIMATE", CONF_ESTIMATE },
+    { "ETIMEOUT", CONF_ETIMEOUT },
+    { "EXCLUDE", CONF_EXCLUDE },
+    { "EXCLUDE-FILE", CONF_EXCLUDE_FILE },
+    { "EXCLUDE-LIST", CONF_EXCLUDE_LIST },
+    { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE },
+    { "FAST", CONF_FAST },
+    { "FILE", CONF_EFILE },
+    { "FILE-PAD", CONF_FILE_PAD },
+    { "FILEMARK", CONF_FILEMARK },
+    { "FIRST", CONF_FIRST },
+    { "FIRSTFIT", CONF_FIRSTFIT },
+    { "HANOI", CONF_HANOI },
+    { "HIGH", CONF_HIGH },
+    { "HOLDINGDISK", CONF_HOLDING },
+    { "IGNORE", CONF_IGNORE },
+    { "INCLUDE", CONF_INCLUDE },
+    { "INCLUDEFILE", CONF_INCLUDEFILE },
+    { "INCRONLY", CONF_INCRONLY },
+    { "INDEX", CONF_INDEX },
+    { "INDEXDIR", CONF_INDEXDIR },
+    { "INFOFILE", CONF_INFOFILE },
+    { "INPARALLEL", CONF_INPARALLEL },
+    { "INTERFACE", CONF_INTERFACE },
+    { "KENCRYPT", CONF_KENCRYPT },
+    { "KRB5KEYTAB", CONF_KRB5KEYTAB },
+    { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
+    { "LABELSTR", CONF_LABELSTR },
+    { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES },
+    { "LARGEST", CONF_LARGEST },
+    { "LARGESTFIT", CONF_LARGESTFIT },
+    { "LAST", CONF_LAST },
+    { "LBL-TEMPL", CONF_LBL_TEMPL },
+    { "LENGTH", CONF_LENGTH },
+    { "LIST", CONF_LIST },
+    { "LOGDIR", CONF_LOGDIR },
+    { "LOW", CONF_LOW },
+    { "MAILTO", CONF_MAILTO },
+    { "MAXDUMPS", CONF_MAXDUMPS },
+    { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
+    { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
+    { "MEDIUM", CONF_MEDIUM },
+    { "NETUSAGE", CONF_NETUSAGE },     /* XXX - historical */
+    { "NEVER", CONF_NEVER },
+    { "NOFULL", CONF_NOFULL },
+    { "NOINC", CONF_NOINC },
+    { "NONE", CONF_NONE },
+    { "OPTIONAL", CONF_OPTIONAL },
+    { "ORG", CONF_ORG },
+    { "PRINTER", CONF_PRINTER },
+    { "PRIORITY", CONF_PRIORITY },
+    { "PROGRAM", CONF_PROGRAM },
+    { "RAWTAPEDEV", CONF_RAWTAPEDEV },
+    { "RECORD", CONF_RECORD },
+    { "REQUIRED", CONF_REQUIRED },
+    { "RESERVE", CONF_RESERVE },
+    { "RUNSPERCYCLE", CONF_RUNSPERCYCLE },
+    { "RUNTAPES", CONF_RUNTAPES },
+    { "SERVER", CONF_SERVER },
+    { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG },
+    { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT },
+    { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT },
+    { "SKIP", CONF_SKIP },
+    { "SKIP-FULL", CONF_SKIP_FULL },
+    { "SKIP-INCR", CONF_SKIP_INCR },
+    { "SMALLEST", CONF_SMALLEST },
+    { "SPEED", CONF_SPEED },
+    { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER },
+    { "SSH_KEYS", CONF_SSH_KEYS },
+    { "STANDARD", CONF_STANDARD },
+    { "STARTTIME", CONF_STARTTIME },
+    { "STRATEGY", CONF_STRATEGY },
+    { "TAPEBUFS", CONF_TAPEBUFS },
+    { "TAPECYCLE", CONF_TAPECYCLE },
+    { "TAPEDEV", CONF_TAPEDEV },
+    { "TAPELIST", CONF_TAPELIST },
+    { "TAPERALGO", CONF_TAPERALGO },
+    { "TAPETYPE", CONF_TAPETYPE },
+    { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
+    { "TPCHANGER", CONF_TPCHANGER },
+    { "USE", CONF_USE },
+    { "USETIMESTAMPS", CONF_USETIMESTAMPS },
+    { NULL, CONF_IDENT },
+    { NULL, CONF_UNKNOWN }
+};
 
+t_conf_var server_var [] = {
+   { CONF_ORG                  , CONFTYPE_STRING   , read_string  , CNF_ORG                  , NULL },
+   { CONF_MAILTO               , CONFTYPE_STRING   , read_string  , CNF_MAILTO               , NULL },
+   { CONF_DUMPUSER             , CONFTYPE_STRING   , read_string  , CNF_DUMPUSER             , NULL },
+   { CONF_PRINTER              , CONFTYPE_STRING   , read_string  , CNF_PRINTER              , NULL },
+   { CONF_TAPEDEV              , CONFTYPE_STRING   , read_string  , CNF_TAPEDEV              , NULL },
+   { CONF_TPCHANGER            , CONFTYPE_STRING   , read_string  , CNF_TPCHANGER            , NULL },
+   { CONF_CHNGRDEV             , CONFTYPE_STRING   , read_string  , CNF_CHNGRDEV             , NULL },
+   { CONF_CHNGRFILE            , CONFTYPE_STRING   , read_string  , CNF_CHNGRFILE            , NULL },
+   { CONF_LABELSTR             , CONFTYPE_STRING   , read_string  , CNF_LABELSTR             , NULL },
+   { CONF_TAPELIST             , CONFTYPE_STRING   , read_string  , CNF_TAPELIST             , NULL },
+   { CONF_DISKFILE             , CONFTYPE_STRING   , read_string  , CNF_DISKFILE             , NULL },
+   { CONF_INFOFILE             , CONFTYPE_STRING   , read_string  , CNF_INFOFILE             , NULL },
+   { CONF_LOGDIR               , CONFTYPE_STRING   , read_string  , CNF_LOGDIR               , NULL },
+   { CONF_INDEXDIR             , CONFTYPE_STRING   , read_string  , CNF_INDEXDIR             , NULL },
+   { CONF_TAPETYPE             , CONFTYPE_IDENT    , read_ident   , CNF_TAPETYPE             , NULL },
+   { CONF_DUMPCYCLE            , CONFTYPE_INT      , read_int     , CNF_DUMPCYCLE            , validate_positive0 },
+   { CONF_RUNSPERCYCLE         , CONFTYPE_INT      , read_int     , CNF_RUNSPERCYCLE         , validate_runspercycle },
+   { CONF_RUNTAPES             , CONFTYPE_INT      , read_int     , CNF_RUNTAPES             , validate_positive0 },
+   { CONF_TAPECYCLE            , CONFTYPE_INT      , read_int     , CNF_TAPECYCLE            , validate_positive1 },
+   { CONF_BUMPDAYS             , CONFTYPE_INT      , read_int     , CNF_BUMPDAYS             , validate_positive1 },
+   { CONF_BUMPSIZE             , CONFTYPE_AM64     , read_am64    , CNF_BUMPSIZE             , validate_positive1 },
+   { CONF_BUMPPERCENT          , CONFTYPE_INT      , read_int     , CNF_BUMPPERCENT          , validate_bumppercent },
+   { CONF_BUMPMULT             , CONFTYPE_REAL     , read_real    , CNF_BUMPMULT             , validate_bumpmult },
+   { CONF_NETUSAGE             , CONFTYPE_INT      , read_int     , CNF_NETUSAGE             , validate_positive1 },
+   { CONF_INPARALLEL           , CONFTYPE_INT      , read_int     , CNF_INPARALLEL           , validate_inparallel },
+   { CONF_DUMPORDER            , CONFTYPE_STRING   , read_string  , CNF_DUMPORDER            , NULL },
+   { CONF_MAXDUMPS             , CONFTYPE_INT      , read_int     , CNF_MAXDUMPS             , validate_positive1 },
+   { CONF_ETIMEOUT             , CONFTYPE_TIME     , read_time    , CNF_ETIMEOUT             , NULL },
+   { CONF_DTIMEOUT             , CONFTYPE_TIME     , read_time    , CNF_DTIMEOUT             , validate_positive1 },
+   { CONF_CTIMEOUT             , CONFTYPE_TIME     , read_time    , CNF_CTIMEOUT             , validate_positive1 },
+   { CONF_TAPEBUFS             , CONFTYPE_INT      , read_int     , CNF_TAPEBUFS             , validate_positive1 },
+   { CONF_RAWTAPEDEV           , CONFTYPE_STRING   , read_string  , CNF_RAWTAPEDEV           , NULL },
+   { CONF_COLUMNSPEC           , CONFTYPE_STRING   , read_string  , CNF_COLUMNSPEC           , NULL },
+   { CONF_TAPERALGO            , CONFTYPE_TAPERALGO, get_taperalgo, CNF_TAPERALGO            , NULL },
+   { CONF_DISPLAYUNIT          , CONFTYPE_STRING   , read_string  , CNF_DISPLAYUNIT          , validate_displayunit },
+   { CONF_AUTOFLUSH            , CONFTYPE_BOOL     , read_bool    , CNF_AUTOFLUSH            , NULL },
+   { CONF_RESERVE              , CONFTYPE_INT      , read_int     , CNF_RESERVE              , validate_reserve },
+   { CONF_MAXDUMPSIZE          , CONFTYPE_AM64     , read_am64    , CNF_MAXDUMPSIZE          , NULL },
+   { CONF_KRB5KEYTAB           , CONFTYPE_STRING   , read_string  , CNF_KRB5KEYTAB           , NULL },
+   { CONF_KRB5PRINCIPAL        , CONFTYPE_STRING   , read_string  , CNF_KRB5PRINCIPAL        , NULL },
+   { CONF_LABEL_NEW_TAPES      , CONFTYPE_STRING   , read_string  , CNF_LABEL_NEW_TAPES      , NULL },
+   { CONF_USETIMESTAMPS        , CONFTYPE_BOOL     , read_bool    , CNF_USETIMESTAMPS        , NULL },
+   { CONF_AMRECOVER_DO_FSF     , CONFTYPE_BOOL     , read_bool    , CNF_AMRECOVER_DO_FSF     , NULL },
+   { CONF_AMRECOVER_CHANGER    , CONFTYPE_STRING   , read_string  , CNF_AMRECOVER_CHANGER    , NULL },
+   { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOL     , read_bool    , CNF_AMRECOVER_CHECK_LABEL, NULL },
+   { CONF_UNKNOWN              , CONFTYPE_INT      , NULL         , CNF_CNF                  , NULL }
+};
 /*
 ** ------------------------
 **  External entry points
 ** ------------------------
 */
 
-int read_conffile(filename)
-char *filename;
+int
+read_conffile(
+    char *filename)
 {
     interface_t *ip;
 
     init_defaults();
 
-    /* We assume that confname & conf are initialized to NULL above */
+    /* We assume that conf_confname & conf are initialized to NULL above */
     read_conffile_recursively(filename);
 
+    /* overwrite with command line option */
+    command_overwrite(server_options, server_var, server_keytab, server_conf,
+                     "");
+
     if(got_parserror != -1 ) {
-       if(lookup_tapetype(conf_tapetype.s) == NULL) {
-           char *save_confname = confname;
+       if(lookup_tapetype(server_conf[CNF_TAPETYPE].v.s) == NULL) {
+           char *save_confname = conf_confname;
 
-           confname = filename;
-           if(!seen_tapetype)
-               parserror("default tapetype %s not defined", conf_tapetype.s);
+           conf_confname = filename;
+           if(!server_conf[CNF_TAPETYPE].seen)
+               conf_parserror("default tapetype %s not defined", server_conf[CNF_TAPETYPE].v.s);
            else {
-               line_num = seen_tapetype;
-               parserror("tapetype %s not defined", conf_tapetype.s);
+               conf_line_num = server_conf[CNF_TAPETYPE].seen;
+               conf_parserror("tapetype %s not defined", server_conf[CNF_TAPETYPE].v.s);
            }
-           confname = save_confname;
+           conf_confname = save_confname;
        }
     }
 
-    ip = alloc(sizeof(interface_t));
-    malloc_mark(ip);
-    ip->name = "";
-    ip->seen = seen_netusage;
-    ip->comment = "implicit from NETUSAGE";
-    ip->maxusage = conf_netusage.i;
+    ip = alloc(SIZEOF(interface_t));
+    ip->name = stralloc("default");
+    ip->seen = server_conf[CNF_NETUSAGE].seen;
+    conf_init_string(&ip->value[INTER_COMMENT], "implicit from NETUSAGE");
+    conf_init_int(&ip->value[INTER_MAXUSAGE], server_conf[CNF_NETUSAGE].v.i);
     ip->curusage = 0;
     ip->next = interface_list;
     interface_list = ip;
@@ -379,95 +361,225 @@ char *filename;
     return got_parserror;
 }
 
-struct byname {
-    char *name;
-    confparm_t parm;
-    tok_t typ;
-} byname_table [] = {
-    { "ORG", CNF_ORG, STRING },
-    { "MAILTO", CNF_MAILTO, STRING },
-    { "DUMPUSER", CNF_DUMPUSER, STRING },
-    { "PRINTER", CNF_PRINTER, STRING },
-    { "TAPEDEV", CNF_TAPEDEV, STRING },
-    { "TPCHANGER", CNF_TPCHANGER, STRING },
-    { "CHANGERDEV", CNF_CHNGRDEV, STRING },
-    { "CHANGERFILE", CNF_CHNGRFILE, STRING },
-    { "LABELSTR", CNF_LABELSTR, STRING },
-    { "TAPELIST", CNF_TAPELIST, STRING },
-    { "DISKFILE", CNF_DISKFILE, STRING },
-    { "INFOFILE", CNF_INFOFILE, STRING },
-    { "LOGDIR", CNF_LOGDIR, STRING },
-    /*{ "LOGFILE", CNF_LOGFILE, STRING },*/
-    /*{ "DISKDIR", CNF_DISKDIR, STRING },*/
-    { "INDEXDIR", CNF_INDEXDIR, STRING },
-    { "TAPETYPE", CNF_TAPETYPE, STRING },
-    { "DUMPCYCLE", CNF_DUMPCYCLE, INT },
-    { "RUNSPERCYCLE", CNF_RUNSPERCYCLE, INT },
-    { "MINCYCLE",  CNF_DUMPCYCLE, INT },
-    { "RUNTAPES",   CNF_RUNTAPES, INT },
-    { "TAPECYCLE", CNF_TAPECYCLE, INT },
-    /*{ "DISKSIZE", CNF_DISKSIZE, INT },*/
-    { "BUMPDAYS", CNF_BUMPDAYS, INT },
-    { "BUMPSIZE", CNF_BUMPSIZE, INT },
-    { "BUMPPERCENT", CNF_BUMPPERCENT, INT },
-    { "BUMPMULT", CNF_BUMPMULT, REAL },
-    { "NETUSAGE", CNF_NETUSAGE, INT },
-    { "INPARALLEL", CNF_INPARALLEL, INT },
-    { "DUMPORDER", CNF_DUMPORDER, STRING },
-    /*{ "TIMEOUT", CNF_TIMEOUT, INT },*/
-    { "MAXDUMPS", CNF_MAXDUMPS, INT },
-    { "ETIMEOUT", CNF_ETIMEOUT, INT },
-    { "DTIMEOUT", CNF_DTIMEOUT, INT },
-    { "CTIMEOUT", CNF_CTIMEOUT, INT },
-    { "TAPEBUFS", CNF_TAPEBUFS, INT },
-    { "RAWTAPEDEV", CNF_RAWTAPEDEV, STRING },
-    { "COLUMNSPEC", CNF_COLUMNSPEC, STRING },
-    { "AMRECOVER_DO_FSF", CNF_AMRECOVER_DO_FSF, BOOL },
-    { "AMRECOVER_CHECK_LABEL", CNF_AMRECOVER_CHECK_LABEL, BOOL },
-    { "AMRECOVER_CHANGER", CNF_AMRECOVER_CHANGER, STRING },
-    { "TAPERALGO", CNF_TAPERALGO, INT },
-    { "DISPLAYUNIT", CNF_DISPLAYUNIT, STRING },
-    { "AUTOFLUSH", CNF_AUTOFLUSH, BOOL },
-    { "RESERVE", CNF_RESERVE, INT },
-    { "MAXDUMPSIZE", CNF_MAXDUMPSIZE, AM64 },
-    { "KRB5KEYTAB", CNF_KRB5KEYTAB, STRING },
-    { "KRB5PRINCIPAL", CNF_KRB5PRINCIPAL, STRING },
-    { "LABEL_NEW_TAPES", CNF_LABEL_NEW_TAPES, STRING },
-    { NULL }
-};
+void
+validate_positive0(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    switch(val->type) {
+    case CONFTYPE_INT:
+       if(val->v.i < 0)
+           conf_parserror("%s must be positive", get_token_name(np->token));
+       break;
+    case CONFTYPE_LONG:
+       if(val->v.l < 0)
+           conf_parserror("%s must be positive", get_token_name(np->token));
+       break;
+    case CONFTYPE_AM64:
+       if(val->v.am64 < 0)
+           conf_parserror("%s must be positive", get_token_name(np->token));
+       break;
+    default:
+       conf_parserror("validate_positive0 invalid type %d\n", val->type);
+    }
+}
+
+void
+validate_positive1(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    switch(val->type) {
+    case CONFTYPE_INT:
+       if(val->v.i < 1)
+           conf_parserror("%s must be positive", get_token_name(np->token));
+       break;
+    case CONFTYPE_LONG:
+       if(val->v.l < 1)
+           conf_parserror("%s must be positive", get_token_name(np->token));
+       break;
+    case CONFTYPE_AM64:
+       if(val->v.am64 < 1)
+           conf_parserror("%s must be positive", get_token_name(np->token));
+       break;
+    case CONFTYPE_TIME:
+       if(val->v.t < 1)
+           conf_parserror("%s must be positive", get_token_name(np->token));
+       break;
+    default:
+       conf_parserror("validate_positive1 invalid type %d\n", val->type);
+    }
+}
+
+void
+validate_runspercycle(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    if(val->v.i < -1)
+       conf_parserror("runspercycle must be >= -1");
+}
+
+void
+validate_bumppercent(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    if(val->v.i < 0 || val->v.i > 100)
+       conf_parserror("bumppercent must be between 0 and 100");
+}
+
+void
+validate_inparallel(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    if(val->v.i < 1 || val->v.i >MAX_DUMPERS)
+       conf_parserror("inparallel must be between 1 and MAX_DUMPERS (%d)",
+                      MAX_DUMPERS);
+}
+
+void
+validate_bumpmult(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    if(val->v.r < 0.999) {
+       conf_parserror("bumpmult must be positive");
+    }
+}
+
+void
+validate_displayunit(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    if(strcmp(val->v.s, "k") == 0 ||
+       strcmp(val->v.s, "K") == 0) {
+       val->v.s[0] = (char)toupper(val->v.s[0]);
+       unit_divisor=1;
+    }
+    else if(strcmp(val->v.s, "m") == 0 ||
+       strcmp(val->v.s, "M") == 0) {
+       val->v.s[0] = (char)toupper(val->v.s[0]);
+       unit_divisor=1024;
+    }
+    else if(strcmp(val->v.s, "g") == 0 ||
+       strcmp(val->v.s, "G") == 0) {
+       val->v.s[0] = (char)toupper(val->v.s[0]);
+       unit_divisor=1024*1024;
+    }
+    else if(strcmp(val->v.s, "t") == 0 ||
+       strcmp(val->v.s, "T") == 0) {
+       val->v.s[0] = (char)toupper(val->v.s[0]);
+       unit_divisor=1024*1024*1024;
+    }
+    else {
+       conf_parserror("displayunit must be k,m,g or t.");
+    }
+}
+
+void
+validate_reserve(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    if(val->v.i < 0 || val->v.i > 100)
+       conf_parserror("reserve must be between 0 and 100");
+}
+
+void
+validate_use(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    val->v.am64 = am_floor(val->v.am64, DISK_BLOCK_KB);
+}
+
+void
+validate_chunksize(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    if(val->v.am64 == 0) {
+       val->v.am64 = ((AM64_MAX / 1024) - (2 * DISK_BLOCK_KB));
+    }
+    else if(val->v.am64 < 0) {
+       conf_parserror("Negative chunksize (%lld) is no longer supported", val->v.am64);
+    }
+    val->v.am64 = am_floor(val->v.am64, (off_t)DISK_BLOCK_KB);
+}
+
+void
+validate_blocksize(
+    struct s_conf_var *np,
+    val_t        *val)
+{
+    np = np;
+    if(val->v.l < DISK_BLOCK_KB) {
+       conf_parserror("Tape blocksize must be at least %d KBytes",
+                 DISK_BLOCK_KB);
+    } else if(val->v.l > MAX_TAPE_BLOCK_KB) {
+       conf_parserror("Tape blocksize must not be larger than %d KBytes",
+                 MAX_TAPE_BLOCK_KB);
+    }
+}
 
-char *getconf_byname(str)
-char *str;
+char *
+getconf_byname(
+    char *str)
 {
     static char *tmpstr;
     char number[NUM_STR_SIZE];
-    struct byname *np;
+    t_conf_var *np;
+    keytab_t *kt;
     char *s;
     char ch;
 
     tmpstr = stralloc(str);
     s = tmpstr;
     while((ch = *s++) != '\0') {
-       if(islower((int)ch)) s[-1] = toupper(ch);
+       if(islower((int)ch))
+           s[-1] = (char)toupper(ch);
+    }
+    for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
+       if(kt->keyword && strcmp(kt->keyword, tmpstr) == 0)
+           break;
     }
 
-    for(np = byname_table; np->name != NULL; np++)
-       if(strcmp(np->name, tmpstr) == 0) break;
+    if(kt->token == CONF_UNKNOWN)
+       return NULL;
+
+    for(np = server_var; np->token != CONF_UNKNOWN; np++) {
+       if(np->token == kt->token)
+           break;
+    }
 
-    if(np->name == NULL) return NULL;
+    if(np->token == CONF_UNKNOWN) return NULL;
 
-    if(np->typ == INT) {
-       snprintf(number, sizeof(number), "%d", getconf_int(np->parm));
+    if(np->type == CONFTYPE_INT) {
+       snprintf(number, sizeof(number), "%d", server_conf[np->parm].v.i);
        tmpstr = newstralloc(tmpstr, number);
-    } else if(np->typ == BOOL) {
-       if(getconf_int(np->parm) == 0) {
+    } else if(np->type == CONFTYPE_BOOL) {
+       if(getconf_boolean(np->parm) == 0) {
            tmpstr = newstralloc(tmpstr, "off");
-       }
-       else {
+       } else {
            tmpstr = newstralloc(tmpstr, "on");
        }
-    } else if(np->typ == REAL) {
-       snprintf(number, sizeof(number), "%f", getconf_real(np->parm));
+    } else if(np->type == CONFTYPE_REAL) {
+       snprintf(number, sizeof(number), "%lf", server_conf[np->parm].v.r);
+       tmpstr = newstralloc(tmpstr, number);
+    } else if(np->type == CONFTYPE_AM64){
+       snprintf(number, sizeof(number), OFF_T_FMT, 
+                (OFF_T_FMT_TYPE)server_conf[np->parm].v.am64);
        tmpstr = newstralloc(tmpstr, number);
     } else {
        tmpstr = newstralloc(tmpstr, getconf_str(np->parm));
@@ -476,205 +588,180 @@ char *str;
     return tmpstr;
 }
 
-int getconf_seen(parm)
-confparm_t parm;
-{
-    switch(parm) {
-    case CNF_ORG: return seen_org;
-    case CNF_MAILTO: return seen_mailto;
-    case CNF_DUMPUSER: return seen_dumpuser;
-    case CNF_PRINTER: return seen_printer;
-    case CNF_TAPEDEV: return seen_tapedev;
-    case CNF_TPCHANGER: return seen_tpchanger;
-    case CNF_CHNGRDEV: return seen_chngrdev;
-    case CNF_CHNGRFILE: return seen_chngrfile;
-    case CNF_LABELSTR: return seen_labelstr;
-    case CNF_RUNTAPES: return seen_runtapes;
-    case CNF_MAXDUMPS: return seen_maxdumps;
-    case CNF_TAPELIST: return seen_tapelist;
-    case CNF_INFOFILE: return seen_infofile;
-    case CNF_DISKFILE: return seen_diskfile;
-    /*case CNF_DISKDIR: return seen_diskdir;*/
-    case CNF_LOGDIR: return seen_logdir;
-    /*case CNF_LOGFILE: return seen_logfile;*/
-    case CNF_BUMPPERCENT: return seen_bumppercent;
-    case CNF_BUMPSIZE: return seen_bumpsize;
-    case CNF_BUMPMULT: return seen_bumpmult;
-    case CNF_BUMPDAYS: return seen_bumpdays;
-    case CNF_TAPETYPE: return seen_tapetype;
-    case CNF_DUMPCYCLE: return seen_dumpcycle;
-    case CNF_RUNSPERCYCLE: return seen_runspercycle;
-    /*case CNF_MAXCYCLE: return seen_maxcycle;*/
-    case CNF_TAPECYCLE: return seen_tapecycle;
-    /*case CNF_DISKSIZE: return seen_disksize;*/
-    case CNF_NETUSAGE: return seen_netusage;
-    case CNF_INPARALLEL: return seen_inparallel;
-    case CNF_DUMPORDER: return seen_dumporder;
-    /*case CNF_TIMEOUT: return seen_timeout;*/
-    case CNF_INDEXDIR: return seen_indexdir;
-    case CNF_ETIMEOUT: return seen_etimeout;
-    case CNF_DTIMEOUT: return seen_dtimeout;
-    case CNF_CTIMEOUT: return seen_ctimeout;
-    case CNF_TAPEBUFS: return seen_tapebufs;
-    case CNF_RAWTAPEDEV: return seen_rawtapedev;
-    case CNF_AUTOFLUSH: return seen_autoflush;
-    case CNF_RESERVE: return seen_reserve;
-    case CNF_MAXDUMPSIZE: return seen_maxdumpsize;
-    case CNF_AMRECOVER_DO_FSF: return seen_amrecover_do_fsf;
-    case CNF_AMRECOVER_CHECK_LABEL: return seen_amrecover_check_label;
-    case CNF_AMRECOVER_CHANGER: return seen_amrecover_changer;
-    case CNF_TAPERALGO: return seen_taperalgo;
-    case CNF_DISPLAYUNIT: return seen_displayunit;
-    case CNF_KRB5KEYTAB: return seen_krb5keytab;
-    case CNF_KRB5PRINCIPAL: return seen_krb5principal;
-    case CNF_LABEL_NEW_TAPES: return seen_label_new_tapes;
-    default: return 0;
-    }
-}
-
-int getconf_int(parm)
-confparm_t parm;
-{
-    int r = 0;
-
-    switch(parm) {
-
-    case CNF_DUMPCYCLE: r = conf_dumpcycle.i; break;
-    case CNF_RUNSPERCYCLE: r = conf_runspercycle.i; break;
-    case CNF_TAPECYCLE: r = conf_tapecycle.i; break;
-    case CNF_RUNTAPES: r = conf_runtapes.i; break;
-    /*case CNF_DISKSIZE: r = conf_disksize.i; break;*/
-    case CNF_BUMPPERCENT: r = conf_bumppercent.i; break;
-    case CNF_BUMPSIZE: r = conf_bumpsize.i; break;
-    case CNF_BUMPDAYS: r = conf_bumpdays.i; break;
-    case CNF_NETUSAGE: r = conf_netusage.i; break;
-    case CNF_INPARALLEL: r = conf_inparallel.i; break;
-    /*case CNF_TIMEOUT: r = conf_timeout.i; break;*/
-    case CNF_MAXDUMPS: r = conf_maxdumps.i; break;
-    case CNF_ETIMEOUT: r = conf_etimeout.i; break;
-    case CNF_DTIMEOUT: r = conf_dtimeout.i; break;
-    case CNF_CTIMEOUT: r = conf_ctimeout.i; break;
-    case CNF_TAPEBUFS: r = conf_tapebufs.i; break;
-    case CNF_AUTOFLUSH: r = conf_autoflush.i; break;
-    case CNF_RESERVE: r = conf_reserve.i; break;
-    case CNF_AMRECOVER_DO_FSF: r = conf_amrecover_do_fsf.i; break;
-    case CNF_AMRECOVER_CHECK_LABEL: r = conf_amrecover_check_label.i; break;
-    case CNF_TAPERALGO: r = conf_taperalgo.i; break;
+int
+getconf_seen(
+    confparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    return(server_conf[np->parm].seen);
+}
 
-    default:
-       error("error [unknown getconf_int parm: %d]", parm);
-       /* NOTREACHED */
+int
+getconf_boolean(
+    confparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_BOOL) {
+       error("getconf_boolean: np is not a CONFTYPE_BOOL");
+       /*NOTREACHED*/
     }
-    return r;
+    return(server_conf[np->parm].v.i != 0);
 }
 
-am64_t getconf_am64(parm)
-confparm_t parm;
+int
+getconf_int(
+    confparm_t parm)
 {
-    am64_t r = 0;
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_INT) {
+       error("getconf_int: np is not a CONFTYPE_INT");
+       /*NOTREACHED*/
+    }
+    return(server_conf[np->parm].v.i);
+}
 
-    switch(parm) {
-    case CNF_MAXDUMPSIZE: r = conf_maxdumpsize.am64; break;
+long
+getconf_long(
+    confparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_LONG) {
+       error("getconf_long: np is not a CONFTYPE_LONG");
+       /*NOTREACHED*/
+    }
+    return(server_conf[np->parm].v.l);
+}
 
-    default:
-       error("error [unknown getconf_am64 parm: %d]", parm);
-       /* NOTREACHED */
+time_t
+getconf_time(
+    confparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_TIME) {
+       error("getconf_time: np is not a CONFTYPE_TIME");
+       /*NOTREACHED*/
     }
-    return r;
+    return(server_conf[np->parm].v.t);
 }
 
-double getconf_real(parm)
-confparm_t parm;
+ssize_t
+getconf_size(
+    confparm_t parm)
 {
-    double r = 0;
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_SIZE) {
+       error("getconf_size: np is not a CONFTYPE_SIZE");
+       /*NOTREACHED*/
+    }
+    return(server_conf[np->parm].v.size);
+}
 
-    switch(parm) {
+off_t
+getconf_am64(
+    confparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_AM64) {
+       error("getconf_am64: np is not a CONFTYPE_AM64");
+       /*NOTREACHED*/
+    }
+    return(server_conf[np->parm].v.am64);
+}
 
-    case CNF_BUMPMULT: r = conf_bumpmult.r; break;
+double
+getconf_real(
+    confparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_REAL) {
+       error("getconf_real: np is not a CONFTYPE_REAL");
+       /*NOTREACHED*/
+    }
+    return(server_conf[np->parm].v.r);
+}
 
-    default:
-       error("error [unknown getconf_real parm: %d]", parm);
-       /* NOTREACHED */
-    }
-    return r;
-}
-
-char *getconf_str(parm)
-confparm_t parm;
-{
-    char *r = 0;
-
-    switch(parm) {
-
-    case CNF_ORG: r = conf_org.s; break;
-    case CNF_MAILTO: r = conf_mailto.s; break;
-    case CNF_DUMPUSER: r = conf_dumpuser.s; break;
-    case CNF_PRINTER: r = conf_printer.s; break;
-    case CNF_TAPEDEV: r = conf_tapedev.s; break;
-    case CNF_TPCHANGER: r = conf_tpchanger.s; break;
-    case CNF_CHNGRDEV: r = conf_chngrdev.s; break;
-    case CNF_CHNGRFILE: r = conf_chngrfile.s; break;
-    case CNF_LABELSTR: r = conf_labelstr.s; break;
-    case CNF_TAPELIST: r = conf_tapelist.s; break;
-    case CNF_INFOFILE: r = conf_infofile.s; break;
-    case CNF_DUMPORDER: r = conf_dumporder.s; break;
-    case CNF_LOGDIR: r = conf_logdir.s; break;
-    /*case CNF_LOGFILE: r = conf_logfile.s; break;*/
-    case CNF_DISKFILE: r = conf_diskfile.s; break;
-    /*case CNF_DISKDIR: r = conf_diskdir.s; break;*/
-    case CNF_TAPETYPE: r = conf_tapetype.s; break;
-    case CNF_INDEXDIR: r = conf_indexdir.s; break;
-    case CNF_RAWTAPEDEV: r = conf_rawtapedev.s; break;
-    case CNF_COLUMNSPEC: r = conf_columnspec.s; break;
-    case CNF_AMRECOVER_CHANGER: r = conf_amrecover_changer.s; break;
-    case CNF_DISPLAYUNIT: r = conf_displayunit.s; break;
-    case CNF_KRB5PRINCIPAL: r = conf_krb5principal.s; break;
-    case CNF_KRB5KEYTAB: r = conf_krb5keytab.s; break;
-    case CNF_LABEL_NEW_TAPES: r = conf_label_new_tapes.s; break;
+char *
+getconf_str(
+    confparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_STRING && np->type != CONFTYPE_IDENT) {
+       error("getconf_str: np is not a CONFTYPE_STRING|CONFTYPE_IDENT: %d", parm);
+       /*NOTREACHED*/
+    }
+    return(server_conf[np->parm].v.s);
+}
 
-    default:
-       error("error [unknown getconf_str parm: %d]", parm);
-       /* NOTREACHED */
+int
+getconf_taperalgo(
+    confparm_t parm)
+{
+    t_conf_var *np;
+    np = get_np(server_var, parm);
+    if (np->type != CONFTYPE_TAPERALGO) {
+       error("getconf_taperalgo: np is not a CONFTYPE_TAPERALGO");
+       /*NOTREACHED*/
     }
-    return r;
+    return(server_conf[np->parm].v.i);
 }
 
-holdingdisk_t *getconf_holdingdisks()
+holdingdisk_t *
+getconf_holdingdisks(
+    void)
 {
     return holdingdisks;
 }
 
-dumptype_t *lookup_dumptype(str)
-char *str;
+dumptype_t *
+lookup_dumptype(
+    char *str)
 {
     dumptype_t *p;
 
     for(p = dumplist; p != NULL; p = p->next) {
-       if(strcmp(p->name, str) == 0) return p;
+       if(strcasecmp(p->name, str) == 0) return p;
     }
     return NULL;
 }
 
-tapetype_t *lookup_tapetype(str)
-char *str;
+tapetype_t *
+lookup_tapetype(
+    char *str)
 {
     tapetype_t *p;
 
     for(p = tapelist; p != NULL; p = p->next) {
-       if(strcmp(p->name, str) == 0) return p;
+       if(strcasecmp(p->name, str) == 0) return p;
     }
     return NULL;
 }
 
-interface_t *lookup_interface(str)
-char *str;
+interface_t *
+lookup_interface(
+    char *str)
 {
+#ifndef __lint
     interface_t *p;
+#endif
 
-    if(str == NULL) return interface_list;
-    for(p = interface_list; p != NULL; p = p->next) {
-       if(strcmp(p->name, str) == 0) return p;
+    if (str == NULL)
+       return interface_list;
+
+#ifndef __lint
+    for (p = interface_list; p != NULL; p = p->next) {
+       if (strcasecmp(p->name, str) == 0)
+           return p;
     }
+#endif
     return NULL;
 }
 
@@ -686,7 +773,9 @@ char *str;
 */
 
 
-static void init_defaults()
+static void
+init_defaults(
+    void)
 {
     char *s;
 
@@ -697,141 +786,70 @@ static void init_defaults()
 #else
     s = "YOUR ORG";
 #endif
-    conf_org.s = stralloc(s);
-    malloc_mark(conf_org.s);
-    conf_mailto.s = stralloc("operators");
-    malloc_mark(conf_mailto.s);
-    conf_dumpuser.s = stralloc(CLIENT_LOGIN);
-    malloc_mark(conf_dumpuser.s);
+    conf_init_string(&server_conf[CNF_ORG], s);
+    conf_init_string(&server_conf[CNF_MAILTO], "operators");
+    conf_init_string(&server_conf[CNF_DUMPUSER], CLIENT_LOGIN);
 #ifdef DEFAULT_TAPE_DEVICE
     s = DEFAULT_TAPE_DEVICE;
 #else
     s = "/dev/rmt8";
 #endif
-    conf_tapedev.s = stralloc(s);
-    malloc_mark(conf_tapedev.s);
-#ifdef DEFAULT_RAW_TAPE_DEVICE
-    s = DEFAULT_RAW_TAPE_DEVICE;
-#else
-    s = "/dev/rawft0";
-#endif
-    conf_rawtapedev.s = stralloc(s);
-    malloc_mark(conf_rawtapedev.s);
-    conf_tpchanger.s = stralloc("");
-    malloc_mark(conf_tpchanger.s);
+    conf_init_string(&server_conf[CNF_TAPEDEV], s);
 #ifdef DEFAULT_CHANGER_DEVICE
     s = DEFAULT_CHANGER_DEVICE;
 #else
     s = "/dev/null";
 #endif
-    conf_chngrdev.s = stralloc(s);
-    malloc_mark(conf_chngrdev.s);
-    conf_chngrfile.s = stralloc("/usr/adm/amanda/changer-status");
-    malloc_mark(conf_chngrfile.s);
-    conf_labelstr.s = stralloc(".*");
-    malloc_mark(conf_labelstr.s);
-    conf_tapelist.s = stralloc("tapelist");
-    malloc_mark(conf_tapelist.s);
-    conf_infofile.s = stralloc("/usr/adm/amanda/curinfo");
-    malloc_mark(conf_infofile.s);
-    conf_logdir.s = stralloc("/usr/adm/amanda");
-    malloc_mark(conf_logdir.s);
-    conf_diskfile.s = stralloc("disklist");
-    malloc_mark(conf_diskfile.s);
-    conf_diskdir.s  = stralloc("/dumps/amanda");
-    malloc_mark(conf_diskdir.s);
-    conf_tapetype.s = stralloc("EXABYTE");
-    malloc_mark(conf_tapetype.s);
-    conf_indexdir.s = stralloc("/usr/adm/amanda/index");
-    malloc_mark(conf_indexdir.s);
-    conf_columnspec.s = stralloc("");
-    malloc_mark(conf_columnspec.s);
-    conf_dumporder.s = stralloc("ttt");
-    malloc_mark(conf_dumporder.s);
-    conf_amrecover_changer.s = stralloc("");
-    conf_printer.s = stralloc("");
-    conf_displayunit.s = stralloc("k");
-    conf_label_new_tapes.s = stralloc("");
-
-    conf_krb5keytab.s = stralloc("/.amanda-v5-keytab");
-    conf_krb5principal.s = stralloc("service/amanda");
-
-    conf_dumpcycle.i   = 10;
-    conf_runspercycle.i        = 0;
-    conf_tapecycle.i   = 15;
-    conf_runtapes.i    = 1;
-    conf_disksize.i    = 0;
-    conf_netusage.i    = 300;
-    conf_inparallel.i  = 10;
-    conf_maxdumps.i    = 1;
-    conf_timeout.i     = 2;
-    conf_bumppercent.i = 0;
-    conf_bumpsize.i    = 10*1024;
-    conf_bumpdays.i    = 2;
-    conf_bumpmult.r    = 1.5;
-    conf_etimeout.i     = 300;
-    conf_dtimeout.i     = 1800;
-    conf_ctimeout.i     = 30;
-    conf_tapebufs.i     = 20;
-    conf_autoflush.i   = 0;
-    conf_reserve.i     = 100;
-    conf_maxdumpsize.am64      = -1;
-    conf_amrecover_do_fsf.i = 1;
-    conf_amrecover_check_label.i = 1;
-    conf_taperalgo.i = 0;
+    conf_init_string(&server_conf[CNF_CHNGRDEV], s);
+    conf_init_string(&server_conf[CNF_CHNGRFILE], "/usr/adm/amanda/changer-status");
+#ifdef DEFAULT_RAW_TAPE_DEVICE
+    s = DEFAULT_RAW_TAPE_DEVICE;
+#else
+    s = "/dev/rawft0";
+#endif
+    conf_init_string   (&server_conf[CNF_LABELSTR]             , ".*");
+    conf_init_string   (&server_conf[CNF_TAPELIST]             , "tapelist");
+    conf_init_string   (&server_conf[CNF_DISKFILE]             , "disklist");
+    conf_init_string   (&server_conf[CNF_INFOFILE]             , "/usr/adm/amanda/curinfo");
+    conf_init_string   (&server_conf[CNF_LOGDIR]               , "/usr/adm/amanda");
+    conf_init_string   (&server_conf[CNF_INDEXDIR]             , "/usr/adm/amanda/index");
+    conf_init_ident    (&server_conf[CNF_TAPETYPE]             , "EXABYTE");
+    conf_init_int      (&server_conf[CNF_DUMPCYCLE]            , 10);
+    conf_init_int      (&server_conf[CNF_RUNSPERCYCLE]         , 0);
+    conf_init_int      (&server_conf[CNF_TAPECYCLE]            , 15);
+    conf_init_int      (&server_conf[CNF_NETUSAGE]             , 300);
+    conf_init_int      (&server_conf[CNF_INPARALLEL]           , 10);
+    conf_init_string   (&server_conf[CNF_DUMPORDER]            , "ttt");
+    conf_init_int      (&server_conf[CNF_BUMPPERCENT]          , 0);
+    conf_init_am64     (&server_conf[CNF_BUMPSIZE]             , (off_t)10*1024);
+    conf_init_real     (&server_conf[CNF_BUMPMULT]             , 1.5);
+    conf_init_int      (&server_conf[CNF_BUMPDAYS]             , 2);
+    conf_init_string   (&server_conf[CNF_TPCHANGER]            , "");
+    conf_init_int      (&server_conf[CNF_RUNTAPES]             , 1);
+    conf_init_int      (&server_conf[CNF_MAXDUMPS]             , 1);
+    conf_init_time     (&server_conf[CNF_ETIMEOUT]             , (time_t)300);
+    conf_init_time     (&server_conf[CNF_DTIMEOUT]             , (time_t)1800);
+    conf_init_time     (&server_conf[CNF_CTIMEOUT]             , (time_t)30);
+    conf_init_int      (&server_conf[CNF_TAPEBUFS]             , 20);
+    conf_init_string   (&server_conf[CNF_RAWTAPEDEV]           , s);
+    conf_init_string   (&server_conf[CNF_PRINTER]              , "");
+    conf_init_bool     (&server_conf[CNF_AUTOFLUSH]            , 0);
+    conf_init_int      (&server_conf[CNF_RESERVE]              , 100);
+    conf_init_am64     (&server_conf[CNF_MAXDUMPSIZE]          , (off_t)-1);
+    conf_init_string   (&server_conf[CNF_COLUMNSPEC]           , "");
+    conf_init_bool     (&server_conf[CNF_AMRECOVER_DO_FSF]     , 1);
+    conf_init_string   (&server_conf[CNF_AMRECOVER_CHANGER]    , "");
+    conf_init_bool     (&server_conf[CNF_AMRECOVER_CHECK_LABEL], 1);
+    conf_init_taperalgo(&server_conf[CNF_TAPERALGO]            , 0);
+    conf_init_string   (&server_conf[CNF_DISPLAYUNIT]          , "k");
+    conf_init_string   (&server_conf[CNF_KRB5KEYTAB]           , "/.amanda-v5-keytab");
+    conf_init_string   (&server_conf[CNF_KRB5PRINCIPAL]        , "service/amanda");
+    conf_init_string   (&server_conf[CNF_LABEL_NEW_TAPES]      , "");
+    conf_init_bool     (&server_conf[CNF_USETIMESTAMPS]        , 0);
 
     /* defaults for internal variables */
 
-    seen_org = 0;
-    seen_mailto = 0;
-    seen_dumpuser = 0;
-    seen_tapedev = 0;
-    seen_rawtapedev = 0;
-    seen_printer = 0;
-    seen_tpchanger = 0;
-    seen_chngrdev = 0;
-    seen_chngrfile = 0;
-    seen_labelstr = 0;
-    seen_runtapes = 0;
-    seen_maxdumps = 0;
-    seen_tapelist = 0;
-    seen_infofile = 0;
-    seen_diskfile = 0;
-    seen_diskdir = 0;
-    seen_logdir = 0;
-    seen_bumppercent = 0;
-    seen_bumpsize = 0;
-    seen_bumpmult = 0;
-    seen_bumpdays = 0;
-    seen_tapetype = 0;
-    seen_dumpcycle = 0;
-    seen_runspercycle = 0;
-    seen_maxcycle = 0;
-    seen_tapecycle = 0;
-    seen_disksize = 0;
-    seen_netusage = 0;
-    seen_inparallel = 0;
-    seen_dumporder = 0;
-    seen_timeout = 0;
-    seen_indexdir = 0;
-    seen_etimeout = 0;
-    seen_dtimeout = 0;
-    seen_ctimeout = 0;
-    seen_tapebufs = 0;
-    seen_autoflush = 0;
-    seen_reserve = 0;
-    seen_maxdumpsize = 0;
-    seen_columnspec = 0;
-    seen_amrecover_do_fsf = 0;
-    seen_amrecover_check_label = 0;
-    seen_amrecover_changer = 0;
-    seen_taperalgo = 0;
-    seen_displayunit = 0;
-    seen_krb5keytab = 0;
-    seen_krb5principal = 0;
-    seen_label_new_tapes = 0;
-
-    line_num = got_parserror = 0;
+    conf_line_num = got_parserror = 0;
     allow_overwrites = 0;
     token_pushed = 0;
 
@@ -870,488 +888,238 @@ static void init_defaults()
 
     /* create some predefined dumptypes for backwards compatability */
     init_dumptype_defaults();
-    dpcur.name = "NO-COMPRESS"; dpcur.seen = -1;
-    dpcur.compress = COMP_NONE; dpcur.s_compress = -1;
+    dpcur.name = stralloc("NO-COMPRESS");
+    dpcur.seen = -1;
+    conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_NONE);
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "COMPRESS-FAST"; dpcur.seen = -1;
-    dpcur.compress = COMP_FAST; dpcur.s_compress = -1;
+    dpcur.name = stralloc("COMPRESS-FAST");
+    dpcur.seen = -1;
+    conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_FAST);
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "COMPRESS-BEST"; dpcur.seen = -1;
-    dpcur.compress = COMP_BEST; dpcur.s_compress = -1;
+    dpcur.name = stralloc("COMPRESS-BEST");
+    dpcur.seen = -1;
+    conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_BEST);
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "COMPRESS-CUST"; dpcur.seen = -1;
-    dpcur.compress = COMP_CUST; dpcur.s_compress = -1;
+    dpcur.name = stralloc("COMPRESS-CUST");
+    dpcur.seen = -1;
+    conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_CUST);
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "SRVCOMPRESS"; dpcur.seen = -1;
-    dpcur.compress = COMP_SERV_FAST; dpcur.s_compress = -1;
+    dpcur.name = stralloc("SRVCOMPRESS");
+    dpcur.seen = -1;
+    conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_SERV_FAST);
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "BSD-AUTH"; dpcur.seen = -1;
-    amfree(dpcur.security_driver);
-    dpcur.security_driver = stralloc("BSD"); dpcur.s_security_driver = -1;
+    dpcur.name = stralloc("BSD-AUTH");
+    dpcur.seen = -1;
+    conf_set_string(&dpcur.value[DUMPTYPE_SECURITY_DRIVER], "BSD");
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "KRB4-AUTH"; dpcur.seen = -1;
-    amfree(dpcur.security_driver);
-    dpcur.security_driver = stralloc("KRB4"); dpcur.s_security_driver = -1;
+    dpcur.name = stralloc("KRB4-AUTH");
+    dpcur.seen = -1;
+    conf_set_string(&dpcur.value[DUMPTYPE_SECURITY_DRIVER], "KRB4");
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "NO-RECORD"; dpcur.seen = -1;
-    dpcur.record = 0; dpcur.s_record = -1;
+    dpcur.name = stralloc("NO-RECORD");
+    dpcur.seen = -1;
+    conf_set_bool(&dpcur.value[DUMPTYPE_RECORD], 0);
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "NO-HOLD"; dpcur.seen = -1;
-    dpcur.no_hold = 1; dpcur.s_no_hold = -1;
+    dpcur.name = stralloc("NO-HOLD");
+    dpcur.seen = -1;
+    conf_set_holding(&dpcur.value[DUMPTYPE_HOLDINGDISK], HOLD_NEVER);
     save_dumptype();
 
     init_dumptype_defaults();
-    dpcur.name = "NO-FULL"; dpcur.seen = -1;
-    dpcur.strategy = DS_NOFULL; dpcur.s_strategy = -1;
+    dpcur.name = stralloc("NO-FULL");
+    dpcur.seen = -1;
+    conf_set_strategy(&dpcur.value[DUMPTYPE_STRATEGY], DS_NOFULL);
     save_dumptype();
 }
 
-static void read_conffile_recursively(filename)
-char *filename;
+static void
+read_conffile_recursively(
+    char *filename)
 {
-    extern int errno;
-
     /* Save globals used in read_confline(), elsewhere. */
-    int  save_line_num  = line_num;
-    FILE *save_conf     = conf;
-    char *save_confname = confname;
+    int  save_line_num  = conf_line_num;
+    FILE *save_conf     = conf_conf;
+    char *save_confname = conf_confname;
+    int        rc;
 
     if (*filename == '/' || config_dir == NULL) {
-       confname = stralloc(filename);
+       conf_confname = stralloc(filename);
     } else {
-       confname = stralloc2(config_dir, filename);
+       conf_confname = stralloc2(config_dir, filename);
     }
 
-    if((conf = fopen(confname, "r")) == NULL) {
-       fprintf(stderr, "could not open conf file \"%s\": %s\n", confname,
+    if((conf_conf = fopen(conf_confname, "r")) == NULL) {
+       fprintf(stderr, "could not open conf file \"%s\": %s\n", conf_confname,
                strerror(errno));
-       amfree(confname);
+       amfree(conf_confname);
        got_parserror = -1;
        return;
     }
 
-    line_num = 0;
+    conf_line_num = 0;
 
     /* read_confline() can invoke us recursively via "includefile" */
-    while(read_confline());
-    afclose(conf);
+    do {
+       rc = read_confline();
+    } while (rc != 0);
+    afclose(conf_conf);
 
-    amfree(confname);
+    amfree(conf_confname);
 
-    /* Restore globals */
-    line_num = save_line_num;
-    conf     = save_conf;
-    confname = save_confname;
+    /* Restore servers */
+    conf_line_num = save_line_num;
+    conf_conf     = save_conf;
+    conf_confname = save_confname;
 }
 
 
 /* ------------------------ */
 
 
-keytab_t main_keytable[] = {
-    { "BUMPDAYS", BUMPDAYS },
-    { "BUMPMULT", BUMPMULT },
-    { "BUMPSIZE", BUMPSIZE },
-    { "BUMPPERCENT", BUMPPERCENT },
-    { "DEFINE", DEFINE },
-    { "DISKDIR", DISKDIR },    /* XXX - historical */
-    { "DISKFILE", DISKFILE },
-    { "DISKSIZE", DISKSIZE },  /* XXX - historical */
-    { "DUMPCYCLE", DUMPCYCLE },
-    { "RUNSPERCYCLE", RUNSPERCYCLE },
-    { "DUMPTYPE", DUMPTYPE },
-    { "DUMPUSER", DUMPUSER },
-    { "PRINTER", PRINTER },
-    { "HOLDINGDISK", HOLDING },
-    { "INCLUDEFILE", INCLUDEFILE },
-    { "INDEXDIR", INDEXDIR },
-    { "INFOFILE", INFOFILE },
-    { "INPARALLEL", INPARALLEL },
-    { "DUMPORDER", DUMPORDER },
-    { "INTERFACE", INTERFACE },
-    { "LABELSTR", LABELSTR },
-    { "LOGDIR", LOGDIR },
-    { "LOGFILE", LOGFILE },    /* XXX - historical */
-    { "MAILTO", MAILTO },
-    { "MAXCYCLE", MAXCYCLE },  /* XXX - historical */
-    { "MAXDUMPS", MAXDUMPS },
-    { "MINCYCLE", DUMPCYCLE }, /* XXX - historical */
-    { "NETUSAGE", NETUSAGE },  /* XXX - historical */
-    { "ORG", ORG },
-    { "RUNTAPES", RUNTAPES },
-    { "TAPECYCLE", TAPECYCLE },
-    { "TAPEDEV", TAPEDEV },
-    { "TAPELIST", TAPELIST },
-    { "TAPETYPE", TAPETYPE },
-    { "TIMEOUT", TIMEOUT },    /* XXX - historical */
-    { "TPCHANGER", TPCHANGER },
-    { "CHANGERDEV", CHNGRDEV },
-    { "CHANGERFILE", CHNGRFILE },
-    { "ETIMEOUT", ETIMEOUT },
-    { "DTIMEOUT", DTIMEOUT },
-    { "CTIMEOUT", CTIMEOUT },
-    { "TAPEBUFS", TAPEBUFS },
-    { "RAWTAPEDEV", RAWTAPEDEV },
-    { "AUTOFLUSH", AUTOFLUSH },
-    { "RESERVE", RESERVE },
-    { "MAXDUMPSIZE", MAXDUMPSIZE },
-    { "COLUMNSPEC", COLUMNSPEC },
-    { "AMRECOVER_DO_FSF", AMRECOVER_DO_FSF },
-    { "AMRECOVER_CHECK_LABEL", AMRECOVER_CHECK_LABEL },
-    { "AMRECOVER_CHANGER", AMRECOVER_CHANGER },
-    { "TAPERALGO", TAPERALGO },
-    { "DISPLAYUNIT", DISPLAYUNIT },
-    { "KRB5KEYTAB", KRB5KEYTAB },
-    { "KRB5PRINCIPAL", KRB5PRINCIPAL },
-    { "LABEL_NEW_TAPES", LABEL_NEW_TAPES },
-    { NULL, IDENT }
-};
-
-static int read_confline()
+static int
+read_confline(
+    void)
 {
-    keytable = main_keytable;
+    t_conf_var *np;
 
-    line_num += 1;
-    get_conftoken(ANY);
+    keytable = server_keytab;
+
+    conf_line_num += 1;
+    get_conftoken(CONF_ANY);
     switch(tok) {
-    case INCLUDEFILE:
+    case CONF_INCLUDEFILE:
        {
            char *fn;
+           char *cname;
 
-           get_conftoken(STRING);
-           fn = tokenval.s;
-           read_conffile_recursively(fn);
-       }
-       break;
-
-    case ORG:       get_simple(&conf_org,       &seen_org,       STRING); break;
-    case MAILTO:    get_simple(&conf_mailto,    &seen_mailto,    STRING); break;
-    case DUMPUSER:  get_simple(&conf_dumpuser,  &seen_dumpuser,  STRING); break;
-    case PRINTER:   get_simple(&conf_printer,   &seen_printer,   STRING); break;
-    case DUMPCYCLE: get_simple(&conf_dumpcycle, &seen_dumpcycle, INT);
-                   if(conf_dumpcycle.i < 0) {
-                       parserror("dumpcycle must be positive");
-                   }
-                   break;
-    case RUNSPERCYCLE: get_simple(&conf_runspercycle, &seen_runspercycle, INT);
-                   if(conf_runspercycle.i < -1) {
-                       parserror("runspercycle must be >= -1");
-                   }
-                   break;
-    case MAXCYCLE:  get_simple(&conf_maxcycle,  &seen_maxcycle,  INT);    break;
-    case TAPECYCLE: get_simple(&conf_tapecycle, &seen_tapecycle, INT);
-                   if(conf_tapecycle.i < 1) {
-                       parserror("tapecycle must be positive");
-                   }
-                   break;
-    case RUNTAPES:  get_simple(&conf_runtapes,  &seen_runtapes,  INT);
-                   if(conf_runtapes.i < 0) {
-                       parserror("runtapes must be positive");
-                   }
-                   break;
-    case TAPEDEV:   get_simple(&conf_tapedev,   &seen_tapedev,   STRING); break;
-    case RAWTAPEDEV:get_simple(&conf_rawtapedev,&seen_rawtapedev,STRING); break;
-    case TPCHANGER: get_simple(&conf_tpchanger, &seen_tpchanger, STRING); break;
-    case CHNGRDEV:  get_simple(&conf_chngrdev,  &seen_chngrdev,  STRING); break;
-    case CHNGRFILE: get_simple(&conf_chngrfile, &seen_chngrfile, STRING); break;
-    case LABELSTR:  get_simple(&conf_labelstr,  &seen_labelstr,  STRING); break;
-    case TAPELIST:  get_simple(&conf_tapelist,  &seen_tapelist,  STRING); break;
-    case INFOFILE:  get_simple(&conf_infofile,  &seen_infofile,  STRING); break;
-    case LOGDIR:    get_simple(&conf_logdir,    &seen_logdir,    STRING); break;
-    case DISKFILE:  get_simple(&conf_diskfile,  &seen_diskfile,  STRING); break;
-    case BUMPMULT:  get_simple(&conf_bumpmult,  &seen_bumpmult,  REAL);
-                   if(conf_bumpmult.r < 0.999) {
-                       parserror("bumpmult must be positive");
-                   }
-                   break;
-    case BUMPPERCENT:  get_simple(&conf_bumppercent,  &seen_bumppercent,  INT);
-                   if(conf_bumppercent.i < 0 || conf_bumppercent.i > 100) {
-                       parserror("bumppercent must be between 0 and 100");
-                   }
-                   break;
-    case BUMPSIZE:  get_simple(&conf_bumpsize,  &seen_bumpsize,  INT);
-                   if(conf_bumpsize.i < 1) {
-                       parserror("bumpsize must be positive");
-                   }
-                   break;
-    case BUMPDAYS:  get_simple(&conf_bumpdays,  &seen_bumpdays,  INT);
-                   if(conf_bumpdays.i < 1) {
-                       parserror("bumpdays must be positive");
-                   }
-                   break;
-    case NETUSAGE:  get_simple(&conf_netusage,  &seen_netusage,  INT);
-                   if(conf_netusage.i < 1) {
-                       parserror("netusage must be positive");
-                   }
-                   break;
-    case INPARALLEL:get_simple(&conf_inparallel,&seen_inparallel,INT);
-                   if(conf_inparallel.i < 1 || conf_inparallel.i >MAX_DUMPERS){
-                       parserror(
-                           "inparallel must be between 1 and MAX_DUMPERS (%d)",
-                           MAX_DUMPERS);
-                   }
-                   break;
-    case DUMPORDER: get_simple(&conf_dumporder, &seen_dumporder, STRING); break;
-    case TIMEOUT:   get_simple(&conf_timeout,   &seen_timeout,   INT);    break;
-    case MAXDUMPS:  get_simple(&conf_maxdumps,  &seen_maxdumps,  INT);
-                   if(conf_maxdumps.i < 1) {
-                       parserror("maxdumps must be positive");
-                   }
-                   break;
-    case TAPETYPE:  get_simple(&conf_tapetype,  &seen_tapetype,  IDENT);  break;
-    case INDEXDIR:  get_simple(&conf_indexdir,  &seen_indexdir,  STRING); break;
-    case ETIMEOUT:  get_simple(&conf_etimeout,  &seen_etimeout,  INT);    break;
-    case DTIMEOUT:  get_simple(&conf_dtimeout,  &seen_dtimeout,  INT);
-                   if(conf_dtimeout.i < 1) {
-                       parserror("dtimeout must be positive");
-                   }
-                   break;
-    case CTIMEOUT:  get_simple(&conf_ctimeout,  &seen_ctimeout,  INT);
-                   if(conf_ctimeout.i < 1) {
-                       parserror("ctimeout must be positive");
-                   }
-                   break;
-    case TAPEBUFS:  get_simple(&conf_tapebufs,  &seen_tapebufs,  INT);
-                   if(conf_tapebufs.i < 1) {
-                       parserror("tapebufs must be positive");
-                   }
-                   break;
-    case AUTOFLUSH: get_simple(&conf_autoflush, &seen_autoflush, BOOL);   break;
-    case RESERVE:   get_simple(&conf_reserve,   &seen_reserve,  INT);
-                   if(conf_reserve.i < 0 || conf_reserve.i > 100) {
-                       parserror("reserve must be between 0 and 100");
-                   }
-                   break;
-    case MAXDUMPSIZE:get_simple(&conf_maxdumpsize,&seen_maxdumpsize,AM64); break;
-    case COLUMNSPEC:get_simple(&conf_columnspec,&seen_columnspec,STRING); break;
-
-    case AMRECOVER_DO_FSF: get_simple(&conf_amrecover_do_fsf,&seen_amrecover_do_fsf, BOOL); break;
-    case AMRECOVER_CHECK_LABEL: get_simple(&conf_amrecover_check_label,&seen_amrecover_check_label, BOOL); break;
-    case AMRECOVER_CHANGER: get_simple(&conf_amrecover_changer,&seen_amrecover_changer, STRING); break;
-
-    case TAPERALGO: get_taperalgo(&conf_taperalgo,&seen_taperalgo); break;
-    case DISPLAYUNIT: get_simple(&conf_displayunit,&seen_displayunit, STRING);
-                     if(strcmp(conf_displayunit.s,"k") == 0 ||
-                        strcmp(conf_displayunit.s,"K") == 0) {
-                         conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
-                         unit_divisor=1;
-                     }
-                     else if(strcmp(conf_displayunit.s,"m") == 0 ||
-                        strcmp(conf_displayunit.s,"M") == 0) {
-                         conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
-                         unit_divisor=1024;
-                     }
-                     else if(strcmp(conf_displayunit.s,"g") == 0 ||
-                        strcmp(conf_displayunit.s,"G") == 0) {
-                         conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
-                         unit_divisor=1024*1024;
-                     }
-                     else if(strcmp(conf_displayunit.s,"t") == 0 ||
-                        strcmp(conf_displayunit.s,"T") == 0) {
-                         conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
-                         unit_divisor=1024*1024*1024;
-                     }
-                     else {
-                         parserror("displayunit must be k,m,g or t.");
-                     }
-                     break;
-
-    /* kerberos 5 bits.  only useful when kerberos 5 built in... */
-    case KRB5KEYTAB:    get_simple(&conf_krb5keytab,   &seen_krb5keytab,   STRING); break;
-    case KRB5PRINCIPAL: get_simple(&conf_krb5principal,&seen_krb5principal,STRING); break;
-
-    case LOGFILE: /* XXX - historical */
-       /* truncate the filename part and pretend he said "logdir" */
-       {
-           char *p;
-
-           get_simple(&conf_logdir, &seen_logdir, STRING);
-
-           p = strrchr(conf_logdir.s, '/');
-           if (p != (char *)0) *p = '\0';
-       }
-       break;
-
-    case DISKDIR:
-       {
-           char *s;
-
-           get_conftoken(STRING);
-           s = tokenval.s;
-
-           if(!seen_diskdir) {
-               conf_diskdir.s = newstralloc(conf_diskdir.s, s);
-               seen_diskdir = line_num;
+           get_conftoken(CONF_STRING);
+           fn = tokenval.v.s;
+           if (*fn == '/' || config_dir == NULL) {
+               cname = stralloc(fn);
+           } else {
+               cname = stralloc2(config_dir, fn);
            }
-
-           init_holdingdisk_defaults();
-           hdcur.name = "default from DISKDIR";
-           hdcur.seen = line_num;
-           hdcur.diskdir = stralloc(s);
-           hdcur.s_disk = line_num;
-           hdcur.disksize = conf_disksize.i;
-           hdcur.s_size = seen_disksize;
-           save_holdingdisk();
-       }
-       break;
-
-    case DISKSIZE:
-       {
-           int i;
-
-           i = get_int();
-           i = (i / DISK_BLOCK_KB) * DISK_BLOCK_KB;
-
-           if(!seen_disksize) {
-               conf_disksize.i = i;
-               seen_disksize = line_num;
+           if ( cname != NULL &&  (access(cname, R_OK) == 0)) {
+               read_conffile_recursively(cname);
+               amfree(cname);
+           } else {
+               conf_parserror("cannot open %s: %s\n", fn, strerror(errno));
            }
-
-           if(holdingdisks != NULL)
-               holdingdisks->disksize = i;
+           amfree(cname);
+           
        }
-
        break;
 
-    case HOLDING:
+    case CONF_HOLDING:
        get_holdingdisk();
        break;
 
-    case DEFINE:
-       get_conftoken(ANY);
-       if(tok == DUMPTYPE) get_dumptype();
-       else if(tok == TAPETYPE) get_tapetype();
-       else if(tok == INTERFACE) get_interface();
-       else parserror("DUMPTYPE, INTERFACE or TAPETYPE expected");
+    case CONF_DEFINE:
+       get_conftoken(CONF_ANY);
+       if(tok == CONF_DUMPTYPE) get_dumptype();
+       else if(tok == CONF_TAPETYPE) get_tapetype();
+       else if(tok == CONF_INTERFACE) get_interface();
+       else conf_parserror("DUMPTYPE, INTERFACE or TAPETYPE expected");
        break;
-    case LABEL_NEW_TAPES:
-        get_simple(&conf_label_new_tapes, &seen_label_new_tapes, STRING);
-        break;
 
-    case NL:   /* empty line */
+    case CONF_NL:      /* empty line */
        break;
-    case END:  /* end of file */
+
+    case CONF_END:     /* end of file */
        return 0;
+
     default:
-       parserror("configuration keyword expected");
+       {
+           for(np = server_var; np->token != CONF_UNKNOWN; np++) 
+               if(np->token == tok) break;
+
+           if(np->token == CONF_UNKNOWN) {
+               conf_parserror("configuration keyword expected");
+           } else {
+               np->read_function(np, &server_conf[np->parm]);
+               if(np->validate)
+                   np->validate(np, &server_conf[np->parm]);
+           }
+       }
     }
-    if(tok != NL) get_conftoken(NL);
+    if(tok != CONF_NL)
+       get_conftoken(CONF_NL);
     return 1;
 }
 
-keytab_t holding_keytable[] = {
-    { "DIRECTORY", DIRECTORY },
-    { "COMMENT", COMMENT },
-    { "USE", USE },
-    { "CHUNKSIZE", CHUNKSIZE },
-    { NULL, IDENT }
+t_conf_var holding_var [] = {
+   { CONF_DIRECTORY, CONFTYPE_STRING, read_string, HOLDING_DISKDIR  , NULL },
+   { CONF_COMMENT  , CONFTYPE_STRING, read_string, HOLDING_COMMENT  , NULL },
+   { CONF_USE      , CONFTYPE_AM64  , read_am64  , HOLDING_DISKSIZE , validate_use },
+   { CONF_CHUNKSIZE, CONFTYPE_AM64  , read_am64  , HOLDING_CHUNKSIZE, validate_chunksize },
+   { CONF_UNKNOWN  , CONFTYPE_INT   , NULL       , HOLDING_HOLDING  , NULL }
 };
 
-static void get_holdingdisk()
+static void
+get_holdingdisk(
+    void)
 {
-    int done;
+    char *prefix;
     int save_overwrites;
-    keytab_t *save_kt;
 
     save_overwrites = allow_overwrites;
     allow_overwrites = 1;
 
-    save_kt = keytable;
-    keytable = holding_keytable;
-
     init_holdingdisk_defaults();
 
-    get_conftoken(IDENT);
-    hdcur.name = stralloc(tokenval.s);
-    malloc_mark(hdcur.name);
-    hdcur.seen = line_num;
+    get_conftoken(CONF_IDENT);
+    hdcur.name = stralloc(tokenval.v.s);
+    hdcur.seen = conf_line_num;
 
-    get_conftoken(LBRACE);
-    get_conftoken(NL);
-
-    done = 0;
-    do {
-       line_num += 1;
-       get_conftoken(ANY);
-       switch(tok) {
-
-       case COMMENT:
-           get_simple((val_t *)&hdcur.comment, &hdcur.s_comment, STRING);
-           break;
-       case DIRECTORY:
-           get_simple((val_t *)&hdcur.diskdir, &hdcur.s_disk, STRING);
-           break;
-       case USE:
-           get_simple((val_t *)&hdcur.disksize, &hdcur.s_size, LONG);
-           hdcur.disksize = am_floor(hdcur.disksize, DISK_BLOCK_KB);
-           break;
-       case CHUNKSIZE:
-           get_simple((val_t *)&hdcur.chunksize, &hdcur.s_csize, LONG);
-           if(hdcur.chunksize == 0) {
-               hdcur.chunksize =  ((INT_MAX / 1024) - (2 * DISK_BLOCK_KB));
-           } else if(hdcur.chunksize < 0) {
-               parserror("Negative chunksize (%ld) is no longer supported",
-                         hdcur.chunksize);
-           }
-           hdcur.chunksize = am_floor(hdcur.chunksize, DISK_BLOCK_KB);
-           break;
-       case RBRACE:
-           done = 1;
-           break;
-       case NL:        /* empty line */
-           break;
-       case END:       /* end of file */
-           done = 1;
-       default:
-           parserror("holding disk parameter expected");
-       }
-       if(tok != NL && tok != END) get_conftoken(NL);
-    } while(!done);
+    prefix = vstralloc( "HOLDINGDISK:", hdcur.name, ":", NULL);
+    read_block(server_options, holding_var, server_keytab, hdcur.value, prefix,
+              "holding disk parameter expected", 1, NULL);
+    amfree(prefix);
+    get_conftoken(CONF_NL);
 
+    hdcur.disksize = holdingdisk_get_disksize(&hdcur);
     save_holdingdisk();
 
     allow_overwrites = save_overwrites;
-    keytable = save_kt;
 }
 
-static void init_holdingdisk_defaults()
+static void
+init_holdingdisk_defaults(
+    void)
 {
-    hdcur.comment = stralloc("");
-    hdcur.diskdir = stralloc(conf_diskdir.s);
-    malloc_mark(hdcur.diskdir);
-    hdcur.disksize = 0;
-    hdcur.chunksize = 1024*1024/**1024*/; /* 1 Gb = 1M counted in 1Kb blocks */
-
-    hdcur.s_comment = 0;
-    hdcur.s_disk = 0;
-    hdcur.s_size = 0;
-    hdcur.s_csize = 0;
+    conf_init_string(&hdcur.value[HOLDING_COMMENT]  , "");
+    conf_init_string(&hdcur.value[HOLDING_DISKDIR]  , "");
+    conf_init_am64(&hdcur.value[HOLDING_DISKSIZE] , (off_t)0);
+                    /* 1 Gb = 1M counted in 1Kb blocks */
+    conf_init_am64(&hdcur.value[HOLDING_CHUNKSIZE], (off_t)1024*1024);
 
     hdcur.up = (void *)0;
+    hdcur.disksize = 0LL;
 }
 
-static void save_holdingdisk()
+static void
+save_holdingdisk(
+    void)
 {
     holdingdisk_t *hp;
 
     hp = alloc(sizeof(holdingdisk_t));
-    malloc_mark(hp);
     *hp = hdcur;
     hp->next = holdingdisks;
     holdingdisks = hp;
@@ -1360,902 +1128,467 @@ static void save_holdingdisk()
 }
 
 
-keytab_t dumptype_keytable[] = {
-    { "AUTH", AUTH },
-    { "BUMPDAYS", BUMPDAYS },
-    { "BUMPMULT", BUMPMULT },
-    { "BUMPSIZE", BUMPSIZE },
-    { "BUMPPERCENT", BUMPPERCENT },
-    { "COMMENT", COMMENT },
-    { "COMPRATE", COMPRATE },
-    { "COMPRESS", COMPRESS },
-    { "ENCRYPT", ENCRYPT },
-    { "SERVER_DECRYPT_OPTION", SRV_DECRYPT_OPT },
-    { "CLIENT_DECRYPT_OPTION", CLNT_DECRYPT_OPT },
-    { "DUMPCYCLE", DUMPCYCLE },
-    { "EXCLUDE", EXCLUDE },
-    { "FREQUENCY", FREQUENCY },        /* XXX - historical */
-    { "HOLDINGDISK", HOLDING },
-    { "IGNORE", IGNORE },
-    { "INCLUDE", INCLUDE },
-    { "INDEX", INDEX },
-    { "KENCRYPT", KENCRYPT },
-    { "MAXCYCLE", MAXCYCLE },  /* XXX - historical */
-    { "MAXDUMPS", MAXDUMPS },
-    { "MAXPROMOTEDAY", MAXPROMOTEDAY },
-    { "OPTIONS", OPTIONS },    /* XXX - historical */
-    { "PRIORITY", PRIORITY },
-    { "PROGRAM", PROGRAM },
-    { "RECORD", RECORD },
-    { "SKIP-FULL", SKIP_FULL },
-    { "SKIP-INCR", SKIP_INCR },
-    { "STARTTIME", STARTTIME },
-    { "STRATEGY", STRATEGY },
-    { "TAPE_SPLITSIZE", TAPE_SPLITSIZE },
-    { "SPLIT_DISKBUFFER", SPLIT_DISKBUFFER },
-    { "FALLBACK_SPLITSIZE", FALLBACK_SPLITSIZE },
-    { "ESTIMATE", ESTIMATE },
-    { "SERVER_CUSTOM_COMPRESS", SRVCOMPPROG },
-    { "CLIENT_CUSTOM_COMPRESS", CLNTCOMPPROG },
-    { "SERVER_ENCRYPT", SRV_ENCRYPT },
-    { "CLIENT_ENCRYPT", CLNT_ENCRYPT },
-    { NULL, IDENT }
+t_conf_var dumptype_var [] = {
+   { CONF_COMMENT           , CONFTYPE_STRING   , read_string , DUMPTYPE_COMMENT           , NULL },
+   { CONF_AUTH              , CONFTYPE_STRING   , read_string , DUMPTYPE_SECURITY_DRIVER   , NULL },
+   { CONF_BUMPDAYS          , CONFTYPE_INT      , read_int    , DUMPTYPE_BUMPDAYS          , NULL },
+   { CONF_BUMPMULT          , CONFTYPE_REAL     , read_real   , DUMPTYPE_BUMPMULT          , NULL },
+   { CONF_BUMPSIZE          , CONFTYPE_AM64     , read_am64   , DUMPTYPE_BUMPSIZE          , NULL },
+   { CONF_BUMPPERCENT       , CONFTYPE_INT      , read_int    , DUMPTYPE_BUMPPERCENT       , NULL },
+   { CONF_COMPRATE          , CONFTYPE_REAL     , get_comprate, DUMPTYPE_COMPRATE          , NULL },
+   { CONF_COMPRESS          , CONFTYPE_INT      , get_compress, DUMPTYPE_COMPRESS          , NULL },
+   { CONF_ENCRYPT           , CONFTYPE_INT      , get_encrypt , DUMPTYPE_ENCRYPT           , NULL },
+   { CONF_DUMPCYCLE         , CONFTYPE_INT      , read_int    , DUMPTYPE_DUMPCYCLE         , validate_positive0 },
+   { CONF_EXCLUDE           , CONFTYPE_EXINCLUDE, get_exclude , DUMPTYPE_EXCLUDE           , NULL },
+   { CONF_INCLUDE           , CONFTYPE_EXINCLUDE, get_exclude , DUMPTYPE_INCLUDE           , NULL },
+   { CONF_IGNORE            , CONFTYPE_BOOL     , read_bool   , DUMPTYPE_IGNORE            , NULL },
+   { CONF_HOLDING           , CONFTYPE_HOLDING  , get_holding , DUMPTYPE_HOLDINGDISK       , NULL },
+   { CONF_INDEX             , CONFTYPE_BOOL     , read_bool   , DUMPTYPE_INDEX             , NULL },
+   { CONF_KENCRYPT          , CONFTYPE_BOOL     , read_bool   , DUMPTYPE_KENCRYPT          , NULL },
+   { CONF_MAXDUMPS          , CONFTYPE_INT      , read_int    , DUMPTYPE_MAXDUMPS          , validate_positive1 },
+   { CONF_MAXPROMOTEDAY     , CONFTYPE_INT      , read_int    , DUMPTYPE_MAXPROMOTEDAY     , validate_positive0 },
+   { CONF_PRIORITY          , CONFTYPE_PRIORITY , get_priority, DUMPTYPE_PRIORITY          , NULL },
+   { CONF_PROGRAM           , CONFTYPE_STRING   , read_string , DUMPTYPE_PROGRAM           , NULL },
+   { CONF_RECORD            , CONFTYPE_BOOL     , read_bool   , DUMPTYPE_RECORD            , NULL },
+   { CONF_SKIP_FULL         , CONFTYPE_BOOL     , read_bool   , DUMPTYPE_SKIP_FULL         , NULL },
+   { CONF_SKIP_INCR         , CONFTYPE_BOOL     , read_bool   , DUMPTYPE_SKIP_INCR         , NULL },
+   { CONF_STARTTIME         , CONFTYPE_TIME     , read_time   , DUMPTYPE_START_T           , NULL },
+   { CONF_STRATEGY          , CONFTYPE_INT      , get_strategy, DUMPTYPE_STRATEGY          , NULL },
+   { CONF_TAPE_SPLITSIZE    , CONFTYPE_AM64     , read_am64   , DUMPTYPE_TAPE_SPLITSIZE    , validate_positive0 },
+   { CONF_SPLIT_DISKBUFFER  , CONFTYPE_STRING   , read_string , DUMPTYPE_SPLIT_DISKBUFFER  , NULL },
+   { CONF_ESTIMATE          , CONFTYPE_INT      , get_estimate, DUMPTYPE_ESTIMATE          , NULL },
+   { CONF_SRV_ENCRYPT       , CONFTYPE_STRING   , read_string , DUMPTYPE_SRV_ENCRYPT       , NULL },
+   { CONF_CLNT_ENCRYPT      , CONFTYPE_STRING   , read_string , DUMPTYPE_CLNT_ENCRYPT      , NULL },
+   { CONF_AMANDAD_PATH      , CONFTYPE_STRING   , read_string , DUMPTYPE_AMANDAD_PATH      , NULL },
+   { CONF_CLIENT_USERNAME   , CONFTYPE_STRING   , read_string , DUMPTYPE_CLIENT_USERNAME   , NULL },
+   { CONF_SSH_KEYS          , CONFTYPE_STRING   , read_string , DUMPTYPE_SSH_KEYS          , NULL },
+   { CONF_SRVCOMPPROG       , CONFTYPE_STRING   , read_string , DUMPTYPE_SRVCOMPPROG       , NULL },
+   { CONF_CLNTCOMPPROG      , CONFTYPE_STRING   , read_string , DUMPTYPE_CLNTCOMPPROG      , NULL },
+   { CONF_FALLBACK_SPLITSIZE, CONFTYPE_AM64     , read_am64   , DUMPTYPE_FALLBACK_SPLITSIZE, NULL },
+   { CONF_SRV_DECRYPT_OPT   , CONFTYPE_STRING   , read_string , DUMPTYPE_SRV_DECRYPT_OPT   , NULL },
+   { CONF_CLNT_DECRYPT_OPT  , CONFTYPE_STRING   , read_string , DUMPTYPE_CLNT_DECRYPT_OPT  , NULL },
+   { CONF_UNKNOWN           , CONFTYPE_INT      , NULL        , DUMPTYPE_DUMPTYPE          , NULL }
 };
 
-dumptype_t *read_dumptype(name, from, fname, linenum)
-     char *name;
-     FILE *from;
-     char *fname;
-     int *linenum;
+dumptype_t *
+read_dumptype(
+    char *name,
+    FILE *from,
+    char *fname,
+    int *linenum)
 {
-    int done;
     int save_overwrites;
-    keytab_t *save_kt;
-    val_t tmpval;
     FILE *saved_conf = NULL;
     char *saved_fname = NULL;
+    char *prefix;
 
     if (from) {
-       saved_conf = conf;
-       conf = from;
+       saved_conf = conf_conf;
+       conf_conf = from;
     }
 
     if (fname) {
-       saved_fname = confname;
-       confname = fname;
+       saved_fname = conf_confname;
+       conf_confname = fname;
     }
 
     if (linenum)
-       line_num = *linenum;
+       conf_line_num = *linenum;
 
     save_overwrites = allow_overwrites;
     allow_overwrites = 1;
 
-    save_kt = keytable;
-    keytable = dumptype_keytable;
-
     init_dumptype_defaults();
-
     if (name) {
        dpcur.name = name;
     } else {
-       get_conftoken(IDENT);
-       dpcur.name = stralloc(tokenval.s);
-       malloc_mark(dpcur.name);
+       get_conftoken(CONF_IDENT);
+       dpcur.name = stralloc(tokenval.v.s);
     }
+    dpcur.seen = conf_line_num;
 
-    dpcur.seen = line_num;
+    prefix = vstralloc( "DUMPTYPE:", dpcur.name, ":", NULL);
+    read_block(server_options, dumptype_var, server_keytab, dpcur.value,
+              prefix, "dumptype parameter expected",
+              (name == NULL), *copy_dumptype);
+    amfree(prefix);
+    if(!name)
+       get_conftoken(CONF_NL);
 
-    if (! name) {
-       get_conftoken(LBRACE);
-       get_conftoken(NL);
-    }
+    /* XXX - there was a stupidity check in here for skip-incr and
+    ** skip-full.  This check should probably be somewhere else. */
 
-    done = 0;
-    do {
-       line_num += 1;
-       get_conftoken(ANY);
-       switch(tok) {
-
-       case AUTH:
-           get_simple((val_t *)&dpcur.security_driver,
-               &dpcur.s_security_driver, STRING);
-           break;
-       case COMMENT:
-           get_simple((val_t *)&dpcur.comment, &dpcur.s_comment, STRING);
-           break;
-       case COMPRATE:
-           get_comprate();
-           break;
-       case COMPRESS:
-           get_compress();
-           break;
-       case ENCRYPT:
-           get_encrypt();
-           break;
-       case SRV_DECRYPT_OPT:
-           get_simple((val_t *)&dpcur.srv_decrypt_opt, &dpcur.s_srv_decrypt_opt, STRING);
-           break;
-       case CLNT_DECRYPT_OPT:
-           get_simple((val_t *)&dpcur.clnt_decrypt_opt, &dpcur.s_clnt_decrypt_opt, STRING);
-           break;
-       case DUMPCYCLE:
-           get_simple((val_t *)&dpcur.dumpcycle, &dpcur.s_dumpcycle, INT);
-           if(dpcur.dumpcycle < 0) {
-               parserror("dumpcycle must be positive");
-           }
-           break;
-       case EXCLUDE:
-           get_exclude();
-           break;
-       case FREQUENCY:
-           get_simple((val_t *)&dpcur.frequency, &dpcur.s_frequency, INT);
-           break;
-       case HOLDING:
-           get_simple(&tmpval, &dpcur.s_no_hold, BOOL);
-           dpcur.no_hold = (tmpval.i == 0);
-           break;
-       case IGNORE:
-           get_simple(&tmpval, &dpcur.s_ignore, BOOL);
-           dpcur.ignore = (tmpval.i != 0);
-           break;
-       case INCLUDE:
-           get_include();
-           break;
-       case INDEX:
-           get_simple(&tmpval, &dpcur.s_index, BOOL);
-           dpcur.index = (tmpval.i != 0);
-           break;
-       case KENCRYPT:
-           get_simple(&tmpval, &dpcur.s_kencrypt, BOOL);
-           dpcur.kencrypt = (tmpval.i != 0);
-           break;
-       case MAXCYCLE:
-           get_simple((val_t *)&conf_maxcycle, &dpcur.s_maxcycle, INT);
-           break;
-       case MAXDUMPS:
-           get_simple((val_t *)&dpcur.maxdumps, &dpcur.s_maxdumps, INT);
-           if(dpcur.maxdumps < 1) {
-               parserror("maxdumps must be positive");
-           }
-           break;
-       case MAXPROMOTEDAY:
-           get_simple((val_t *)&dpcur.maxpromoteday, &dpcur.s_maxpromoteday, INT);
-           if(dpcur.maxpromoteday < 0) {
-               parserror("dpcur.maxpromoteday must be >= 0");
-           }
-           break;
-       case BUMPPERCENT:
-           get_simple((val_t *)&dpcur.bumppercent,  &dpcur.s_bumppercent,  INT);
-           if(dpcur.bumppercent < 0 || dpcur.bumppercent > 100) {
-               parserror("bumppercent must be between 0 and 100");
-           }
-           break;
-       case BUMPSIZE:
-           get_simple((val_t *)&dpcur.bumpsize,  &dpcur.s_bumpsize,  INT);
-           if(dpcur.bumpsize < 1) {
-               parserror("bumpsize must be positive");
-           }
-           break;
-       case BUMPDAYS:
-           get_simple((val_t *)&dpcur.bumpdays,  &dpcur.s_bumpdays,  INT);
-           if(dpcur.bumpdays < 1) {
-               parserror("bumpdays must be positive");
-           }
-           break;
-       case BUMPMULT:
-           get_simple((val_t *)&dpcur.bumpmult,  &dpcur.s_bumpmult,  REAL);
-           if(dpcur.bumpmult < 0.999) {
-               parserror("bumpmult must be positive (%f)",dpcur.bumpmult);
-           }
-           break;
-       case OPTIONS:
-           get_dumpopts();
-           break;
-       case PRIORITY:
-           get_priority();
-           break;
-       case PROGRAM:
-           get_simple((val_t *)&dpcur.program, &dpcur.s_program, STRING);
-           break;
-       case RECORD:
-           get_simple(&tmpval, &dpcur.s_record, BOOL);
-           dpcur.record = (tmpval.i != 0);
-           break;
-       case SKIP_FULL:
-           get_simple(&tmpval, &dpcur.s_skip_full, BOOL);
-           dpcur.skip_full = (tmpval.i != 0);
-           break;
-       case SKIP_INCR:
-           get_simple(&tmpval, &dpcur.s_skip_incr, BOOL);
-           dpcur.skip_incr = (tmpval.i != 0);
-           break;
-       case STARTTIME:
-           get_simple((val_t *)&dpcur.start_t, &dpcur.s_start_t, TIME);
-           break;
-       case STRATEGY:
-           get_strategy();
-           break;
-       case ESTIMATE:
-           get_estimate();
-           break;
-       case IDENT:
-           copy_dumptype();
-           break;
-       case TAPE_SPLITSIZE:
-           get_simple((val_t *)&dpcur.tape_splitsize,  &dpcur.s_tape_splitsize,  INT);
-           if(dpcur.tape_splitsize < 0) {
-             parserror("tape_splitsize must be >= 0");
-           }
-           break;
-       case SPLIT_DISKBUFFER:
-           get_simple((val_t *)&dpcur.split_diskbuffer, &dpcur.s_split_diskbuffer, STRING);
-           break;
-       case FALLBACK_SPLITSIZE:
-           get_simple((val_t *)&dpcur.fallback_splitsize,  &dpcur.s_fallback_splitsize,  INT);
-           if(dpcur.fallback_splitsize < 0) {
-             parserror("fallback_splitsize must be >= 0");
-           }
-           break;
-       case SRVCOMPPROG:
-           get_simple((val_t *)&dpcur.srvcompprog, &dpcur.s_srvcompprog, STRING);
-           break;
-        case CLNTCOMPPROG:
-           get_simple((val_t *)&dpcur.clntcompprog, &dpcur.s_clntcompprog, STRING);
-           break;
-       case SRV_ENCRYPT:
-           get_simple((val_t *)&dpcur.srv_encrypt, &dpcur.s_srv_encrypt, STRING);
-           break;
-        case CLNT_ENCRYPT:
-           get_simple((val_t *)&dpcur.clnt_encrypt, &dpcur.s_clnt_encrypt, STRING);
-           break;
-       case RBRACE:
-           done = 1;
-           break;
-       case NL:        /* empty line */
-           break;
-       case END:       /* end of file */
-           done = 1;
-       default:
-           parserror("dump type parameter expected");
-       }
-       if(tok != NL && tok != END &&
-          /* When a name is specified, we shouldn't consume the NL
-             after the RBRACE.  */
-          (tok != RBRACE || name == 0))
-           get_conftoken(NL);
-    } while(!done);
-
-    /* XXX - there was a stupidity check in here for skip-incr and
-    ** skip-full.  This check should probably be somewhere else. */
-
-    save_dumptype();
+    save_dumptype();
 
     allow_overwrites = save_overwrites;
-    keytable = save_kt;
 
     if (linenum)
-       *linenum = line_num;
+       *linenum = conf_line_num;
 
     if (fname)
-       confname = saved_fname;
+       conf_confname = saved_fname;
 
     if (from)
-       conf = saved_conf;
+       conf_conf = saved_conf;
 
     return lookup_dumptype(dpcur.name);
 }
 
-static void get_dumptype()
+static void
+get_dumptype(void)
 {
     read_dumptype(NULL, NULL, NULL, NULL);
 }
 
-static void init_dumptype_defaults()
-{
-    dpcur.comment = stralloc("");
-    dpcur.program = stralloc("DUMP");
-    dpcur.srvcompprog = stralloc("");
-    dpcur.clntcompprog = stralloc("");
-    dpcur.srv_encrypt = stralloc("");
-    dpcur.clnt_encrypt = stralloc("");
-    dpcur.exclude_file = NULL;
-    dpcur.exclude_list = NULL;
-    dpcur.include_file = NULL;
-    dpcur.include_list = NULL;
-    dpcur.priority = 1;
-    dpcur.dumpcycle = conf_dumpcycle.i;
-    dpcur.maxcycle = conf_maxcycle.i;
-    dpcur.frequency = 1;
-    dpcur.maxdumps = conf_maxdumps.i;
-    dpcur.maxpromoteday = 10000;
-    dpcur.bumppercent = conf_bumppercent.i;
-    dpcur.bumpsize = conf_bumpsize.i;
-    dpcur.bumpdays = conf_bumpdays.i;
-    dpcur.bumpmult = conf_bumpmult.r;
-    dpcur.start_t = 0;
-    dpcur.security_driver = stralloc("BSD");
-
-    /* options */
-    dpcur.record = 1;
-    dpcur.strategy = DS_STANDARD;
-    dpcur.estimate = ES_CLIENT;
-    dpcur.compress = COMP_FAST;
-    dpcur.encrypt = ENCRYPT_NONE;
-    dpcur.srv_decrypt_opt = stralloc("-d");
-    dpcur.clnt_decrypt_opt = stralloc("-d");
-    dpcur.comprate[0] = dpcur.comprate[1] = 0.50;
-    dpcur.skip_incr = dpcur.skip_full = 0;
-    dpcur.no_hold = 0;
-    dpcur.kencrypt = 0;
-    dpcur.ignore = 0;
-    dpcur.index = 0;
-    dpcur.tape_splitsize = 0;
-    dpcur.split_diskbuffer = NULL;
-    dpcur.fallback_splitsize = 10 * 1024;
-
-    dpcur.s_comment = 0;
-    dpcur.s_program = 0;
-    dpcur.s_srvcompprog = 0;
-    dpcur.s_clntcompprog = 0;
-    dpcur.s_clnt_encrypt= 0;
-    dpcur.s_srv_encrypt= 0;
-
-    dpcur.s_exclude_file = 0;
-    dpcur.s_exclude_list = 0;
-    dpcur.s_include_file = 0;
-    dpcur.s_include_list = 0;
-    dpcur.s_priority = 0;
-    dpcur.s_dumpcycle = 0;
-    dpcur.s_maxcycle = 0;
-    dpcur.s_frequency = 0;
-    dpcur.s_maxdumps = 0;
-    dpcur.s_maxpromoteday = 0;
-    dpcur.s_bumppercent = 0;
-    dpcur.s_bumpsize = 0;
-    dpcur.s_bumpdays = 0;
-    dpcur.s_bumpmult = 0;
-    dpcur.s_start_t = 0;
-    dpcur.s_security_driver = 0;
-    dpcur.s_record = 0;
-    dpcur.s_strategy = 0;
-    dpcur.s_estimate = 0;
-    dpcur.s_compress = 0;
-    dpcur.s_encrypt = 0;
-    dpcur.s_srv_decrypt_opt = 0;
-    dpcur.s_clnt_decrypt_opt = 0;
-    dpcur.s_comprate = 0;
-    dpcur.s_skip_incr = 0;
-    dpcur.s_skip_full = 0;
-    dpcur.s_no_hold = 0;
-    dpcur.s_kencrypt = 0;
-    dpcur.s_ignore = 0;
-    dpcur.s_index = 0;
-    dpcur.s_tape_splitsize = 0;
-    dpcur.s_split_diskbuffer = 0;
-    dpcur.s_fallback_splitsize = 0;
-}
-
-static void save_dumptype()
+static void
+init_dumptype_defaults(void)
 {
-    dumptype_t *dp;
+    dpcur.name = NULL;
+    conf_init_string   (&dpcur.value[DUMPTYPE_COMMENT]           , "");
+    conf_init_string   (&dpcur.value[DUMPTYPE_PROGRAM]           , "DUMP");
+    conf_init_string   (&dpcur.value[DUMPTYPE_SRVCOMPPROG]       , "");
+    conf_init_string   (&dpcur.value[DUMPTYPE_CLNTCOMPPROG]      , "");
+    conf_init_string   (&dpcur.value[DUMPTYPE_SRV_ENCRYPT]       , "");
+    conf_init_string   (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT]      , "");
+    conf_init_string   (&dpcur.value[DUMPTYPE_AMANDAD_PATH]      , "X");
+    conf_init_string   (&dpcur.value[DUMPTYPE_CLIENT_USERNAME]   , "X");
+    conf_init_string   (&dpcur.value[DUMPTYPE_SSH_KEYS]          , "X");
+    conf_init_string   (&dpcur.value[DUMPTYPE_SECURITY_DRIVER]   , "BSD");
+    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]         , server_conf[CNF_DUMPCYCLE].v.i);
+    conf_init_int      (&dpcur.value[DUMPTYPE_MAXDUMPS]          , server_conf[CNF_MAXDUMPS].v.i);
+    conf_init_int      (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY]     , 10000);
+    conf_init_int      (&dpcur.value[DUMPTYPE_BUMPPERCENT]       , server_conf[CNF_BUMPPERCENT].v.i);
+    conf_init_am64     (&dpcur.value[DUMPTYPE_BUMPSIZE]          , server_conf[CNF_BUMPSIZE].v.am64);
+    conf_init_int      (&dpcur.value[DUMPTYPE_BUMPDAYS]          , server_conf[CNF_BUMPDAYS].v.i);
+    conf_init_real     (&dpcur.value[DUMPTYPE_BUMPMULT]          , server_conf[CNF_BUMPMULT].v.r);
+    conf_init_time     (&dpcur.value[DUMPTYPE_START_T]           , (time_t)0);
+    conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY]          , DS_STANDARD);
+    conf_init_estimate (&dpcur.value[DUMPTYPE_ESTIMATE]          , ES_CLIENT);
+    conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS]          , COMP_FAST);
+    conf_init_encrypt  (&dpcur.value[DUMPTYPE_ENCRYPT]           , ENCRYPT_NONE);
+    conf_init_string   (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT]   , "-d");
+    conf_init_string   (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT]  , "-d");
+    conf_init_rate     (&dpcur.value[DUMPTYPE_COMPRATE]          , 0.50, 0.50);
+    conf_init_am64     (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE]    , (off_t)0);
+    conf_init_am64     (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (off_t)10 * 1024);
+    conf_init_string   (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER]  , NULL);
+    conf_init_bool     (&dpcur.value[DUMPTYPE_RECORD]            , 1);
+    conf_init_bool     (&dpcur.value[DUMPTYPE_SKIP_INCR]         , 0);
+    conf_init_bool     (&dpcur.value[DUMPTYPE_SKIP_FULL]         , 0);
+    conf_init_holding  (&dpcur.value[DUMPTYPE_HOLDINGDISK]       , HOLD_AUTO);
+    conf_init_bool     (&dpcur.value[DUMPTYPE_KENCRYPT]          , 0);
+    conf_init_bool     (&dpcur.value[DUMPTYPE_IGNORE]            , 0);
+    conf_init_bool     (&dpcur.value[DUMPTYPE_INDEX]             , 1);
+}
+
+static void
+save_dumptype(void)
+{
+    dumptype_t *dp, *dp1;;
 
     dp = lookup_dumptype(dpcur.name);
 
     if(dp != (dumptype_t *)0) {
-       parserror("dumptype %s already defined on line %d", dp->name, dp->seen);
+       conf_parserror("dumptype %s already defined on line %d", dp->name, dp->seen);
        return;
     }
 
     dp = alloc(sizeof(dumptype_t));
-    malloc_mark(dp);
     *dp = dpcur;
-    dp->next = dumplist;
-    dumplist = dp;
+    dp->next = NULL;
+    /* add at end of list */
+    if(!dumplist)
+       dumplist = dp;
+    else {
+       dp1 = dumplist;
+       while (dp1->next != NULL) {
+            dp1 = dp1->next;
+       }
+       dp1->next = dp;
+    }
 }
 
-static void copy_dumptype()
+static void
+copy_dumptype(void)
 {
     dumptype_t *dt;
+    int i;
 
-    dt = lookup_dumptype(tokenval.s);
+    dt = lookup_dumptype(tokenval.v.s);
 
     if(dt == NULL) {
-       parserror("dump type parameter expected");
+       conf_parserror("dumptype parameter expected");
        return;
     }
 
-#define dtcopy(v,s) if(dt->s) { dpcur.v = dt->v; dpcur.s = dt->s; }
-
-    if(dt->s_comment) {
-       dpcur.comment = newstralloc(dpcur.comment, dt->comment);
-       dpcur.s_comment = dt->s_comment;
-    }
-    if(dt->s_program) {
-       dpcur.program = newstralloc(dpcur.program, dt->program);
-       dpcur.s_program = dt->s_program;
-    }
-    if(dt->s_security_driver) {
-       dpcur.security_driver = newstralloc(dpcur.security_driver,
-                                           dt->security_driver);
-       dpcur.s_security_driver = dt->s_security_driver;
-    }
-    if(dt->s_srvcompprog) {
-       dpcur.srvcompprog = newstralloc(dpcur.srvcompprog, dt->srvcompprog);
-       dpcur.s_srvcompprog = dt->s_srvcompprog;
-    }
-    if(dt->s_clntcompprog) {
-       dpcur.clntcompprog = newstralloc(dpcur.clntcompprog, dt->clntcompprog);
-       dpcur.s_clntcompprog = dt->s_clntcompprog;
-    }
-    if(dt->s_srv_encrypt) {
-       dpcur.srv_encrypt = newstralloc(dpcur.srv_encrypt, dt->srv_encrypt);
-       dpcur.s_srv_encrypt = dt->s_srv_encrypt;
-    }
-    if(dt->s_clnt_encrypt) {
-       dpcur.clnt_encrypt = newstralloc(dpcur.clnt_encrypt, dt->clnt_encrypt);
-       dpcur.s_clnt_encrypt = dt->s_clnt_encrypt;
-    }
-    if(dt->s_srv_decrypt_opt) {
-       dpcur.srv_decrypt_opt = newstralloc(dpcur.srv_decrypt_opt, dt->srv_decrypt_opt);
-       dpcur.s_srv_decrypt_opt = dt->s_srv_decrypt_opt;
-    }
-    if(dt->s_clnt_decrypt_opt) {
-       dpcur.clnt_decrypt_opt = newstralloc(dpcur.clnt_decrypt_opt, dt->clnt_decrypt_opt);
-       dpcur.s_clnt_decrypt_opt = dt->s_clnt_decrypt_opt;
-    }
-
-    if(dt->s_exclude_file) {
-       dpcur.exclude_file = duplicate_sl(dt->exclude_file);
-       dpcur.s_exclude_file = dt->s_exclude_file;
-    }
-    if(dt->s_exclude_list) {
-       dpcur.exclude_list = duplicate_sl(dt->exclude_list);
-       dpcur.s_exclude_list = dt->s_exclude_list;
-    }
-    if(dt->s_include_file) {
-       dpcur.include_file = duplicate_sl(dt->include_file);
-       dpcur.s_include_file = dt->s_include_file;
-    }
-    if(dt->s_include_list) {
-       dpcur.include_list = duplicate_sl(dt->include_list);
-       dpcur.s_include_list = dt->s_include_list;
-    }
-    dtcopy(priority, s_priority);
-    dtcopy(dumpcycle, s_dumpcycle);
-    dtcopy(maxcycle, s_maxcycle);
-    dtcopy(frequency, s_frequency);
-    dtcopy(maxdumps, s_maxdumps);
-    dtcopy(maxpromoteday, s_maxpromoteday);
-    dtcopy(bumppercent, s_bumppercent);
-    dtcopy(bumpsize, s_bumpsize);
-    dtcopy(bumpdays, s_bumpdays);
-    dtcopy(bumpmult, s_bumpmult);
-    dtcopy(start_t, s_start_t);
-    dtcopy(record, s_record);
-    dtcopy(strategy, s_strategy);
-    dtcopy(estimate, s_estimate);
-    dtcopy(compress, s_compress);
-    dtcopy(encrypt, s_encrypt);
-    dtcopy(comprate[0], s_comprate);
-    dtcopy(comprate[1], s_comprate);
-    dtcopy(skip_incr, s_skip_incr);
-    dtcopy(skip_full, s_skip_full);
-    dtcopy(no_hold, s_no_hold);
-    dtcopy(kencrypt, s_kencrypt);
-    dtcopy(ignore, s_ignore);
-    dtcopy(index, s_index);
-    dtcopy(tape_splitsize, s_tape_splitsize);
-    dtcopy(split_diskbuffer, s_split_diskbuffer);
-    dtcopy(fallback_splitsize, s_fallback_splitsize);
-}
-
-keytab_t tapetype_keytable[] = {
-    { "COMMENT", COMMENT },
-    { "LBL-TEMPL", LBL_TEMPL },
-    { "BLOCKSIZE", BLOCKSIZE },
-    { "FILE-PAD", FILE_PAD },
-    { "FILEMARK", FILEMARK },
-    { "LENGTH", LENGTH },
-    { "SPEED", SPEED },
-    { NULL, IDENT }
+    for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
+       if(dt->value[i].seen) {
+           free_val_t(&dpcur.value[i]);
+           copy_val_t(&dpcur.value[i], &dt->value[i]);
+       }
+    }
+}
+
+t_conf_var tapetype_var [] = {
+   { CONF_COMMENT  , CONFTYPE_STRING, read_string, TAPETYPE_COMMENT  , NULL },
+   { CONF_LBL_TEMPL, CONFTYPE_STRING, read_string, TAPETYPE_LBL_TEMPL, NULL },
+   { CONF_BLOCKSIZE, CONFTYPE_SIZE  , read_size  , TAPETYPE_BLOCKSIZE, validate_blocksize },
+   { CONF_LENGTH   , CONFTYPE_AM64  , read_am64  , TAPETYPE_LENGTH   , validate_positive0 },
+   { CONF_FILEMARK , CONFTYPE_AM64  , read_am64  , TAPETYPE_FILEMARK , NULL },
+   { CONF_SPEED    , CONFTYPE_INT   , read_int   , TAPETYPE_SPEED    , validate_positive0 },
+   { CONF_FILE_PAD , CONFTYPE_BOOL  , read_bool  , TAPETYPE_FILE_PAD , NULL },
+   { CONF_UNKNOWN  , CONFTYPE_INT   , NULL       , TAPETYPE_TAPETYPE , NULL }
 };
 
-static void get_tapetype()
+static void
+get_tapetype(void)
 {
-    int done;
     int save_overwrites;
-    val_t value;
-
-    keytab_t *save_kt;
+    char *prefix;
 
     save_overwrites = allow_overwrites;
     allow_overwrites = 1;
 
-    save_kt = keytable;
-    keytable = tapetype_keytable;
-
     init_tapetype_defaults();
 
-    get_conftoken(IDENT);
-    tpcur.name = stralloc(tokenval.s);
-    malloc_mark(tpcur.name);
-    tpcur.seen = line_num;
-
-    get_conftoken(LBRACE);
-    get_conftoken(NL);
-
-    done = 0;
-    do {
-       line_num += 1;
-       get_conftoken(ANY);
-       switch(tok) {
+    get_conftoken(CONF_IDENT);
+    tpcur.name = stralloc(tokenval.v.s);
+    tpcur.seen = conf_line_num;
 
-       case RBRACE:
-           done = 1;
-           break;
-       case COMMENT:
-           get_simple((val_t *)&tpcur.comment, &tpcur.s_comment, STRING);
-           break;
-       case LBL_TEMPL:
-           get_simple((val_t *)&tpcur.lbl_templ, &tpcur.s_lbl_templ, STRING);
-           break;
-       case BLOCKSIZE:
-           get_simple((val_t *)&tpcur.blocksize, &tpcur.s_blocksize, LONG);
-           if(tpcur.blocksize < DISK_BLOCK_KB) {
-               parserror("Tape blocksize must be at least %d KBytes",
-                         DISK_BLOCK_KB);
-           } else if(tpcur.blocksize > MAX_TAPE_BLOCK_KB) {
-               parserror("Tape blocksize must not be larger than %d KBytes",
-                         MAX_TAPE_BLOCK_KB);
-           }
-           break;
-       case FILE_PAD:
-           get_simple(&value, &tpcur.s_file_pad, BOOL);
-           tpcur.file_pad = (value.i != 0);
-           break;
-       case LENGTH:
-           get_simple(&value, &tpcur.s_length, LONG);
-           if(value.l < 0) {
-               parserror("Tape length must be positive");
-           }
-           else {
-               tpcur.length = (unsigned long) value.l;
-           }
-           break;
-       case FILEMARK:
-           get_simple(&value, &tpcur.s_filemark, LONG);
-           if(value.l < 0) {
-               parserror("Tape file mark size must be positive");
-           }
-           else {
-               tpcur.filemark = (unsigned long) value.l;
-           }
-           break;
-       case SPEED:
-           get_simple((val_t *)&tpcur.speed, &tpcur.s_speed, INT);
-           if(tpcur.speed < 0) {
-               parserror("Speed must be positive");
-           }
-           break;
-       case IDENT:
-           copy_tapetype();
-           break;
-       case NL:        /* empty line */
-           break;
-       case END:       /* end of file */
-           done = 1;
-       default:
-           parserror("tape type parameter expected");
-       }
-       if(tok != NL && tok != END) get_conftoken(NL);
-    } while(!done);
+    prefix = vstralloc( "TAPETYPE:", tpcur.name, ":", NULL);
+    read_block(server_options, tapetype_var, server_keytab, tpcur.value,
+              prefix, "tapetype parameter expected", 1, &copy_tapetype);
+    amfree(prefix);
+    get_conftoken(CONF_NL);
 
     save_tapetype();
 
     allow_overwrites = save_overwrites;
-    keytable = save_kt;
 }
 
-static void init_tapetype_defaults()
+static void
+init_tapetype_defaults(void)
 {
-    tpcur.comment = stralloc("");
-    tpcur.lbl_templ = stralloc("");
-    tpcur.blocksize = (DISK_BLOCK_KB);
-    tpcur.file_pad = 1;
-    tpcur.length = 2000 * 1024;
-    tpcur.filemark = 1000;
-    tpcur.speed = 200;
-
-    tpcur.s_comment = 0;
-    tpcur.s_lbl_templ = 0;
-    tpcur.s_blocksize = 0;
-    tpcur.s_file_pad = 0;
-    tpcur.s_length = 0;
-    tpcur.s_filemark = 0;
-    tpcur.s_speed = 0;
+    conf_init_string(&tpcur.value[TAPETYPE_COMMENT]  , "");
+    conf_init_string(&tpcur.value[TAPETYPE_LBL_TEMPL], "");
+    conf_init_size  (&tpcur.value[TAPETYPE_BLOCKSIZE], DISK_BLOCK_KB);
+    conf_init_am64  (&tpcur.value[TAPETYPE_LENGTH]   , (off_t)2000 * 1024);
+    conf_init_am64  (&tpcur.value[TAPETYPE_FILEMARK] , (off_t)1000);
+    conf_init_int   (&tpcur.value[TAPETYPE_SPEED]    , 200);
+    conf_init_bool  (&tpcur.value[TAPETYPE_FILE_PAD] , 1);
 }
 
-static void save_tapetype()
+static void
+save_tapetype(void)
 {
-    tapetype_t *tp;
+    tapetype_t *tp, *tp1;
 
     tp = lookup_tapetype(tpcur.name);
 
     if(tp != (tapetype_t *)0) {
        amfree(tpcur.name);
-       parserror("tapetype %s already defined on line %d", tp->name, tp->seen);
+       conf_parserror("tapetype %s already defined on line %d", tp->name, tp->seen);
        return;
     }
 
     tp = alloc(sizeof(tapetype_t));
-    malloc_mark(tp);
     *tp = tpcur;
-    tp->next = tapelist;
-    tapelist = tp;
+    /* add at end of list */
+    if(!tapelist)
+       tapelist = tp;
+    else {
+       tp1 = tapelist;
+       while (tp1->next != NULL) {
+           tp1 = tp1->next;
+       }
+       tp1->next = tp;
+    }
 }
 
-static void copy_tapetype()
+static void
+copy_tapetype(void)
 {
     tapetype_t *tp;
+    int i;
 
-    tp = lookup_tapetype(tokenval.s);
+    tp = lookup_tapetype(tokenval.v.s);
 
     if(tp == NULL) {
-       parserror("tape type parameter expected");
+       conf_parserror("tape type parameter expected");
        return;
     }
 
-#define ttcopy(v,s) if(tp->s) { tpcur.v = tp->v; tpcur.s = tp->s; }
-
-    if(tp->s_comment) {
-       tpcur.comment = newstralloc(tpcur.comment, tp->comment);
-       tpcur.s_comment = tp->s_comment;
-    }
-    if(tp->s_lbl_templ) {
-       tpcur.lbl_templ = newstralloc(tpcur.lbl_templ, tp->lbl_templ);
-       tpcur.s_lbl_templ = tp->s_lbl_templ;
+    for(i=0; i < TAPETYPE_TAPETYPE; i++) {
+       if(tp->value[i].seen) {
+           free_val_t(&tpcur.value[i]);
+           copy_val_t(&tpcur.value[i], &tp->value[i]);
+       }
     }
-    ttcopy(blocksize, s_blocksize);
-    ttcopy(file_pad, s_file_pad);
-    ttcopy(length, s_length);
-    ttcopy(filemark, s_filemark);
-    ttcopy(speed, s_speed);
 }
 
-keytab_t interface_keytable[] = {
-    { "COMMENT", COMMENT },
-    { "USE", USE },
-    { NULL, IDENT }
+t_conf_var interface_var [] = {
+   { CONF_COMMENT, CONFTYPE_STRING, read_string, INTER_COMMENT , NULL },
+   { CONF_USE    , CONFTYPE_INT   , read_int   , INTER_MAXUSAGE, validate_positive1 },
+   { CONF_UNKNOWN, CONFTYPE_INT   , NULL       , INTER_INTER   , NULL }
 };
 
-static void get_interface()
+static void
+get_interface(void)
 {
-    int done;
     int save_overwrites;
-    keytab_t *save_kt;
+    char *prefix;
 
     save_overwrites = allow_overwrites;
     allow_overwrites = 1;
 
-    save_kt = keytable;
-    keytable = interface_keytable;
-
     init_interface_defaults();
 
-    get_conftoken(IDENT);
-    ifcur.name = stralloc(tokenval.s);
-    malloc_mark(ifcur.name);
-    ifcur.seen = line_num;
+    get_conftoken(CONF_IDENT);
+    ifcur.name = stralloc(tokenval.v.s);
+    ifcur.seen = conf_line_num;
 
-    get_conftoken(LBRACE);
-    get_conftoken(NL);
-
-    done = 0;
-    do {
-       line_num += 1;
-       get_conftoken(ANY);
-       switch(tok) {
-
-       case RBRACE:
-           done = 1;
-           break;
-       case COMMENT:
-           get_simple((val_t *)&ifcur.comment, &ifcur.s_comment, STRING);
-           break;
-       case USE:
-           get_simple((val_t *)&ifcur.maxusage, &ifcur.s_maxusage, INT);
-           if(ifcur.maxusage <1) {
-               parserror("use must bbe positive");
-           }
-           break;
-       case IDENT:
-           copy_interface();
-           break;
-       case NL:        /* empty line */
-           break;
-       case END:       /* end of file */
-           done = 1;
-       default:
-           parserror("interface parameter expected");
-       }
-       if(tok != NL && tok != END) get_conftoken(NL);
-    } while(!done);
+    prefix = vstralloc( "INTERFACE:", ifcur.name, ":", NULL);
+    read_block(server_options, interface_var, server_keytab, ifcur.value,
+              prefix, "interface parameter expected", 1, &copy_interface);
+    amfree(prefix);
+    get_conftoken(CONF_NL);
 
     save_interface();
 
     allow_overwrites = save_overwrites;
-    keytable = save_kt;
 
     return;
 }
 
-static void init_interface_defaults()
+static void
+init_interface_defaults(void)
 {
-    ifcur.comment = stralloc("");
-    ifcur.maxusage = 300;
-
-    ifcur.s_comment = 0;
-    ifcur.s_maxusage = 0;
+    conf_init_string(&ifcur.value[INTER_COMMENT] , "");
+    conf_init_int   (&ifcur.value[INTER_MAXUSAGE], 300);
 
     ifcur.curusage = 0;
 }
 
-static void save_interface()
+static void
+save_interface(void)
 {
-    interface_t *ip;
+    interface_t *ip, *ip1;
 
     ip = lookup_interface(ifcur.name);
 
     if(ip != (interface_t *)0) {
-       parserror("interface %s already defined on line %d", ip->name, ip->seen);
+       conf_parserror("interface %s already defined on line %d", ip->name,
+                      ip->seen);
        return;
     }
 
     ip = alloc(sizeof(interface_t));
-    malloc_mark(ip);
     *ip = ifcur;
-    ip->next = interface_list;
-    interface_list = ip;
+    /* add at end of list */
+    if(!interface_list) {
+       interface_list = ip;
+    } else {
+       ip1 = interface_list;
+       while (ip1->next != NULL) {
+           ip1 = ip1->next;
+       }
+       ip1->next = ip;
+    }
 }
 
-static void copy_interface()
+static void
+copy_interface(void)
 {
+/*
+    int i;
+    t_xxx *np;
+    keytab_t *kt;
+    
+    val_t val;
+*/
     interface_t *ip;
+    int i;
 
-    ip = lookup_interface(tokenval.s);
+    ip = lookup_interface(tokenval.v.s);
 
     if(ip == NULL) {
-       parserror("interface parameter expected");
+       conf_parserror("interface parameter expected");
        return;
     }
 
-#define ifcopy(v,s) if(ip->s) { ifcur.v = ip->v; ifcur.s = ip->s; }
-
-    if(ip->s_comment) {
-       ifcur.comment = newstralloc(ifcur.comment, ip->comment);
-       ifcur.s_comment = ip->s_comment;
-    }
-    ifcopy(maxusage, s_maxusage);
-}
-
-keytab_t dumpopts_keytable[] = {
-    { "COMPRESS", COMPRESS },
-    { "ENCRYPT", ENCRYPT },
-    { "INDEX", INDEX },
-    { "EXCLUDE-FILE", EXCLUDE_FILE },
-    { "EXCLUDE-LIST", EXCLUDE_LIST },
-    { "KENCRYPT", KENCRYPT },
-    { "SKIP-FULL", SKIP_FULL },
-    { "SKIP-INCR", SKIP_INCR },
-    { NULL, IDENT }
-};
-
-static void get_dumpopts() /* XXX - for historical compatability */
-{
-    int done;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = dumpopts_keytable;
-
-    done = 0;
-    do {
-       get_conftoken(ANY);
-       switch(tok) {
-       case COMPRESS:   ckseen(&dpcur.s_compress);  dpcur.compress = COMP_FAST; break;
-       case ENCRYPT:   ckseen(&dpcur.s_encrypt);  dpcur.encrypt = ENCRYPT_NONE; break;
-       case EXCLUDE_FILE:
-           ckseen(&dpcur.s_exclude_file);
-           get_conftoken(STRING);
-           dpcur.exclude_file = append_sl(dpcur.exclude_file, tokenval.s);
-           break;
-       case EXCLUDE_LIST:
-           ckseen(&dpcur.s_exclude_list);
-           get_conftoken(STRING);
-           dpcur.exclude_list = append_sl(dpcur.exclude_list, tokenval.s);
-           break;
-       case KENCRYPT:   ckseen(&dpcur.s_kencrypt);  dpcur.kencrypt = 1; break;
-       case SKIP_INCR:  ckseen(&dpcur.s_skip_incr); dpcur.skip_incr= 1; break;
-       case SKIP_FULL:  ckseen(&dpcur.s_skip_full); dpcur.skip_full= 1; break;
-       case INDEX:      ckseen(&dpcur.s_index);     dpcur.index    = 1; break;
-       case IDENT:
-           copy_dumptype();
-           break;
-       case NL: done = 1; break;
-       case COMMA: break;
-       case END:
-           done = 1;
-       default:
-           parserror("dump option expected");
+    for(i=0; i < INTER_INTER; i++) {
+       if(ip->value[i].seen) {
+           free_val_t(&ifcur.value[i]);
+           copy_val_t(&ifcur.value[i], &ip->value[i]);
        }
-    } while(!done);
-
-    keytable = save_kt;
+    }
 }
 
-static void get_comprate()
+static void
+get_comprate(
+    t_conf_var *np,
+    val_t *val)
 {
-    val_t var;
-
-    get_simple(&var, &dpcur.s_comprate, REAL);
-    dpcur.comprate[0] = dpcur.comprate[1] = var.r;
-    if(dpcur.comprate[0] < 0) {
-       parserror("full compression rate must be >= 0");
+    np = np;
+    get_conftoken(CONF_REAL);
+    val->v.rate[0] = tokenval.v.r;
+    val->v.rate[1] = tokenval.v.r;
+    val->seen = tokenval.seen;
+    if(tokenval.v.r < 0) {
+       conf_parserror("full compression rate must be >= 0");
     }
 
-    get_conftoken(ANY);
+    get_conftoken(CONF_ANY);
     switch(tok) {
-    case NL:
+    case CONF_NL:
+       return;
+
+    case CONF_END:
        return;
-    case COMMA:
+
+    case CONF_COMMA:
        break;
+
     default:
        unget_conftoken();
     }
 
-    get_conftoken(REAL);
-    dpcur.comprate[1] = tokenval.r;
-    if(dpcur.comprate[1] < 0) {
-       parserror("incremental compression rate must be >= 0");
+    get_conftoken(CONF_REAL);
+    val->v.rate[1] = tokenval.v.r;
+    if(tokenval.v.r < 0) {
+       conf_parserror("incremental compression rate must be >= 0");
     }
 }
 
-keytab_t compress_keytable[] = {
-    { "BEST", BEST },
-    { "CLIENT", CLIENT },
-    { "FAST", FAST },
-    { "NONE", NONE },
-    { "SERVER", SERVER },
-    { "CUSTOM", CUSTOM },
-    { NULL, IDENT }
-};
-
-static void get_compress()
+static void
+get_compress(
+    t_conf_var *np,
+    val_t *val)
 {
-    keytab_t *save_kt;
     int serv, clie, none, fast, best, custom;
     int done;
-    int comp;
-
-    save_kt = keytable;
-    keytable = compress_keytable;
+    comp_t comp;
 
-    ckseen(&dpcur.s_compress);
+    np = np;
+    ckseen(&val->seen);
 
     serv = clie = none = fast = best = custom  = 0;
 
     done = 0;
     do {
-       get_conftoken(ANY);
+       get_conftoken(CONF_ANY);
        switch(tok) {
-       case NONE:   none = 1; break;
-       case FAST:   fast = 1; break;
-       case BEST:   best = 1; break;
-       case CLIENT: clie = 1; break;
-       case SERVER: serv = 1; break;
-       case CUSTOM: custom=1; break;
-       case NL:     done = 1; break;
+       case CONF_NONE:   none = 1; break;
+       case CONF_FAST:   fast = 1; break;
+       case CONF_BEST:   best = 1; break;
+       case CONF_CLIENT: clie = 1; break;
+       case CONF_SERVER: serv = 1; break;
+       case CONF_CUSTOM: custom=1; break;
+       case CONF_NL:     done = 1; break;
+       case CONF_END:    done = 1; break;
        default:
            done = 1;
            serv = clie = 1; /* force an error */
@@ -2281,307 +1614,275 @@ static void get_compress()
        if(!none && !fast && !best && custom) comp = COMP_SERV_CUST;
     }
 
-    if(comp == -1) {
-       parserror("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected");
+    if((int)comp == -1) {
+       conf_parserror("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected");
        comp = COMP_NONE;
     }
 
-    dpcur.compress = comp;
-
-    keytable = save_kt;
+    val->v.i = (int)comp;
 }
 
-keytab_t encrypt_keytable[] = {
-    { "NONE", NONE },
-    { "CLIENT", CLIENT },
-    { "SERVER", SERVER },
-    { NULL, IDENT }
-};
-
-static void get_encrypt()
+static void
+get_encrypt(
+    t_conf_var *np,
+    val_t *val)
 {
-   keytab_t *save_kt;
-   int encrypt;
-
-   save_kt = keytable;
-   keytable = encrypt_keytable;
+   encrypt_t encrypt;
 
-   ckseen(&dpcur.s_encrypt);
+   np = np;
+   ckseen(&val->seen);
 
-   get_conftoken(ANY);
+   get_conftoken(CONF_ANY);
    switch(tok) {
-   case NONE:  
+   case CONF_NONE:  
      encrypt = ENCRYPT_NONE; 
      break;
-   case CLIENT:  
+
+   case CONF_CLIENT:  
      encrypt = ENCRYPT_CUST;
      break;
-   case SERVER: 
+
+   case CONF_SERVER: 
      encrypt = ENCRYPT_SERV_CUST;
      break;
+
    default:
-     parserror("NONE, CLIENT or SERVER expected");
+     conf_parserror("NONE, CLIENT or SERVER expected");
      encrypt = ENCRYPT_NONE;
+     break;
    }
 
-   dpcur.encrypt = encrypt;
-   keytable = save_kt; 
+   val->v.i = (int)encrypt;
 }
 
-keytab_t taperalgo_keytable[] = {
-    { "FIRST", FIRST },
-    { "FIRSTFIT", FIRSTFIT },
-    { "LARGEST", LARGEST },
-    { "LARGESTFIT", LARGESTFIT },
-    { "SMALLEST", SMALLEST },
-    { "LAST", LAST },
-    { NULL, IDENT }
-};
-
-static void get_taperalgo(c_taperalgo, s_taperalgo)
-val_t *c_taperalgo;
-int *s_taperalgo;
+static void
+get_holding(
+    t_conf_var *np,
+    val_t *val)
 {
-    keytab_t *save_kt;
+   dump_holdingdisk_t holding;
 
-    save_kt = keytable;
-    keytable = taperalgo_keytable;
+   np = np;
+   ckseen(&val->seen);
 
-    ckseen(s_taperalgo);
+   get_conftoken(CONF_ANY);
+   switch(tok) {
+   case CONF_NEVER:  
+     holding = HOLD_NEVER; 
+     break;
 
-    get_conftoken(ANY);
+   case CONF_AUTO:  
+     holding = HOLD_AUTO;
+     break;
+
+   case CONF_REQUIRED: 
+     holding = HOLD_REQUIRED;
+     break;
+
+   default: /* can be a BOOLEAN */
+     unget_conftoken();
+     holding =  (dump_holdingdisk_t)get_bool();
+     if (holding == 0)
+       holding = HOLD_NEVER;
+     else if (holding == 1 || holding == 2)
+       holding = HOLD_AUTO;
+     else
+       conf_parserror("NEVER, AUTO or REQUIRED expected");
+     break;
+   }
+
+   val->v.i = (int)holding;
+}
+
+static void
+get_taperalgo(
+    t_conf_var *np,
+    val_t *val)
+{
+    np = np;
+    ckseen(&val->seen);
+
+    get_conftoken(CONF_ANY);
     switch(tok) {
-    case FIRST:      c_taperalgo->i = ALGO_FIRST;      break;
-    case FIRSTFIT:   c_taperalgo->i = ALGO_FIRSTFIT;   break;
-    case LARGEST:    c_taperalgo->i = ALGO_LARGEST;    break;
-    case LARGESTFIT: c_taperalgo->i = ALGO_LARGESTFIT; break;
-    case SMALLEST:   c_taperalgo->i = ALGO_SMALLEST;   break;
-    case LAST:       c_taperalgo->i = ALGO_LAST;       break;
+    case CONF_FIRST:      val->v.i = ALGO_FIRST;      break;
+    case CONF_FIRSTFIT:   val->v.i = ALGO_FIRSTFIT;   break;
+    case CONF_LARGEST:    val->v.i = ALGO_LARGEST;    break;
+    case CONF_LARGESTFIT: val->v.i = ALGO_LARGESTFIT; break;
+    case CONF_SMALLEST:   val->v.i = ALGO_SMALLEST;   break;
+    case CONF_LAST:       val->v.i = ALGO_LAST;       break;
     default:
-       parserror("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected");
+       conf_parserror("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected");
     }
-
-    keytable = save_kt;
 }
 
-keytab_t priority_keytable[] = {
-    { "HIGH", HIGH },
-    { "LOW", LOW },
-    { "MEDIUM", MEDIUM },
-    { NULL, IDENT }
-};
-
-static void get_priority()
+static void
+get_priority(
+    t_conf_var *np,
+    val_t *val)
 {
     int pri;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = priority_keytable;
 
-    ckseen(&dpcur.s_priority);
+    np = np;
+    ckseen(&val->seen);
 
-    get_conftoken(ANY);
+    get_conftoken(CONF_ANY);
     switch(tok) {
-    case LOW: pri = 0; break;
-    case MEDIUM: pri = 1; break;
-    case HIGH: pri = 2; break;
-    case INT: pri = tokenval.i; break;
+    case CONF_LOW: pri = 0; break;
+    case CONF_MEDIUM: pri = 1; break;
+    case CONF_HIGH: pri = 2; break;
+    case CONF_INT: pri = tokenval.v.i; break;
     default:
-       parserror("LOW, MEDIUM, HIGH or integer expected");
+       conf_parserror("LOW, MEDIUM, HIGH or integer expected");
        pri = 0;
     }
-    dpcur.priority = pri;
-
-    keytable = save_kt;
+    val->v.i = pri;
 }
 
-keytab_t strategy_keytable[] = {
-    { "HANOI", HANOI },
-    { "NOFULL", NOFULL },
-    { "NOINC", NOINC },
-    { "SKIP", SKIP },
-    { "STANDARD", STANDARD },
-    { "INCRONLY", INCRONLY },
-    { NULL, IDENT }
-};
-
-static void get_strategy()
+static void
+get_strategy(
+    t_conf_var *np,
+    val_t *val)
 {
     int strat;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = strategy_keytable;
 
-    ckseen(&dpcur.s_strategy);
+    np = np;
+    ckseen(&val->seen);
 
-    get_conftoken(ANY);
+    get_conftoken(CONF_ANY);
     switch(tok) {
-    case SKIP:
+    case CONF_SKIP:
        strat = DS_SKIP;
        break;
-    case STANDARD:
+    case CONF_STANDARD:
        strat = DS_STANDARD;
        break;
-    case NOFULL:
+    case CONF_NOFULL:
        strat = DS_NOFULL;
        break;
-    case NOINC:
+    case CONF_NOINC:
        strat = DS_NOINC;
        break;
-    case HANOI:
+    case CONF_HANOI:
        strat = DS_HANOI;
        break;
-    case INCRONLY:
+    case CONF_INCRONLY:
        strat = DS_INCRONLY;
        break;
     default:
-       parserror("STANDARD or NOFULL expected");
+       conf_parserror("STANDARD or NOFULL expected");
        strat = DS_STANDARD;
     }
-    dpcur.strategy = strat;
-
-    keytable = save_kt;
+    val->v.i = strat;
 }
 
-keytab_t estimate_keytable[] = {
-    { "CLIENT", CLIENT },
-    { "SERVER", SERVER },
-    { "CALCSIZE", CALCSIZE }
-};
-
-static void get_estimate()
+static void
+get_estimate(
+    t_conf_var *np,
+    val_t *val)
 {
     int estime;
-    keytab_t *save_kt;
 
-    save_kt = keytable;
-    keytable = estimate_keytable;
+    np = np;
+    ckseen(&val->seen);
 
-    ckseen(&dpcur.s_estimate);
-
-    get_conftoken(ANY);
+    get_conftoken(CONF_ANY);
     switch(tok) {
-    case CLIENT:
+    case CONF_CLIENT:
        estime = ES_CLIENT;
        break;
-    case SERVER:
+    case CONF_SERVER:
        estime = ES_SERVER;
        break;
-    case CALCSIZE:
+    case CONF_CALCSIZE:
        estime = ES_CALCSIZE;
        break;
     default:
-       parserror("CLIENT, SERVER or CALCSIZE expected");
+       conf_parserror("CLIENT, SERVER or CALCSIZE expected");
        estime = ES_CLIENT;
     }
-    dpcur.estimate = estime;
-
-    keytable = save_kt;
+    val->v.i = estime;
 }
 
-keytab_t exclude_keytable[] = {
-    { "LIST", LIST },
-    { "FILE", EFILE },
-    { "APPEND", APPEND },
-    { "OPTIONAL", OPTIONAL },
-    { NULL, IDENT }
-};
-
-static void get_exclude()
+static void
+get_exclude(
+    t_conf_var *np,
+    val_t *val)
 {
-    int list, got_one = 0;
-    keytab_t *save_kt;
+    int file, got_one = 0;
     sl_t *exclude;
     int optional = 0;
-    int append = 0;
 
-    save_kt = keytable;
-    keytable = exclude_keytable;
-
-    get_conftoken(ANY);
-    if(tok == LIST) {
-       list = 1;
-       exclude = dpcur.exclude_list;
-       ckseen(&dpcur.s_exclude_list);
-       get_conftoken(ANY);
+    np = np;
+    get_conftoken(CONF_ANY);
+    if(tok == CONF_LIST) {
+       file = 0;
+       get_conftoken(CONF_ANY);
     }
     else {
-       list = 0;
-       exclude = dpcur.exclude_file;
-       ckseen(&dpcur.s_exclude_file);
-       if(tok == EFILE) get_conftoken(ANY);
+       file = 1;
+       if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
     }
+    val->v.exinclude.type = file;
+    exclude = val->v.exinclude.sl;
+    ckseen(&val->seen);
 
-    if(tok == OPTIONAL) {
-       get_conftoken(ANY);
+    if(tok == CONF_OPTIONAL) {
+       get_conftoken(CONF_ANY);
        optional = 1;
     }
 
-    if(tok == APPEND) {
-       get_conftoken(ANY);
-       append = 1;
+    if(tok == CONF_APPEND) {
+       get_conftoken(CONF_ANY);
     }
     else {
        free_sl(exclude);
        exclude = NULL;
-       append = 0;
     }
 
-    while(tok == STRING) {
-       exclude = append_sl(exclude, tokenval.s);
+    while(tok == CONF_STRING) {
+       exclude = append_sl(exclude, tokenval.v.s);
        got_one = 1;
-       get_conftoken(ANY);
+       get_conftoken(CONF_ANY);
     }
     unget_conftoken();
 
     if(got_one == 0) { free_sl(exclude); exclude = NULL; }
 
-    if(list == 0)
-       dpcur.exclude_file = exclude;
-    else {
-       dpcur.exclude_list = exclude;
-       if(!append || optional)
-           dpcur.exclude_optional = optional;
-    }
-
-    keytable = save_kt;
+    val->v.exinclude.sl = exclude;
+    val->v.exinclude.optional = optional;
 }
 
-
-static void get_include()
+/*
+static void get_include(np, val)
+    t_conf_var *np;
+    val_t *val;
 {
     int list, got_one = 0;
-    keytab_t *save_kt;
     sl_t *include;
     int optional = 0;
     int append = 0;
 
-    save_kt = keytable;
-    keytable = exclude_keytable;
-
-    get_conftoken(ANY);
-    if(tok == LIST) {
+    get_conftoken(CONF_ANY);
+    if(tok == CONF_LIST) {
        list = 1;
-       include = dpcur.include_list;
-       ckseen(&dpcur.s_include_list);
-       get_conftoken(ANY);
+       include = dpcur.value[DUMPTYPE_INCLUDE_LIST].v.sl;
+       ckseen(&dpcur.value[DUMPTYPE_INCLUDE_LIST].seen);
+       get_conftoken(CONF_ANY);
     }
     else {
        list = 0;
-       include = dpcur.include_file;
-       ckseen(&dpcur.s_include_file);
-       if(tok == EFILE) get_conftoken(ANY);
+       include = dpcur.value[DUMPTYPE_INCLUDE_FILE].v.sl;
+       ckseen(&dpcur.value[DUMPTYPE_INCLUDE_FILE].seen);
+       if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
     }
 
-    if(tok == OPTIONAL) {
-       get_conftoken(ANY);
+    if(tok == CONF_OPTIONAL) {
+       get_conftoken(CONF_ANY);
        optional = 1;
     }
 
-    if(tok == APPEND) {
-       get_conftoken(ANY);
+    if(tok == CONF_APPEND) {
+       get_conftoken(CONF_ANY);
        append = 1;
     }
     else {
@@ -2590,581 +1891,38 @@ static void get_include()
        append = 0;
     }
 
-    while(tok == STRING) {
-       include = append_sl(include, tokenval.s);
+    while(tok == CONF_STRING) {
+       include = append_sl(include, tokenval.v.s);
        got_one = 1;
-       get_conftoken(ANY);
+       get_conftoken(CONF_ANY);
     }
     unget_conftoken();
 
     if(got_one == 0) { free_sl(include); include = NULL; }
 
     if(list == 0)
-       dpcur.include_file = include;
+       dpcur.value[DUMPTYPE_INCLUDE_FILE].v.sl = include;
     else {
-       dpcur.include_list = include;
+       dpcur.value[DUMPTYPE_INCLUDE_LIST].v.sl = include;
        if(!append || optional)
-           dpcur.include_optional = optional;
+           dpcur.value[DUMPTYPE_INCLUDE_OPTIONAL].v.i = optional;
     }
-
-    keytable = save_kt;
 }
-
+*/
 
 /* ------------------------ */
 
-
-static void get_simple(var, seen, type)
-val_t *var;
-int *seen;
-tok_t type;
-{
-    ckseen(seen);
-
-    switch(type) {
-    case STRING:
-    case IDENT:
-       get_conftoken(type);
-       var->s = newstralloc(var->s, tokenval.s);
-       malloc_mark(var->s);
-       break;
-    case INT:
-       var->i = get_int();
-       break;
-    case LONG:
-       var->l = get_long();
-       break;
-    case AM64:
-       var->am64 = get_am64_t();
-       break;
-    case BOOL:
-       var->i = get_bool();
-       break;
-    case REAL:
-       get_conftoken(REAL);
-       var->r = tokenval.r;
-       break;
-    case TIME:
-       var->i = get_time();
-       break;
-    default:
-       error("error [unknown get_simple type: %d]", type);
-       /* NOTREACHED */
-    }
-    return;
-}
-
-static int get_time()
-{
-    time_t st = start_time.r.tv_sec;
-    struct tm *stm;
-    int hhmm;
-
-    get_conftoken(INT);
-    hhmm = tokenval.i;
-
-    stm = localtime(&st);
-    st -= stm->tm_sec + 60 * (stm->tm_min + 60 * stm->tm_hour);
-    st += ((hhmm/100*60) + hhmm%100)*60;
-
-    if (st-start_time.r.tv_sec<-43200)
-       st += 86400;
-
-    return st;
-}
-
-keytab_t numb_keytable[] = {
-    { "B", MULT1 },
-    { "BPS", MULT1 },
-    { "BYTE", MULT1 },
-    { "BYTES", MULT1 },
-    { "DAY", MULT1 },
-    { "DAYS", MULT1 },
-    { "INF", INFINITY },
-    { "K", MULT1K },
-    { "KB", MULT1K },
-    { "KBPS", MULT1K },
-    { "KBYTE", MULT1K },
-    { "KBYTES", MULT1K },
-    { "KILOBYTE", MULT1K },
-    { "KILOBYTES", MULT1K },
-    { "KPS", MULT1K },
-    { "M", MULT1M },
-    { "MB", MULT1M },
-    { "MBPS", MULT1M },
-    { "MBYTE", MULT1M },
-    { "MBYTES", MULT1M },
-    { "MEG", MULT1M },
-    { "MEGABYTE", MULT1M },
-    { "MEGABYTES", MULT1M },
-    { "G", MULT1G },
-    { "GB", MULT1G },
-    { "GBPS", MULT1G },
-    { "GBYTE", MULT1G },
-    { "GBYTES", MULT1G },
-    { "GIG", MULT1G },
-    { "GIGABYTE", MULT1G },
-    { "GIGABYTES", MULT1G },
-    { "MPS", MULT1M },
-    { "TAPE", MULT1 },
-    { "TAPES", MULT1 },
-    { "WEEK", MULT7 },
-    { "WEEKS", MULT7 },
-    { NULL, IDENT }
-};
-
-static int get_int()
-{
-    int val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = numb_keytable;
-
-    get_conftoken(ANY);
-
-    switch(tok) {
-    case AM64:
-       if(abs(tokenval.am64) > INT_MAX)
-           parserror("value too large");
-       val = (int) tokenval.am64;
-       break;
-    case INFINITY:
-       val = (int) BIGINT;
-       break;
-    default:
-       parserror("an integer expected");
-       val = 0;
-    }
-
-    /* get multiplier, if any */
-    get_conftoken(ANY);
-
-    switch(tok) {
-    case NL:                   /* multiply by one */
-    case MULT1:
-    case MULT1K:
-       break;
-    case MULT7:
-       if(abs(val) > INT_MAX/7)
-           parserror("value too large");
-       val *= 7;
-       break;
-    case MULT1M:
-       if(abs(val) > INT_MAX/1024)
-           parserror("value too large");
-       val *= 1024;
-       break;
-    case MULT1G:
-       if(abs(val) > INT_MAX/(1024*1024))
-           parserror("value too large");
-       val *= 1024*1024;
-       break;
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-    }
-
-    keytable = save_kt;
-
-    return val;
-}
-
-static long get_long()
-{
-    long val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = numb_keytable;
-
-    get_conftoken(ANY);
-
-    switch(tok) {
-    case AM64:
-       if(tokenval.am64 > LONG_MAX || tokenval.am64 < LONG_MIN)
-           parserror("value too large");
-       val = (long) tokenval.am64;
-       break;
-    case INFINITY:
-       val = (long) LONG_MAX;
-       break;
-    default:
-       parserror("a long expected");
-       val = 0;
-    }
-
-    /* get multiplier, if any */
-    get_conftoken(ANY);
-
-    switch(tok) {
-    case NL:                   /* multiply by one */
-    case MULT1:
-    case MULT1K:
-       break;
-    case MULT7:
-       if(val > LONG_MAX/7 || val < LONG_MIN/7)
-           parserror("value too large");
-       val *= 7;
-       break;
-    case MULT1M:
-       if(val > LONG_MAX/1024 || val < LONG_MIN/7)
-           parserror("value too large");
-       val *= 1024;
-       break;
-    case MULT1G:
-       if(val > LONG_MAX/(1024*1024) || val < LONG_MIN/(1024*1024))
-           parserror("value too large");
-       val *= 1024*1024;
-       break;
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-    }
-
-    keytable = save_kt;
-
-    return val;
-}
-
-static am64_t get_am64_t()
-{
-    am64_t val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = numb_keytable;
-
-    get_conftoken(ANY);
-
-    switch(tok) {
-    case AM64:
-       val = tokenval.am64;
-       break;
-    case INFINITY:
-       val = AM64_MAX;
-       break;
-    default:
-       parserror("a am64 expected %d", tok);
-       val = 0;
-    }
-
-    /* get multiplier, if any */
-    get_conftoken(ANY);
-
-    switch(tok) {
-    case NL:                   /* multiply by one */
-    case MULT1:
-    case MULT1K:
-       break;
-    case MULT7:
-       if(val > AM64_MAX/7 || val < AM64_MIN/7)
-           parserror("value too large");
-       val *= 7;
-       break;
-    case MULT1M:
-       if(val > AM64_MAX/1024 || val < AM64_MIN/1024)
-           parserror("value too large");
-       val *= 1024;
-       break;
-    case MULT1G:
-       if(val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
-           parserror("value too large");
-       val *= 1024*1024;
-       break;
-    default:   /* it was not a multiplier */
-       unget_conftoken();
-    }
-
-    keytable = save_kt;
-
-    return val;
-}
-
-keytab_t bool_keytable[] = {
-    { "Y", ATRUE },
-    { "YES", ATRUE },
-    { "T", ATRUE },
-    { "TRUE", ATRUE },
-    { "ON", ATRUE },
-    { "N", AFALSE },
-    { "NO", AFALSE },
-    { "F", AFALSE },
-    { "FALSE", AFALSE },
-    { "OFF", AFALSE },
-    { NULL, IDENT }
-};
-
-static int get_bool()
-{
-    int val;
-    keytab_t *save_kt;
-
-    save_kt = keytable;
-    keytable = bool_keytable;
-
-    get_conftoken(ANY);
-
-    switch(tok) {
-    case INT:
-       val = tokenval.i ? 1 : 0;
-       break;
-    case ATRUE:
-       val = 1;
-       break;
-    case AFALSE:
-       val = 0;
-       break;
-    case NL:
-    default:
-       unget_conftoken();
-       val = 2; /* no argument - most likely TRUE */
-    }
-
-    keytable = save_kt;
-
-    return val;
-}
-
-static void ckseen(seen)
-int *seen;
-{
-    if(*seen && !allow_overwrites) {
-       parserror("duplicate parameter, prev def on line %d", *seen);
-    }
-    *seen = line_num;
-}
-
-printf_arglist_function(static void parserror, char *, format)
-{
-    va_list argp;
-
-    /* print error message */
-
-    fprintf(stderr, "\"%s\", line %d: ", confname, line_num);
-    arglist_start(argp, format);
-    vfprintf(stderr, format, argp);
-    arglist_end(argp);
-    fputc('\n', stderr);
-
-    got_parserror = 1;
-}
-
-static tok_t lookup_keyword(str)
-char *str;
-{
-    keytab_t *kwp;
-
-    /* switch to binary search if performance warrants */
-
-    for(kwp = keytable; kwp->keyword != NULL; kwp++) {
-       if(strcmp(kwp->keyword, str) == 0) break;
-    }
-    return kwp->token;
-}
-
-static char tkbuf[4096];
-
-/* push the last token back (can only unget ANY tokens) */
-static void unget_conftoken()
-{
-    token_pushed = 1;
-    pushed_tok = tok;
-    tok = UNKNOWN;
-    return;
-}
-
-static void get_conftoken(exp)
-tok_t exp;
-{
-    int ch, d;
-    am64_t am64;
-    char *buf;
-    int token_overflow;
-
-    if(token_pushed) {
-       token_pushed = 0;
-       tok = pushed_tok;
-
-       /* If it looked like a key word before then look it
-       ** up again in the current keyword table. */
-       switch(tok) {
-       case LONG:    case AM64:
-       case INT:     case REAL:    case STRING:
-       case LBRACE:  case RBRACE:  case COMMA:
-       case NL:      case END:     case UNKNOWN:
-           break;
-       default:
-           if(exp == IDENT) tok = IDENT;
-           else tok = lookup_keyword(tokenval.s);
-       }
-    }
-    else {
-       ch = getc(conf);
-
-       while(ch != EOF && ch != '\n' && isspace(ch)) ch = getc(conf);
-       if(ch == '#') {         /* comment - eat everything but eol/eof */
-           while((ch = getc(conf)) != EOF && ch != '\n') {}
-       }
-
-       if(isalpha(ch)) {               /* identifier */
-           buf = tkbuf;
-           token_overflow = 0;
-           do {
-               if(islower(ch)) ch = toupper(ch);
-               if(buf < tkbuf+sizeof(tkbuf)-1) {
-                   *buf++ = ch;
-               } else {
-                   *buf = '\0';
-                   if(!token_overflow) {
-                       parserror("token too long: %.20s...", tkbuf);
-                   }
-                   token_overflow = 1;
-               }
-               ch = getc(conf);
-           } while(isalnum(ch) || ch == '_' || ch == '-');
-
-           ungetc(ch, conf);
-           *buf = '\0';
-
-           tokenval.s = tkbuf;
-
-           if(token_overflow) tok = UNKNOWN;
-           else if(exp == IDENT) tok = IDENT;
-           else tok = lookup_keyword(tokenval.s);
-       }
-       else if(isdigit(ch)) {  /* integer */
-           int sign;
-           if (1) {
-               sign = 1;
-           } else {
-           negative_number: /* look for goto negative_number below */
-               sign = -1;
-           }
-           tokenval.am64 = 0;
-           do {
-               tokenval.am64 = tokenval.am64 * 10 + (ch - '0');
-               ch = getc(conf);
-           } while(isdigit(ch));
-           if(ch != '.') {
-               if(exp == INT) {
-                   tok = INT;
-                   tokenval.i *= sign;
-               }
-               else if(exp == LONG) {
-                   tok = LONG;
-                   tokenval.l *= sign;
-               }
-               else if(exp != REAL) {
-                   tok = AM64;
-                   tokenval.am64 *= sign;
-               } else {
-                   /* automatically convert to real when expected */
-                   am64 = tokenval.am64;
-                   tokenval.r = sign * (double) am64;
-                   tok = REAL;
-               }
-           }
-           else {
-               /* got a real number, not an int */
-               am64 = tokenval.am64;
-               tokenval.r = sign * (double) am64;
-               am64=0; d=1;
-               ch = getc(conf);
-               while(isdigit(ch)) {
-                   am64 = am64 * 10 + (ch - '0');
-                   d = d * 10;
-                   ch = getc(conf);
-               }
-               tokenval.r += sign * ((double)am64)/d;
-               tok = REAL;
-           }
-           ungetc(ch,conf);
-       }
-       else switch(ch) {
-
-       case '"':                       /* string */
-           buf = tkbuf;
-           token_overflow = 0;
-           ch = getc(conf);
-           while(ch != '"' && ch != '\n' && ch != EOF) {
-               if(buf < tkbuf+sizeof(tkbuf)-1) {
-                   *buf++ = ch;
-               } else {
-                   *buf = '\0';
-                   if(!token_overflow) {
-                       parserror("string too long: %.20s...", tkbuf);
-                   }
-                   token_overflow = 1;
-               }
-               ch = getc(conf);
-           }
-           if(ch != '"') {
-               parserror("missing end quote");
-               ungetc(ch, conf);
-           }
-           *buf = '\0';
-           tokenval.s = tkbuf;
-           if(token_overflow) tok = UNKNOWN;
-           else tok = STRING;
-           break;
-
-       case '-':
-           ch = getc(conf);
-           if (isdigit(ch))
-               goto negative_number;
-           else {
-               ungetc(ch, conf);
-               tok = UNKNOWN;
-           }
-           break;
-       case ',':  tok = COMMA; break;
-       case '{':  tok = LBRACE; break;
-       case '}':  tok = RBRACE; break;
-       case '\n': tok = NL; break;
-       case EOF:  tok = END; break;
-       default:   tok = UNKNOWN;
-       }
-    }
-
-    if(exp != ANY && tok != exp) {
-       char *str;
-       keytab_t *kwp;
-
-       switch(exp) {
-       case LBRACE: str = "\"{\""; break;
-       case RBRACE: str = "\"}\""; break;
-       case COMMA:  str = "\",\""; break;
-
-       case NL: str = "end of line"; break;
-       case END: str = "end of file"; break;
-       case INT: str = "an integer"; break;
-       case REAL: str = "a real number"; break;
-       case STRING: str = "a quoted string"; break;
-       case IDENT: str = "an identifier"; break;
-       default:
-           for(kwp = keytable; kwp->keyword != NULL; kwp++)
-               if(exp == kwp->token) break;
-           if(kwp->keyword == NULL) str = "token not";
-           else str = kwp->keyword;
-       }
-       parserror("%s expected", str);
-       tok = exp;
-       if(tok == INT) tokenval.i = 0;
-       else tokenval.s = "";
-    }
-
-    return;
-}
-
-int ColumnDataCount()
+int
+ColumnDataCount(void )
 {
-    return sizeof(ColumnData) / sizeof(ColumnData[0]);
+    return (int)(SIZEOF(ColumnData) / SIZEOF(ColumnData[0]));
 }
 
 /* conversion from string to table index
  */
 int
-StringToColumn(s)
-    char *s;
+StringToColumn(
+    char *s)
 {
     int cn;
 
@@ -3177,18 +1935,23 @@ StringToColumn(s)
 }
 
 char
-LastChar(s)
-    char *s;
+LastChar(
+    char *s)
 {
     return s[strlen(s)-1];
 }
 
 int
-SetColumDataFromString(ci, s, errstr)
-    ColumnInfo* ci;
-    char *s;
-    char **errstr;
+SetColumDataFromString(
+    ColumnInfo* ci,
+    char *s,
+    char **errstr)
 {
+#ifdef TEST
+    char *myname= "SetColumDataFromString";
+#endif
+    ci = ci;
+
     /* Convert from a Columspec string to our internal format
      * of columspec. The purpose is to provide this string
      * as configuration paramter in the amanda.conf file or
@@ -3214,9 +1977,6 @@ SetColumDataFromString(ci, s, errstr)
      * output as it was all the time.
      *                                                 ElB, 1999-02-24.
      */
-#ifdef TEST
-    char *myname= "SetColumDataFromString";
-#endif
 
     while (s && *s) {
        int Space, Width;
@@ -3247,7 +2007,7 @@ SetColumDataFromString(ci, s, errstr)
            return -1;
        }
        ColumnData[cn].Width= Width;
-       ColumnData[cn].PrefixSpace= Space;
+       ColumnData[cn].PrefixSpace = Space;
        if (LastChar(ColumnData[cn].Format) == 's') {
            if (Width < 0)
                ColumnData[cn].MaxWidth= 1;
@@ -3256,7 +2016,7 @@ SetColumDataFromString(ci, s, errstr)
                    ColumnData[cn].Precision= Width;
        }
        else if (Width < ColumnData[cn].Precision)
-           ColumnData[cn].Precision= Width;
+           ColumnData[cn].Precision = Width;
        s= strchr(eon+1, ',');
        if (s != NULL)
            s++;
@@ -3265,19 +2025,8 @@ SetColumDataFromString(ci, s, errstr)
 }
 
 
-char *taperalgo2str(taperalgo)
-int taperalgo;
-{
-    if(taperalgo == ALGO_FIRST) return "FIRST";
-    if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
-    if(taperalgo == ALGO_LARGEST) return "LARGEST";
-    if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
-    if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
-    if(taperalgo == ALGO_LAST) return "LAST";
-    return "UNKNOWN";
-}
-
-long int getconf_unit_divisor()
+long int
+getconf_unit_divisor(void)
 {
     return unit_divisor;
 }
@@ -3285,242 +2034,129 @@ long int getconf_unit_divisor()
 /* ------------------------ */
 
 
-#ifdef TEST
-
 void
-dump_configuration(filename)
-    char *filename;
+dump_configuration(
+    char *filename)
 {
     tapetype_t *tp;
     dumptype_t *dp;
     interface_t *ip;
     holdingdisk_t *hp;
-    time_t st;
-    struct tm *stm;
+    int i;
+    t_conf_var *np;
+    keytab_t *kt;
+    char *prefix;
 
     printf("AMANDA CONFIGURATION FROM FILE \"%s\":\n\n", filename);
 
-    printf("conf_org = \"%s\"\n", getconf_str(CNF_ORG));
-    printf("conf_mailto = \"%s\"\n", getconf_str(CNF_MAILTO));
-    printf("conf_dumpuser = \"%s\"\n", getconf_str(CNF_DUMPUSER));
-    printf("conf_printer = \"%s\"\n", getconf_str(CNF_PRINTER));
-    printf("conf_tapedev = \"%s\"\n", getconf_str(CNF_TAPEDEV));
-    printf("conf_rawtapedev = \"%s\"\n", getconf_str(CNF_RAWTAPEDEV));
-    printf("conf_tpchanger = \"%s\"\n", getconf_str(CNF_TPCHANGER));
-    printf("conf_chngrdev = \"%s\"\n", getconf_str(CNF_CHNGRDEV));
-    printf("conf_chngrfile = \"%s\"\n", getconf_str(CNF_CHNGRFILE));
-    printf("conf_labelstr = \"%s\"\n", getconf_str(CNF_LABELSTR));
-    printf("conf_tapelist = \"%s\"\n", getconf_str(CNF_TAPELIST));
-    printf("conf_infofile = \"%s\"\n", getconf_str(CNF_INFOFILE));
-    printf("conf_logdir = \"%s\"\n", getconf_str(CNF_LOGDIR));
-    printf("conf_diskfile = \"%s\"\n", getconf_str(CNF_DISKFILE));
-    printf("conf_tapetype = \"%s\"\n", getconf_str(CNF_TAPETYPE));
-
-    printf("conf_dumpcycle = %d\n", getconf_int(CNF_DUMPCYCLE));
-    printf("conf_runspercycle = %d\n", getconf_int(CNF_RUNSPERCYCLE));
-    printf("conf_runtapes = %d\n", getconf_int(CNF_RUNTAPES));
-    printf("conf_tapecycle = %d\n", getconf_int(CNF_TAPECYCLE));
-    printf("conf_bumppercent = %d\n", getconf_int(CNF_BUMPPERCENT));
-    printf("conf_bumpsize = %d\n", getconf_int(CNF_BUMPSIZE));
-    printf("conf_bumpdays = %d\n", getconf_int(CNF_BUMPDAYS));
-    printf("conf_bumpmult = %f\n", getconf_real(CNF_BUMPMULT));
-    printf("conf_netusage = %d\n", getconf_int(CNF_NETUSAGE));
-    printf("conf_inparallel = %d\n", getconf_int(CNF_INPARALLEL));
-    printf("conf_dumporder = \"%s\"\n", getconf_str(CNF_DUMPORDER));
-    /*printf("conf_timeout = %d\n", getconf_int(CNF_TIMEOUT));*/
-    printf("conf_maxdumps = %d\n", getconf_int(CNF_MAXDUMPS));
-    printf("conf_etimeout = %d\n", getconf_int(CNF_ETIMEOUT));
-    printf("conf_dtimeout = %d\n", getconf_int(CNF_DTIMEOUT));
-    printf("conf_ctimeout = %d\n", getconf_int(CNF_CTIMEOUT));
-    printf("conf_tapebufs = %d\n", getconf_int(CNF_TAPEBUFS));
-    printf("conf_autoflush  = %d\n", getconf_int(CNF_AUTOFLUSH));
-    printf("conf_reserve  = %d\n", getconf_int(CNF_RESERVE));
-    printf("conf_maxdumpsize  = " AM64_FMT "\n", getconf_am64(CNF_MAXDUMPSIZE));
-    printf("conf_amrecover_do_fsf  = %d\n", getconf_int(CNF_AMRECOVER_DO_FSF));
-    printf("conf_amrecover_check_label  = %d\n", getconf_int(CNF_AMRECOVER_CHECK_LABEL));
-    printf("conf_amrecover_changer = \"%s\"\n", getconf_str(CNF_AMRECOVER_CHANGER));
-    printf("conf_taperalgo  = %s\n", taperalgo2str(getconf_int(CNF_TAPERALGO)));
-    printf("conf_displayunit  = %s\n", getconf_str(CNF_DISPLAYUNIT));
-
-    /*printf("conf_diskdir = \"%s\"\n", getconf_str(CNF_DISKDIR));*/
-    /*printf("conf_disksize = %d\n", getconf_int(CNF_DISKSIZE));*/
-    printf("conf_columnspec = \"%s\"\n", getconf_str(CNF_COLUMNSPEC));
-    printf("conf_indexdir = \"%s\"\n", getconf_str(CNF_INDEXDIR));
-    printf("num_holdingdisks = %d\n", num_holdingdisks);
-    printf("conf_krb5keytab = \"%s\"\n", getconf_str(CNF_KRB5KEYTAB));
-    printf("conf_krb5principal = \"%s\"\n", getconf_str(CNF_KRB5PRINCIPAL));
-    printf("conf_label_new_tapes  = \"%s\"\n", getconf_str(CNF_LABEL_NEW_TAPES));
-    for(hp = holdingdisks; hp != NULL; hp = hp->next) {
-       printf("\nHOLDINGDISK %s:\n", hp->name);
-       printf("        COMMENT \"%s\"\n", hp->comment);
-       printf("        DISKDIR \"%s\"\n", hp->diskdir);
-       printf("        SIZE %ld\n", (long)hp->disksize);
-       printf("        CHUNKSIZE %ld\n", (long)hp->chunksize);
-    }
+    for(i=0; i < CNF_CNF; i++) {
+       for(np=server_var; np->token != CONF_UNKNOWN; np++) {
+           if(np->parm == i)
+               break;
+       }
+       if(np->token == CONF_UNKNOWN)
+           error("server bad value");
 
-    for(tp = tapelist; tp != NULL; tp = tp->next) {
-       printf("\nTAPETYPE %s:\n", tp->name);
-       printf("        COMMENT \"%s\"\n", tp->comment);
-       printf("        LBL_TEMPL %s\n", tp->lbl_templ);
-       printf("        BLOCKSIZE %ld\n", (long)tp->blocksize);
-       printf("        FILE_PAD %s\n", (tp->file_pad) ? "YES" : "NO");
-       printf("        LENGTH %lu\n", (unsigned long)tp->length);
-       printf("        FILEMARK %lu\n", (unsigned long)tp->filemark);
-       printf("        SPEED %ld\n", (long)tp->speed);
+       for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+           if(kt->token == np->token) break;
+       if(kt->token == CONF_UNKNOWN)
+           error("server bad token");
+
+       printf("%-21s %s\n", kt->keyword, conf_print(&server_conf[i]));
     }
 
-    for(dp = dumplist; dp != NULL; dp = dp->next) {
-       printf("\nDUMPTYPE %s:\n", dp->name);
-       printf("        COMMENT \"%s\"\n", dp->comment);
-       printf("        PROGRAM \"%s\"\n", dp->program);
-       printf("        SERVER_CUSTOM_COMPRESS \"%s\"\n", dp->srvcompprog);
-       printf("        CLIENT_CUSTOM_COMPRESS \"%s\"\n", dp->clntcompprog);
-       printf("        SERVER_ENCRYPT \"%s\"\n", dp->srv_encrypt);
-       printf("        CLIENT_ENCRYPT \"%s\"\n", dp->clnt_encrypt);
-       printf("        SERVER_DECRYPT_OPTION \"%s\"\n", dp->srv_decrypt_opt);
-       printf("        CLIENT_DECRYPT_OPTION \"%s\"\n", dp->clnt_decrypt_opt);
-       printf("        PRIORITY %ld\n", (long)dp->priority);
-       printf("        DUMPCYCLE %ld\n", (long)dp->dumpcycle);
-       st = dp->start_t;
-       if(st) {
-           stm = localtime(&st);
-           printf("    STARTTIME %d:%02d:%02d\n",
-             stm->tm_hour, stm->tm_min, stm->tm_sec);
-       }
-       if(dp->exclude_file) {
-           sle_t *excl;
-           printf("    EXCLUDE FILE");
-           for(excl = dp->exclude_file->first; excl != NULL; excl =excl->next){
-               printf(" \"%s\"", excl->name);
-           }
-           printf("\n");
-       }
-       if(dp->exclude_list) {
-           sle_t *excl;
-           printf("    EXCLUDE LIST");
-           for(excl = dp->exclude_list->first; excl != NULL; excl =excl->next){
-               printf(" \"%s\"", excl->name);
-           }
-           printf("\n");
-       }
-       if(dp->include_file) {
-           sle_t *incl;
-           printf("    INCLUDE FILE");
-           for(incl = dp->include_file->first; incl != NULL; incl =incl->next){
-               printf(" \"%s\"", incl->name);
-           }
-           printf("\n");
-       }
-       if(dp->include_list) {
-           sle_t *incl;
-           printf("    INCLUDE LIST");
-           for(incl = dp->include_list->first; incl != NULL; incl =incl->next){
-               printf(" \"%s\"", incl->name);
+    for(hp = holdingdisks; hp != NULL; hp = hp->next) {
+       printf("\nHOLDINGDISK %s {\n", hp->name);
+       for(i=0; i < HOLDING_HOLDING; i++) {
+           for(np=holding_var; np->token != CONF_UNKNOWN; np++) {
+               if(np->parm == i)
+                       break;
            }
-           printf("\n");
-       }
-       printf("        FREQUENCY %ld\n", (long)dp->frequency);
-       printf("        MAXDUMPS %d\n", dp->maxdumps);
-       printf("        MAXPROMOTEDAY %d\n", dp->maxpromoteday);
-       printf("        STRATEGY ");
-       switch(dp->strategy) {
-       case DS_SKIP:
-           printf("SKIP");
-           break;
-       case DS_STANDARD:
-           printf("STANDARD");
-           break;
-       case DS_NOFULL:
-           printf("NOFULL");
-           break;
-       case DS_NOINC:
-           printf("NOINC");
-           break;
-       case DS_HANOI:
-           printf("HANOI");
-           break;
-       case DS_INCRONLY:
-           printf("INCRONLY");
-           break;
-       }
-       putchar('\n');
-       printf("        ESTIMATE ");
-       switch(dp->estimate) {
-       case ES_CLIENT:
-           printf("CLIENT");
-           break;
-       case ES_SERVER:
-           printf("SERVER");
-           break;
-       case ES_CALCSIZE:
-           printf("CALCSIZE");
-           break;
-       }
-       putchar('\n');
-       printf("        COMPRATE %f, %f\n", dp->comprate[0], dp->comprate[1]);
+           if(np->token == CONF_UNKNOWN)
+               error("holding bad value");
 
-       printf("        OPTIONS: ");
+           for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
+               if(kt->token == np->token)
+                   break;
+           }
+           if(kt->token == CONF_UNKNOWN)
+               error("holding bad token");
 
-       switch(dp->compress) {
-       case COMP_NONE:
-           printf("NO-COMPRESS ");
-           break;
-       case COMP_FAST:
-           printf("COMPRESS-FAST ");
-           break;
-       case COMP_BEST:
-           printf("COMPRESS-BEST ");
-           break;
-       case COMP_CUST:
-           printf("COMPRESS-CUST ");
-           break;
-       case COMP_SERV_FAST:
-           printf("SRVCOMP-FAST ");
-           break;
-       case COMP_SERV_BEST:
-           printf("SRVCOMP-BEST ");
-           break;
-       case COMP_SERV_CUST:
-           printf("SRVCOMP-CUST ");
-           break;
+           printf("      %-9s %s\n", kt->keyword, conf_print(&hp->value[i]));
        }
+       printf("}\n");
+    }
 
-       switch(dp->encrypt) {
-       case ENCRYPT_NONE:
-           printf("ENCRYPT-NONE ");
-           break;
-       case ENCRYPT_CUST:
-           printf("ENCRYPT-CUST ");
-           break;
-       case ENCRYPT_SERV_CUST:
-           printf("ENCRYPT-SERV-CUST ");
-           break;
+    for(tp = tapelist; tp != NULL; tp = tp->next) {
+       printf("\nDEFINE TAPETYPE %s {\n", tp->name);
+       for(i=0; i < TAPETYPE_TAPETYPE; i++) {
+           for(np=tapetype_var; np->token != CONF_UNKNOWN; np++)
+               if(np->parm == i) break;
+           if(np->token == CONF_UNKNOWN)
+               error("tapetype bad value");
+
+           for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+               if(kt->token == np->token) break;
+           if(kt->token == CONF_UNKNOWN)
+               error("tapetype bad token");
+
+           printf("      %-9s %s\n", kt->keyword, conf_print(&tp->value[i]));
        }
+       printf("}\n");
+    }
 
-       if(!dp->record) printf("NO-");
-       printf("RECORD");
-       printf(" %s-AUTH", dp->security_driver);
-       if(dp->skip_incr) printf(" SKIP-INCR");
-       if(dp->skip_full) printf(" SKIP-FULL");
-       if(dp->no_hold) printf(" NO-HOLD");
-       if(dp->kencrypt) printf(" KENCRYPT");
-       /* an ignored disk will never reach this point */
-       assert(!dp->ignore);
-       if(dp->index) printf(" INDEX");
-       putchar('\n');
+    for(dp = dumplist; dp != NULL; dp = dp->next) {
+       if(dp->seen == -1)
+           prefix = "#";
+       else
+           prefix = "";
+       printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name);
+       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");
+
+           printf("%s      %-19s %s\n", prefix, kt->keyword, conf_print(&dp->value[i]));
+       }
+       printf("%s}\n", prefix);
     }
 
     for(ip = interface_list; ip != NULL; ip = ip->next) {
-       printf("\nINTERFACE %s:\n", ip->name);
-       printf("        COMMENT \"%s\"\n", ip->comment);
-       printf("        USE %d\n", ip->maxusage);
+       if(strcmp(ip->name,"default") == 0)
+           prefix = "#";
+       else
+           prefix = "";
+       printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name);
+       for(i=0; i < INTER_INTER; i++) {
+           for(np=interface_var; np->token != CONF_UNKNOWN; np++)
+               if(np->parm == i) break;
+           if(np->token == CONF_UNKNOWN)
+               error("interface bad value");
+
+           for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+               if(kt->token == np->token) break;
+           if(kt->token == CONF_UNKNOWN)
+               error("interface bad token");
+
+           printf("%s      %-9s %s\n", prefix, kt->keyword, conf_print(&ip->value[i]));
+       }
+       printf("%s}\n",prefix);
     }
+
 }
 
+#ifdef TEST
+
 int
-main(argc, argv)
-    int argc;
-    char *argv[];
+main(
+    int argc,
+    char *argv[])
 {
   char *conffile;
   char *diskfile;
@@ -3585,10 +2221,11 @@ main(argc, argv)
 #endif /* TEST */
 
 char *
-generic_get_security_conf(string, arg)
-       char *string;
-       void *arg;
+generic_get_security_conf(
+       char *string,
+       void *arg)
 {
+       arg = arg;
        if(!string || !*string)
                return(NULL);
 
@@ -3599,3 +2236,141 @@ generic_get_security_conf(string, arg)
        }
        return(NULL);
 }
+
+char *
+get_token_name(
+    tok_t token)
+{
+    keytab_t *kt;
+
+    for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+       if(kt->token == token) break;
+
+    if(kt->token == CONF_UNKNOWN)
+       return("");
+    return(kt->keyword);
+}
+
+void
+parse_server_conf(
+    int parse_argc,
+    char **parse_argv,
+    int *new_argc,
+    char ***new_argv)
+{
+    int i;
+    char **my_argv;
+    char *myarg, *value;
+    command_option_t *server_option;
+
+    server_options = alloc((size_t)(parse_argc+1) * SIZEOF(*server_options));
+    server_option = server_options;
+    server_option->name = NULL;
+
+    my_argv = alloc((size_t)parse_argc * SIZEOF(char *));
+    *new_argv = my_argv;
+    *new_argc = 0;
+    i=0;
+    while(i<parse_argc) {
+       if(strncmp(parse_argv[i],"-o",2) == 0) {
+           if(strlen(parse_argv[i]) > 2)
+               myarg = &parse_argv[i][2];
+           else {
+               i++;
+               if(i >= parse_argc)
+                   error("expect something after -o");
+               myarg = parse_argv[i];
+           }
+           value = index(myarg,'=');
+           if (value == NULL) {
+               conf_parserror("Must specify a value for %s.\n", myarg);
+           } else {
+               *value = '\0';
+               value++;
+               server_option->used = 0;
+               server_option->name = stralloc(myarg);
+               server_option->value = stralloc(value);
+               server_option++;
+               server_option->name = NULL;
+           }
+       }
+       else {
+           my_argv[*new_argc] = stralloc(parse_argv[i]);
+           *new_argc += 1;
+       }
+       i++;
+    }
+}
+
+void
+report_bad_conf_arg(void)
+{
+    command_option_t *command_option;
+
+    for(command_option = server_options; command_option->name != NULL;
+                                                       command_option++) {
+       if(command_option->used == 0) {
+           fprintf(stderr,"argument -o%s=%s not used\n",
+                   command_option->name, command_option->value);
+       }
+    }
+}
+
+void
+free_server_config(void)
+{
+    holdingdisk_t    *hp, *hpnext;
+    dumptype_t       *dp, *dpnext;
+    tapetype_t       *tp, *tpnext;
+    interface_t      *ip, *ipnext;
+    command_option_t *server_option;
+    int               i;
+
+    for(hp=holdingdisks; hp != NULL; hp = hpnext) {
+       amfree(hp->name);
+       for(i=0; i<HOLDING_HOLDING-1; i++) {
+          free_val_t(&hp->value[i]);
+       }
+       hpnext = hp->next;
+       amfree(hp);
+    }
+
+    for(dp=dumplist; dp != NULL; dp = dpnext) {
+       amfree(dp->name);
+       for(i=0; i<DUMPTYPE_DUMPTYPE-1; i++) {
+          free_val_t(&dp->value[i]);
+       }
+       dpnext = dp->next;
+       amfree(dp);
+    }
+
+    for(tp=tapelist; tp != NULL; tp = tpnext) {
+       amfree(tp->name);
+       for(i=0; i<TAPETYPE_TAPETYPE-1; i++) {
+          free_val_t(&tp->value[i]);
+       }
+       tpnext = tp->next;
+       amfree(tp);
+    }
+
+    for(ip=interface_list; ip != NULL; ip = ipnext) {
+       amfree(ip->name);
+       for(i=0; i<INTER_INTER-1; i++) {
+          free_val_t(&ip->value[i]);
+       }
+       ipnext = ip->next;
+       amfree(ip);
+    }
+
+    if(server_options) {
+       for(server_option = server_options; server_option->name != NULL;
+                                               server_option++) {
+           amfree(server_option->name);
+           amfree(server_option->value);
+        }
+       amfree(server_options);
+    }
+
+    for(i=0; i<CNF_CNF-1; i++)
+       free_val_t(&server_conf[i]);
+}
index ef6c165da3400fa0c534501fac36c2db2c0feaac..4a46da51b0c63705b558c4efeb33b484b77774e5 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: conffile.h,v 1.60 2005/12/21 19:07:50 paddy_s Exp $
+ * $Id: conffile.h,v 1.72 2006/07/26 15:17:37 martinea Exp $
  *
  * interface for config file reading code
  */
 #define CONFFILE_H
 
 #include "amanda.h"
-#include "sl.h"
+#include "util.h"
 
 #define CONFFILE_NAME "amanda.conf"
 
-typedef enum conf_e {
+typedef enum {
     CNF_ORG,
     CNF_MAILTO,
     CNF_DUMPUSER,
@@ -49,18 +49,14 @@ typedef enum conf_e {
     CNF_DISKFILE,
     CNF_INFOFILE,
     CNF_LOGDIR,
-    CNF_DISKDIR,
     CNF_INDEXDIR,
     CNF_TAPETYPE,
     CNF_DUMPCYCLE,
     CNF_RUNSPERCYCLE,
-    CNF_MAXCYCLE,
     CNF_TAPECYCLE,
-    CNF_DISKSIZE,
     CNF_NETUSAGE,
     CNF_INPARALLEL,
     CNF_DUMPORDER,
-    CNF_TIMEOUT,
     CNF_BUMPPERCENT,
     CNF_BUMPSIZE,
     CNF_BUMPMULT,
@@ -85,32 +81,41 @@ typedef enum conf_e {
     CNF_DISPLAYUNIT,
     CNF_KRB5KEYTAB,
     CNF_KRB5PRINCIPAL,
-    CNF_LABEL_NEW_TAPES
+    CNF_LABEL_NEW_TAPES,
+    CNF_USETIMESTAMPS,
+    CNF_CNF
 } confparm_t;
 
+typedef enum tapetype_e  {
+    TAPETYPE_COMMENT,
+    TAPETYPE_LBL_TEMPL,
+    TAPETYPE_BLOCKSIZE,
+    TAPETYPE_LENGTH,
+    TAPETYPE_FILEMARK,
+    TAPETYPE_SPEED,
+    TAPETYPE_FILE_PAD,
+    TAPETYPE_TAPETYPE
+} tapetype_ee;
+
 typedef struct tapetype_s {
     struct tapetype_s *next;
     int seen;
     char *name;
 
-    char *comment;
-    char *lbl_templ;
-    long blocksize;
-    unsigned long length;
-    unsigned long filemark;
-    int speed;
-    int file_pad;
-
-    /* seen flags */
-    int s_comment;
-    int s_lbl_templ;
-    int s_blocksize;
-    int s_file_pad;
-    int s_length;
-    int s_filemark;
-    int s_speed;
+    val_t value[TAPETYPE_TAPETYPE];
 } tapetype_t;
 
+#define tapetype_get(tapetype, field) (tapetype->field)
+#define tapetype_get_name(tapetype) tapetype->name
+#define tapetype_get_seen(tapetype) tapetype->seen
+#define tapetype_get_comment(tapetype)   get_conftype_string(&tapetype->value[TAPETYPE_COMMENT])
+#define tapetype_get_lbl_templ(tapetype) get_conftype_string(&tapetype->value[TAPETYPE_LBL_TEMPL])
+#define tapetype_get_blocksize(tapetype) get_conftype_size  (&tapetype->value[TAPETYPE_BLOCKSIZE])
+#define tapetype_get_length(tapetype)    get_conftype_am64  (&tapetype->value[TAPETYPE_LENGTH])
+#define tapetype_get_filemark(tapetype)  get_conftype_am64  (&tapetype->value[TAPETYPE_FILEMARK])
+#define tapetype_get_speed(tapetype)     get_conftype_int   (&tapetype->value[TAPETYPE_SPEED])
+#define tapetype_get_file_pad(tapetype)  get_conftype_bool  (&tapetype->value[TAPETYPE_FILE_PAD])
+
 /* Dump strategies */
 #define DS_SKIP                0       /* Don't do any dumps at all */
 #define DS_STANDARD    1       /* Standard (0 1 1 1 1 2 2 2 ...) */
@@ -126,24 +131,6 @@ typedef struct tapetype_s {
 #define ES_SERVER      1       /* server estimate */
 #define ES_CALCSIZE    2       /* calcsize estimate */
 
-/* Compression types */
-typedef enum {
-    COMP_NONE,         /* No compression */
-    COMP_FAST,         /* Fast compression on client */
-    COMP_BEST,         /* Best compression on client */
-    COMP_CUST,         /* Custom compression on client */
-    COMP_SERV_FAST,    /* Fast compression on server */
-    COMP_SERV_BEST,    /* Best compression on server */
-    COMP_SERV_CUST     /* Custom compression on server */
-} comp_t;
-
-/* Encryption types */
-typedef enum {
-    ENCRYPT_NONE,              /* No encryption */
-    ENCRYPT_CUST,              /* Custom encryption on client */
-    ENCRYPT_SERV_CUST,         /* Custom encryption on server */
-} encrypt_t;
-
 #define ALGO_FIRST     0
 #define ALGO_FIRSTFIT  1
 #define ALGO_LARGEST   2
@@ -151,145 +138,161 @@ typedef enum {
 #define ALGO_SMALLEST  4
 #define ALGO_LAST      5
 
+typedef enum dumptype_e  {
+    DUMPTYPE_COMMENT,
+    DUMPTYPE_PROGRAM,
+    DUMPTYPE_SRVCOMPPROG,
+    DUMPTYPE_CLNTCOMPPROG,
+    DUMPTYPE_SRV_ENCRYPT,
+    DUMPTYPE_CLNT_ENCRYPT,
+    DUMPTYPE_AMANDAD_PATH,
+    DUMPTYPE_CLIENT_USERNAME,
+    DUMPTYPE_SSH_KEYS,
+    DUMPTYPE_SECURITY_DRIVER,
+    DUMPTYPE_EXCLUDE,
+    DUMPTYPE_INCLUDE,
+    DUMPTYPE_PRIORITY,
+    DUMPTYPE_DUMPCYCLE,
+    DUMPTYPE_MAXDUMPS,
+    DUMPTYPE_MAXPROMOTEDAY,
+    DUMPTYPE_BUMPPERCENT,
+    DUMPTYPE_BUMPSIZE,
+    DUMPTYPE_BUMPDAYS,
+    DUMPTYPE_BUMPMULT,
+    DUMPTYPE_START_T,
+    DUMPTYPE_STRATEGY,
+    DUMPTYPE_ESTIMATE,
+    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_DUMPTYPE
+} dumptype_ee;
+
 typedef struct dumptype_s {
     struct dumptype_s *next;
     int seen;
     char *name;
 
-    char *comment;
-    char *program;
-    char *srvcompprog;
-    char *clntcompprog;
-    char *srv_encrypt;
-    char *clnt_encrypt;
-    sl_t *exclude_file;
-    sl_t *exclude_list;
-    sl_t *include_file;
-    sl_t *include_list;
-    int exclude_optional;
-    int include_optional;
-    int priority;
-    int dumpcycle;
-    int maxcycle;
-    int frequency;
-    char *security_driver;
-    int maxdumps;
-    int maxpromoteday;
-    int bumppercent;
-    int bumpsize;
-    int bumpdays;
-    double bumpmult;
-    time_t start_t;
-    int strategy;
-    int estimate;
-    comp_t compress;
-    encrypt_t encrypt;
-    char *srv_decrypt_opt;
-    char *clnt_decrypt_opt;
-    float comprate[2]; /* first is full, second is incremental */
-    long tape_splitsize;
-    char *split_diskbuffer;
-    long fallback_splitsize;
-    /* flag options */
-    unsigned int record:1;
-    unsigned int skip_incr:1;
-    unsigned int skip_full:1;
-    unsigned int no_hold:1;
-    unsigned int kencrypt:1;
-    unsigned int ignore:1;
-    unsigned int index:1;
-
-    /* seen flags */
-    int s_comment;
-    int s_program;
-    int s_srvcompprog;
-    int s_clntcompprog;
-    int s_srv_encrypt;
-    int s_clnt_encrypt;
-    int s_exclude_file;
-    int s_exclude_list;
-    int s_include_file;
-    int s_include_list;
-    int s_exclude_optional;
-    int s_include_optional;
-    int s_priority;
-    int s_dumpcycle;
-    int s_maxcycle;
-    int s_frequency;
-    int s_security_driver;
-    int s_maxdumps;
-    int s_maxpromoteday;
-    int s_bumppercent;
-    int s_bumpsize;
-    int s_bumpdays;
-    int s_bumpmult;
-    int s_start_t;
-    int s_strategy;
-    int s_estimate;
-    int s_compress;
-    int s_encrypt;
-    int s_srv_decrypt_opt;
-    int s_clnt_decrypt_opt;
-    int s_comprate;
-    int s_record;
-    int s_skip_incr;
-    int s_skip_full;
-    int s_no_hold;
-    int s_kencrypt;
-    int s_ignore;
-    int s_index;
-    int s_tape_splitsize;
-    int s_split_diskbuffer;
-    int s_fallback_splitsize;
+    val_t value[DUMPTYPE_DUMPTYPE];
 } dumptype_t;
 
+#define dumptype_get_name(dumptype) dumptype->name
+#define dumptype_get_seen(dumptype) dumptype->seen
+#define dumptype_get_comment(dumptype)            get_conftype_string   (&dumptype->value[DUMPTYPE_COMMENT])
+#define dumptype_get_program(dumptype)            get_conftype_string   (&dumptype->value[DUMPTYPE_PROGRAM])
+#define dumptype_get_srvcompprog(dumptype)        get_conftype_string   (&dumptype->value[DUMPTYPE_SRVCOMPPROG])
+#define dumptype_get_clntcompprog(dumptype)       get_conftype_string   (&dumptype->value[DUMPTYPE_CLNTCOMPPROG])
+#define dumptype_get_srv_encrypt(dumptype)        get_conftype_string   (&dumptype->value[DUMPTYPE_SRV_ENCRYPT])
+#define dumptype_get_clnt_encrypt(dumptype)       get_conftype_string   (&dumptype->value[DUMPTYPE_CLNT_ENCRYPT])
+#define dumptype_get_amandad_path(dumptype)       get_conftype_string   (&dumptype->value[DUMPTYPE_AMANDAD_PATH])
+#define dumptype_get_client_username(dumptype)    get_conftype_string   (&dumptype->value[DUMPTYPE_CLIENT_USERNAME])
+#define dumptype_get_ssh_keys(dumptype)           get_conftype_string   (&dumptype->value[DUMPTYPE_SSH_KEYS])
+#define dumptype_get_security_driver(dumptype)    get_conftype_string   (&dumptype->value[DUMPTYPE_SECURITY_DRIVER])
+#define dumptype_get_exclude(dumptype)            get_conftype_exinclude(&dumptype->value[DUMPTYPE_EXCLUDE])
+#define dumptype_get_include(dumptype)            get_conftype_exinclude(&dumptype->value[DUMPTYPE_INCLUDE])
+#define dumptype_get_priority(dumptype)           get_conftype_priority (&dumptype->value[DUMPTYPE_PRIORITY])
+#define dumptype_get_dumpcycle(dumptype)          get_conftype_int      (&dumptype->value[DUMPTYPE_DUMPCYCLE])
+#define dumptype_get_maxcycle(dumptype)           get_conftype_int      (&dumptype->value[DUMPTYPE_MAXCYCLE])
+#define dumptype_get_frequency(dumptype)          get_conftype_int      (&dumptype->value[DUMPTYPE_FREQUENCY])
+#define dumptype_get_maxdumps(dumptype)           get_conftype_int      (&dumptype->value[DUMPTYPE_MAXDUMPS])
+#define dumptype_get_maxpromoteday(dumptype)      get_conftype_int      (&dumptype->value[DUMPTYPE_MAXPROMOTEDAY])
+#define dumptype_get_bumppercent(dumptype)        get_conftype_int      (&dumptype->value[DUMPTYPE_BUMPPERCENT])
+#define dumptype_get_bumpsize(dumptype)           get_conftype_am64     (&dumptype->value[DUMPTYPE_BUMPSIZE])
+#define dumptype_get_bumpdays(dumptype)           get_conftype_int      (&dumptype->value[DUMPTYPE_BUMPDAYS])
+#define dumptype_get_bumpmult(dumptype)           get_conftype_real     (&dumptype->value[DUMPTYPE_BUMPMULT])
+#define dumptype_get_start_t(dumptype)            get_conftype_time     (&dumptype->value[DUMPTYPE_START_T])
+#define dumptype_get_strategy(dumptype)           get_conftype_strategy (&dumptype->value[DUMPTYPE_STRATEGY])
+#define dumptype_get_estimate(dumptype)           get_conftype_estimate (&dumptype->value[DUMPTYPE_ESTIMATE])
+#define dumptype_get_compress(dumptype)           get_conftype_compress (&dumptype->value[DUMPTYPE_COMPRESS])
+#define dumptype_get_encrypt(dumptype)            get_conftype_encrypt  (&dumptype->value[DUMPTYPE_ENCRYPT])
+#define dumptype_get_srv_decrypt_opt(dumptype)    get_conftype_string   (&dumptype->value[DUMPTYPE_SRV_DECRYPT_OPT])
+#define dumptype_get_clnt_decrypt_opt(dumptype)   get_conftype_string   (&dumptype->value[DUMPTYPE_CLNT_DECRYPT_OPT])
+#define dumptype_get_comprate(dumptype)                                   dumptype->value[DUMPTYPE_COMPRATE].v.rate
+#define dumptype_get_tape_splitsize(dumptype)     get_conftype_am64     (&dumptype->value[DUMPTYPE_TAPE_SPLITSIZE])
+#define dumptype_get_fallback_splitsize(dumptype) get_conftype_am64     (&dumptype->value[DUMPTYPE_FALLBACK_SPLITSIZE])
+#define dumptype_get_split_diskbuffer(dumptype)   get_conftype_string   (&dumptype->value[DUMPTYPE_SPLIT_DISKBUFFER])
+#define dumptype_get_record(dumptype)             get_conftype_bool     (&dumptype->value[DUMPTYPE_RECORD])
+#define dumptype_get_skip_incr(dumptype)          get_conftype_bool     (&dumptype->value[DUMPTYPE_SKIP_INCR])
+#define dumptype_get_skip_full(dumptype)          get_conftype_bool     (&dumptype->value[DUMPTYPE_SKIP_FULL])
+#define dumptype_get_to_holdingdisk(dumptype)     get_conftype_hold     (&dumptype->value[DUMPTYPE_HOLDINGDISK])
+#define dumptype_get_kencrypt(dumptype)           get_conftype_bool     (&dumptype->value[DUMPTYPE_KENCRYPT])
+#define dumptype_get_ignore(dumptype)             get_conftype_bool     (&dumptype->value[DUMPTYPE_IGNORE])
+#define dumptype_get_index(dumptype)              get_conftype_bool     (&dumptype->value[DUMPTYPE_INDEX])
+
 /* A network interface */
+typedef enum interface_e  {
+    INTER_COMMENT,
+    INTER_MAXUSAGE,
+    INTER_INTER
+} interface_ee;
+
+
 typedef struct interface_s {
     struct interface_s *next;
     int seen;
     char *name;
 
-    char *comment;
-    int maxusage;              /* bandwidth we can consume [kb/s] */
+    val_t value[INTER_INTER];
 
-    /* seen flags */
-    int s_comment;
-    int s_maxusage;
-
-    int curusage;              /* current usage */
+    unsigned long curusage;            /* current usage */
 } interface_t;
 
+#define interface_get_name(interface) interface->name
+#define interface_get_seen(interface) interface->seen
+#define interface_get_comment(interface)  get_conftype_string(&interface->value[INTER_COMMENT])
+#define interface_get_maxusage(interface) get_conftype_int   (&interface->value[INTER_MAXUSAGE])
+
 /* A holding disk */
+typedef enum holdingdisk_e  {
+    HOLDING_COMMENT,
+    HOLDING_DISKDIR,
+    HOLDING_DISKSIZE,
+    HOLDING_CHUNKSIZE,
+    HOLDING_HOLDING
+} holdingdisk_ee;
+
 typedef struct holdingdisk_s {
     struct holdingdisk_s *next;
     int seen;
     char *name;
 
-    char *comment;
-    char *diskdir;
-    long disksize;
-    long chunksize;
-
-    int s_comment;
-    int s_disk;
-    int s_size;
-    int s_csize;
+    val_t value[HOLDING_HOLDING];
 
     void *up;                  /* generic user pointer */
+    off_t disksize;
 } holdingdisk_t;
 
+#define holdingdisk_get_name(holdingdisk) (holdingdisk)->name
+#define holdingdisk_get_seen(holdingdisk) (holdingdisk)->seen
+#define holdingdisk_get_comment(holdingdisk)   get_conftype_string(&(holdingdisk)->value[HOLDING_COMMENT])
+#define holdingdisk_get_diskdir(holdingdisk)   get_conftype_string(&(holdingdisk)->value[HOLDING_DISKDIR])
+#define holdingdisk_get_disksize(holdingdisk)  get_conftype_am64  (&(holdingdisk)->value[HOLDING_DISKSIZE])
+#define holdingdisk_get_chunksize(holdingdisk) get_conftype_am64  (&(holdingdisk)->value[HOLDING_CHUNKSIZE])
+
 /* for each column we define some values on how to
  * format this column element
  */
 typedef struct {
     char *Name;                /* column name */
-    char PrefixSpace;  /* the blank space to print before this
+    int PrefixSpace;   /* the blank space to print before this
                         * column. It is used to get the space
                         * between the colums
                         */
-    char Width;                /* the widht of the column itself */
-    char Precision;    /* the precision if its a float */
-    char MaxWidth;     /* if set, Width will be recalculated
+    int Width;         /* the width of the column itself */
+    int Precision;     /* the precision if its a float */
+    int MaxWidth;      /* if set, Width will be recalculated
                         * to the space needed */
     char *Format;      /* the printf format string for this
                         * column element
@@ -308,27 +311,35 @@ extern char *config_dir;
 extern holdingdisk_t *holdingdisks;
 extern int num_holdingdisks;
 
-int read_conffile P((char *filename));
-int getconf_seen P((confparm_t parameter));
-int getconf_int P((confparm_t parameter));
-am64_t getconf_am64 P((confparm_t parameter));
-double getconf_real P((confparm_t parameter));
-char *getconf_str P((confparm_t parameter));
-char *getconf_byname P((char *confname));
-dumptype_t *lookup_dumptype P((char *identifier));
-dumptype_t *read_dumptype P((char *name, FILE *from, char *fname, int *linenum));
-tapetype_t *lookup_tapetype P((char *identifier));
-interface_t *lookup_interface P((char *identifier));
-holdingdisk_t *getconf_holdingdisks P((void));
-long int getconf_unit_divisor P((void));
-
-int ColumnDataCount P((void));
-int StringToColumn P((char *s));
-char LastChar P((char *s));
-int SetColumDataFromString P((ColumnInfo* ci, char *s, char **errstr));
-
-char *taperalgo2str P((int taperalgo));
+void parse_server_conf(int parse_argc, char **parse_argv, int *new_argc,
+                      char ***new_argv);
+void report_bad_conf_arg(void);
+void free_server_config(void);
+
+int read_conffile(char *filename);
+int getconf_seen(confparm_t parameter);
+int getconf_boolean(confparm_t parameter);
+int getconf_int(confparm_t parameter);
+long getconf_long(confparm_t parameter);
+ssize_t getconf_size(confparm_t parameter);
+time_t getconf_time(confparm_t parameter);
+off_t getconf_am64(confparm_t parameter);
+double getconf_real(confparm_t parameter);
+char *getconf_str(confparm_t parameter);
+int getconf_taperalgo(confparm_t parameter);
+char *getconf_byname(char *confname);
+dumptype_t *lookup_dumptype(char *identifier);
+dumptype_t *read_dumptype(char *name, FILE *from, char *fname, int *linenum);
+tapetype_t *lookup_tapetype(char *identifier);
+interface_t *lookup_interface(char *identifier);
+holdingdisk_t *getconf_holdingdisks(void);
+long int getconf_unit_divisor(void);
+void dump_configuration(char *filename);
+int ColumnDataCount(void);
+int StringToColumn(char *s);
+char LastChar(char *s);
+int SetColumDataFromString(ColumnInfo* ci, char *s, char **errstr);
 
 /* this is in securityconf.h */
-char *generic_get_security_conf P((char *, void *));
+char *generic_get_security_conf(char *, void *);
 #endif /* ! CONFFILE_H */
index 8d465bb8e5c8201663fede3bbb002a16334b2c5b..1e02f74225a8a575aa62d15fdd71b6f275ed34cd 100644 (file)
@@ -23,7 +23,7 @@
  * Authors: the Amanda Development Team.  Its members are listed in a
  * file named AUTHORS, in the root directory of this distribution.
  */
-/* $Id: disk_history.c,v 1.12 2006/01/16 00:07:01 martinea Exp $
+/* $Id: disk_history.c,v 1.13 2006/05/25 01:47:19 johnfranks Exp $
  *
  * functions for obtaining backup history
  */
@@ -33,7 +33,8 @@
 
 static DUMP_ITEM *disk_hist = NULL;
 
-void clear_list P((void))
+void
+clear_list(void)
 {
     DUMP_ITEM *item, *this;
 
@@ -55,28 +56,31 @@ void clear_list P((void))
 }
 
 /* add item, maintain list ordered by oldest date last */
-void add_dump(date, level, tape, file, partnum)
-char *date;
-int level;
-char *tape;
-int file;
-int partnum;
+
+void
+add_dump(
+    char *     date,
+    int                level,
+    char *     tape,
+    off_t      file,
+    int                partnum)
 {
     DUMP_ITEM *new, *item, *before;
     int isafile = 0;
 
-    new = (DUMP_ITEM *)alloc(sizeof(DUMP_ITEM));
-    strncpy(new->date, date, sizeof(new->date)-1);
-    new->date[sizeof(new->date)-1] = '\0';
+    new = (DUMP_ITEM *)alloc(SIZEOF(DUMP_ITEM));
+    strncpy(new->date, date, SIZEOF(new->date)-1);
+    new->date[SIZEOF(new->date)-1] = '\0';
     new->level = level;
-    strncpy(new->tape, tape, sizeof(new->tape)-1);
-    new->tape[sizeof(new->tape)-1] = '\0';
+    strncpy(new->tape, tape, SIZEOF(new->tape)-1);
+    new->tape[SIZEOF(new->tape)-1] = '\0';
     new->file = file;
     if(partnum == -1) new->is_split = 0;
     else new->is_split = 1;
     new->tapes = NULL;
 
-   if(new->tape[0] == '/') isafile = 1; /* XXX kludgey, like this whole thing */
+    if(new->tape[0] == '/')
+       isafile = 1; /* XXX kludgey, like this whole thing */
 
     if (disk_hist == NULL)
     {
@@ -123,13 +127,8 @@ int partnum;
 }
 
 
-DUMP_ITEM *first_dump P((void))
+DUMP_ITEM *
+first_dump(void)
 {
     return disk_hist;
 }
-
-DUMP_ITEM *next_dump(item)
-DUMP_ITEM *item;
-{
-    return item->next;
-}
index b10f0358c364bad6016b867c9d56f81b4d047f12..71d9866fb8c26ac8e1a932b935632720b8c99c8c 100644 (file)
  * Authors: the Amanda Development Team.  Its members are listed in a
  * file named AUTHORS, in the root directory of this distribution.
  */
-/* $Id: disk_history.h,v 1.4 2005/10/11 01:17:01 vectro Exp $
+/* $Id: disk_history.h,v 1.6 2006/05/25 01:47:19 johnfranks Exp $
  *
  * interface for obtaining disk backup history
  */
+#ifndef DISK_HISTORY_H
+#define DISK_HISTORY_H
 
 #include "tapelist.h"
 
 typedef struct DUMP_ITEM
 {
-    char date[11];
+    char date[20];
     int  level;
     int  is_split;
     char tape[256];
     tapelist_t *tapes;
-    int  file;
+    off_t  file;
 
     struct DUMP_ITEM *next;
 }
 DUMP_ITEM;
 
-extern void clear_list P((void));
-extern void add_dump P((char *date, int level, char *tape, int file, int partnum));
-extern DUMP_ITEM *first_dump P((void));
-extern DUMP_ITEM *next_dump P((DUMP_ITEM *item));
+#define next_dump(item)        ((item)->next)
+
+extern void clear_list(void);
+extern void add_dump(char *date, int level, char *tape, off_t file, int partnum);
+extern DUMP_ITEM *first_dump(void);
+#endif /* !DISK_HISTORY_H */
index a224eeeeba99b6d82d7e0fa4bad2e378db54fb80..0222a7de46caf5f72fec5daf670733964a870aa6 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: diskfile.c,v 1.73 2006/03/10 13:51:06 martinea Exp $
+ * $Id: diskfile.c,v 1.95 2006/07/26 15:17:37 martinea Exp $
  *
  * read disklist file
  */
 static am_host_t *hostlist;
 
 /* local functions */
-static char *upcase P((char *st));
-static int parse_diskline P((disklist_t *, const char *, FILE *, int *, char **));
-static void parserror P((const char *, int, const char *, ...))
+static char *upcase(char *st);
+static int parse_diskline(disklist_t *, const char *, FILE *, int *, char **);
+static void disk_parserror(const char *, int, const char *, ...)
     __attribute__ ((format (printf, 3, 4)));
 
 
 int
-read_diskfile(filename, lst)
-    const char *filename;
-    disklist_t *lst;
+read_diskfile(
+    const char *filename,
+    disklist_t *lst)
 {
     FILE *diskf;
     int line_num;
     char *line;
 
     /* initialize */
-
     hostlist = NULL;
     lst->head = lst->tail = NULL;
     line_num = 0;
 
     if ((diskf = fopen(filename, "r")) == NULL) {
-       error("could not open disklist file \"%s\": %s",
-             filename, strerror(errno));
+       return -1;
+        /*NOTREACHED*/
     }
 
     while ((line = agets(diskf)) != NULL) {
        line_num++;
-       if (parse_diskline(lst, filename, diskf, &line_num, &line) < 0) {
-           amfree(line);
-           afclose(diskf);
-           return (-1);
+       if (line[0] != '\0') {
+           if (parse_diskline(lst, filename, diskf, &line_num, &line) < 0) {
+               amfree(line);
+               afclose(diskf);
+               return (-1);
+           }
        }
        amfree(line);
     }
@@ -79,8 +80,8 @@ read_diskfile(filename, lst)
 }
 
 am_host_t *
-lookup_host(hostname)
-    const char *hostname;
+lookup_host(
+    const char *hostname)
 {
     am_host_t *p;
 
@@ -91,8 +92,9 @@ lookup_host(hostname)
 }
 
 disk_t *
-lookup_disk(hostname, diskname)
-    const char *hostname, *diskname;
+lookup_disk(
+    const char *hostname,
+    const char *diskname)
 {
     am_host_t *host;
     disk_t *disk;
@@ -108,9 +110,15 @@ lookup_disk(hostname, diskname)
     return (NULL);
 }
 
-void enqueue_disk(list, disk)  /* put disk on end of queue */
-disklist_t *list;
-disk_t *disk;
+
+/*
+ * put disk on end of queue
+ */
+
+void
+enqueue_disk(
+    disklist_t *list,
+    disk_t *   disk)
 {
     if(list->tail == NULL) list->head = disk;
     else list->tail->next = disk;
@@ -120,9 +128,15 @@ disk_t *disk;
     disk->next = NULL;
 }
 
-void headqueue_disk(list, disk)        /* put disk on head of queue */
-disklist_t *list;
-disk_t *disk;
+
+/*
+ * put disk on head of queue
+ */
+
+void
+headqueue_disk(
+    disklist_t *list,
+    disk_t *   disk)
 {
     if(list->head == NULL) list->tail = disk;
     else list->head->prev = disk;
@@ -132,10 +146,16 @@ disk_t *disk;
     disk->prev = NULL;
 }
 
-void insert_disk(list, disk, cmp)      /* insert in sorted order */
-disklist_t *list;
-disk_t *disk;
-int (*cmp) P((disk_t *a, disk_t *b));
+
+/*
+ * insert in sorted order
+ */
+
+void
+insert_disk(
+    disklist_t *list,
+    disk_t *   disk,
+    int                (*cmp)(disk_t *a, disk_t *b))
 {
     disk_t *prev, *ptr;
 
@@ -156,19 +176,20 @@ int (*cmp) P((disk_t *a, disk_t *b));
     else ptr->prev = disk;
 }
 
-disk_t *add_disk(list, hostname, diskname)
-disklist_t *list;
-char *hostname;
-char *diskname;
+disk_t *
+add_disk(
+    disklist_t *list,
+    char *     hostname,
+    char *     diskname)
 {
     disk_t *disk;
     am_host_t *host;
 
-    disk = alloc(sizeof(disk_t));
+    disk = alloc(SIZEOF(disk_t));
     disk->line = 0;
-    disk->tape_splitsize = 0;
+    disk->tape_splitsize = (off_t)0;
     disk->split_diskbuffer = NULL;
-    disk->fallback_splitsize = 0;
+    disk->fallback_splitsize = (off_t)0;
     disk->name = stralloc(diskname);
     disk->device = stralloc(diskname);
     disk->spindle = -1;
@@ -177,10 +198,15 @@ char *diskname;
     disk->encrypt  = ENCRYPT_NONE;
     disk->start_t = 0;
     disk->todo = 1;
+    disk->index = 1;
+    disk->exclude_list = NULL;
+    disk->exclude_file = NULL;
+    disk->include_list = NULL;
+    disk->include_file = NULL;
 
     host = lookup_host(hostname);
     if(host == NULL) {
-       host = alloc(sizeof(am_host_t));
+       host = alloc(SIZEOF(am_host_t));
        host->next = hostlist;
        hostlist = host;
 
@@ -202,22 +228,35 @@ char *diskname;
     return disk;
 }
 
-int find_disk(list, disk)
-disklist_t *list;
-disk_t *disk;
-/* check if disk is present in list. Return true if so, false otherwise. */
-{
-disk_t *t;
 
-    for( t = list->head; t && t != disk; t = t->next );
+/*
+ * check if disk is present in list. Return true if so, false otherwise.
+ */
 
-    return t == disk;
+int
+find_disk(
+    disklist_t *list,
+    disk_t *   disk)
+{
+    disk_t *t;
+
+    t = list->head;
+    while ((t != NULL) && (t != disk)) {
+        t = t->next;
+    }
+    return (t == disk);
 }
 
-void sort_disk(in, out, cmp)   /* sort a whole queue */
-disklist_t *in;
-disklist_t *out;
-int (*cmp) P((disk_t *a, disk_t *b));
+
+/*
+ * sort a whole queue
+ */
+
+void
+sort_disk(
+    disklist_t *in,
+    disklist_t *out,
+    int                (*cmp)(disk_t *a, disk_t *b))
 {
     disklist_t *tmp;
     disk_t *disk;
@@ -231,8 +270,14 @@ int (*cmp) P((disk_t *a, disk_t *b));
        insert_disk(out, disk, cmp);
 }
 
-disk_t *dequeue_disk(list)     /* remove disk from front of queue */
-disklist_t *list;
+
+/*
+ * remove disk from front of queue
+ */
+
+disk_t *
+dequeue_disk(
+    disklist_t *list)
 {
     disk_t *disk;
 
@@ -248,9 +293,10 @@ disklist_t *list;
     return disk;
 }
 
-void remove_disk(list, disk)
-disklist_t *list;
-disk_t *disk;
+void
+remove_disk(
+    disklist_t *list,
+    disk_t *   disk)
 {
     if(disk->prev == NULL) list->head = disk->next;
     else disk->prev->next = disk->next;
@@ -261,32 +307,56 @@ disk_t *disk;
     disk->prev = disk->next = NULL;
 }
 
-void free_disklist(disklist_t* dl) {
-  while (dl->head != NULL) {
-    free(dequeue_disk(dl));
-  }
+void
+free_disklist(
+    disklist_t* dl)
+{
+    disk_t    *dp;
+    am_host_t *host, *hostnext;
+
+    while (dl->head != NULL) {
+       dp = dequeue_disk(dl);
+       amfree(dp->name);
+       free_sl(dp->exclude_file);
+       free_sl(dp->exclude_list);
+       free_sl(dp->include_file);
+       free_sl(dp->include_list);
+       free(dp);
+    }
+
+    for(host=hostlist; host != NULL; host = hostnext) {
+       amfree(host->hostname);
+       am_release_feature_set(host->features);
+       host->features = NULL;
+       hostnext = host->next;
+       amfree(host);
+    }
+    hostlist=NULL;
 }
 
-static char *upcase(st)
-char *st;
+static char *
+upcase(
+    char *st)
 {
     char *s = st;
 
     while(*s) {
-       if(islower((int)*s)) *s = toupper((int)*s);
+       if(islower((int)*s)) *s = (char)toupper((int)*s);
        s++;
     }
     return st;
 }
 
 
+/* return  0 on success */
+/* return -1 on error   */
 static int
-parse_diskline(lst, filename, diskf, line_num_p, line_p)
-    disklist_t *lst;
-    const char *filename;
-    FILE *diskf;
-    int *line_num_p;
-    char **line_p;
+parse_diskline(
+    disklist_t *lst,
+    const char *filename,
+    FILE *     diskf,
+    int *      line_num_p,
+    /*@keep@*/ char ** line_p)
 {
     am_host_t *host;
     disk_t *disk;
@@ -294,6 +364,7 @@ parse_diskline(lst, filename, diskf, line_num_p, line_p)
     interface_t *netif = 0;
     char *hostname = NULL;
     char *diskname, *diskdevice;
+    char *dumptype;
     char *s, *fp;
     int ch, dup = 0;
     char *line = *line_p;
@@ -322,52 +393,60 @@ parse_diskline(lst, filename, diskf, line_num_p, line_p)
 
     skip_whitespace(s, ch);
     if(ch == '\0' || ch == '#') {
-       parserror(filename, line_num, "disk device name expected");
-       if (host == NULL) amfree(hostname);
+       disk_parserror(filename, line_num, "disk device name expected");
+       amfree(hostname);
        return (-1);
     }
+
     fp = s - 1;
-    skip_non_whitespace(s, ch);
+    skip_quoted_string(s, ch);
     s[-1] = '\0';
-    diskname = stralloc(fp);
+    diskname = unquote_string(fp);
 
     skip_whitespace(s, ch);
     if(ch == '\0' || ch == '#') {
-       parserror(filename, line_num, "disk dumptype expected");
-       if(host == NULL) amfree(hostname);
+       disk_parserror(filename, line_num, "disk dumptype expected");
+       amfree(hostname);
        amfree(diskname);
-       return 1;
+       return (-1);
     }
     fp = s - 1;
-    skip_non_whitespace(s, ch);
+    skip_quoted_string(s, ch);
     s[-1] = '\0';
 
     /* diskdevice */
-    diskdevice = stralloc(fp);
-    if(fp[0] != '{' && (dtype = lookup_dumptype(upcase(fp))) == NULL) {
-       skip_whitespace(s, ch);
-       if(ch == '\0' || ch == '#') {
-           parserror(filename, line_num, "disk dumptype expected");
-           if(host == NULL) amfree(hostname);
-           amfree(diskdevice);
-           amfree(diskname);
-           return 1;
+    dumptype = NULL;
+    diskdevice = NULL;
+    dumptype = unquote_string(fp);
+    if(fp[0] != '{') {
+       if ((dtype = lookup_dumptype(dumptype)) == NULL) {
+           diskdevice = dumptype;
+           skip_whitespace(s, ch);
+           if(ch == '\0' || ch == '#') {
+               disk_parserror(filename, line_num,
+                       "disk dumptype '%s' not found", dumptype);
+               amfree(hostname);
+               amfree(diskdevice);
+               amfree(diskname);
+               return (-1);
+           }
+
+           fp = s - 1;
+           skip_quoted_string(s, ch);
+           s[-1] = '\0';
+           dumptype = unquote_string(fp);
        }
-       fp = s - 1;
-       skip_non_whitespace(s, ch);
-       s[-1] = '\0';
-    }
-    else {
-       amfree(diskdevice);
     }
+    else
+       amfree(dumptype);
 
     /* check for duplicate disk */
     if(host && (disk = lookup_disk(hostname, diskname)) != NULL) {
-       parserror(filename, line_num,
+       disk_parserror(filename, line_num,
            "duplicate disk record, previous on line %d", disk->line);
        dup = 1;
     } else {
-       disk = alloc(sizeof(disk_t));
+       disk = alloc(SIZEOF(disk_t));
        malloc_mark(disk);
        disk->line = line_num;
        disk->name = diskname;
@@ -379,18 +458,19 @@ parse_diskline(lst, filename, diskf, line_num_p, line_p)
     }
 
     if (fp[0] == '{') {
-       s[-1] = ch;
+       s[-1] = (char)ch;
        s = fp+2;
        skip_whitespace(s, ch);
        if (ch != '\0' && ch != '#') {
-           parserror(filename, line_num,
+           disk_parserror(filename, line_num,
                      "expected line break after `{\', ignoring rest of line");
        }
 
        if (strchr(s-1, '}') &&
            (strchr(s-1, '#') == NULL ||
             strchr(s-1, '}') < strchr(s-1, '#'))) {
-           if(host == NULL) amfree(hostname);
+           disk_parserror(filename, line_num,"'}' on same line than '{'");
+           amfree(hostname);
            if(!dup) {
                amfree(disk->device);
                amfree(disk->name);
@@ -406,12 +486,10 @@ parse_diskline(lst, filename, diskf, line_num_p, line_p)
        dtype = read_dumptype(vstralloc("custom(", hostname,
                                        ":", disk->name, ")", 0),
                              diskf, (char*)filename, line_num_p);
-
-       *line_p = line = agets(diskf);
-       line_num = *line_num_p; /* no incr, read_dumptype did it already */
-
        if (dtype == NULL || dup) {
-           if(host == NULL) amfree(hostname);
+           disk_parserror(filename, line_num,
+                          "read of custom dumptype failed");
+           amfree(hostname);
            if(!dup) {
                amfree(disk->device);
                amfree(disk->name);
@@ -423,78 +501,109 @@ parse_diskline(lst, filename, diskf, line_num_p, line_p)
            return (-1);
        }
 
+       *line_p = line = agets(diskf);
+       line_num = *line_num_p; /* no incr, read_dumptype did it already */
+
        if (line == NULL)
            *line_p = line = stralloc("");
        s = line;
        ch = *s++;
-    } else if((dtype = lookup_dumptype(upcase(fp))) == NULL) {
-       parserror(filename, line_num, "undefined dumptype `%s'", fp);
-       if(host == NULL) amfree(hostname);
-       if (!dup) {
-           amfree(disk->device);
-           amfree(disk->name);
-           amfree(disk);
-       } else {
-           amfree(diskdevice);
-           amfree(diskname);
+    } else {
+       if((dtype = lookup_dumptype(dumptype)) == NULL) {
+           char *qdt = quote_string(dumptype);
+
+           disk_parserror(filename, line_num, "undefined dumptype `%s'", qdt);
+           amfree(qdt);
+           amfree(dumptype);
+           amfree(hostname);
+           if (!dup) {
+               amfree(disk->device);
+               amfree(disk->name);
+               amfree(disk);
+           } else {
+               amfree(diskdevice);
+               amfree(diskname);
+           }
+           return (-1);
        }
-       return (-1);
     }
 
     if (dup) {
-       if (host == NULL) amfree(hostname);
+       amfree(hostname);
        amfree(diskdevice);
        amfree(diskname);
        return (-1);
     }
 
-    disk->dtype_name   = dtype->name;
-    disk->program      = dtype->program;
-    disk->exclude_file = duplicate_sl(dtype->exclude_file);
-    disk->exclude_list = duplicate_sl(dtype->exclude_list);
-    disk->include_file = duplicate_sl(dtype->include_file);
-    disk->include_list = duplicate_sl(dtype->include_list);
-    disk->exclude_optional = dtype->exclude_optional;
-    disk->include_optional = dtype->include_optional;
-    disk->priority     = dtype->priority;
-    disk->dumpcycle    = dtype->dumpcycle;
-    disk->frequency    = dtype->frequency;
-    disk->security_driver = dtype->security_driver;
-    disk->maxdumps     = dtype->maxdumps;
-    disk->tape_splitsize       = dtype->tape_splitsize;
-    disk->split_diskbuffer     = dtype->split_diskbuffer;
-    disk->fallback_splitsize   = dtype->fallback_splitsize;
-    disk->maxpromoteday        = dtype->maxpromoteday;
-    disk->bumppercent  = dtype->bumppercent;
-    disk->bumpsize     = dtype->bumpsize;
-    disk->bumpdays     = dtype->bumpdays;
-    disk->bumpmult     = dtype->bumpmult;
-    disk->start_t      = dtype->start_t;
-    disk->strategy     = dtype->strategy;
-    disk->estimate     = dtype->estimate;
-    disk->compress     = dtype->compress;
-    disk->srvcompprog  = dtype->srvcompprog;
-    disk->clntcompprog = dtype->clntcompprog;
-    disk->encrypt       = dtype->encrypt;
-    disk->srv_decrypt_opt   = dtype->srv_decrypt_opt;
-    disk->clnt_decrypt_opt  = dtype->clnt_decrypt_opt;
-    disk->srv_encrypt   = dtype->srv_encrypt;
-    disk->clnt_encrypt  = dtype->clnt_encrypt;
-    disk->comprate[0]  = dtype->comprate[0];
-    disk->comprate[1]  = dtype->comprate[1];
-    disk->record       = dtype->record;
-    disk->skip_incr    = dtype->skip_incr;
-    disk->skip_full    = dtype->skip_full;
-    disk->no_hold      = dtype->no_hold;
-    disk->kencrypt     = dtype->kencrypt;
-    disk->index                = dtype->index;
-    disk->todo         = 1;
+    disk->dtype_name        = dtype->name;
+    disk->program           = dumptype_get_program(dtype);
+    if(dumptype_get_exclude(dtype).type == 0) {
+       disk->exclude_list   = duplicate_sl(dumptype_get_exclude(dtype).sl);
+       disk->exclude_file   = NULL;
+    }
+    else {
+       disk->exclude_file   = duplicate_sl(dumptype_get_exclude(dtype).sl);
+       disk->exclude_list   = NULL;
+    }
+    disk->exclude_optional   = dumptype_get_exclude(dtype).optional;
+    if(dumptype_get_include(dtype).type == 0) {
+       disk->include_list   = duplicate_sl(dumptype_get_include(dtype).sl);
+       disk->include_file   = NULL;
+    }
+    else {
+       disk->include_file   = duplicate_sl(dumptype_get_include(dtype).sl);
+       disk->include_list   = NULL;
+    }
+    disk->include_optional   = dumptype_get_include(dtype).optional;
+    disk->priority          = dumptype_get_priority(dtype);
+    disk->dumpcycle         = dumptype_get_dumpcycle(dtype);
+/*    disk->frequency       = dumptype_get_frequency(dtype);*/
+    disk->security_driver    = dumptype_get_security_driver(dtype);
+    disk->maxdumps          = dumptype_get_maxdumps(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);
+    disk->maxpromoteday             = dumptype_get_maxpromoteday(dtype);
+    disk->bumppercent       = dumptype_get_bumppercent(dtype);
+    disk->bumpsize          = dumptype_get_bumpsize(dtype);
+    disk->bumpdays          = dumptype_get_bumpdays(dtype);
+    disk->bumpmult          = dumptype_get_bumpmult(dtype);
+    disk->start_t           = dumptype_get_start_t(dtype);
+    disk->strategy          = dumptype_get_strategy(dtype);
+    disk->estimate          = dumptype_get_estimate(dtype);
+    disk->compress          = dumptype_get_compress(dtype);
+    disk->srvcompprog       = dumptype_get_srvcompprog(dtype);
+    disk->clntcompprog      = dumptype_get_clntcompprog(dtype);
+    disk->encrypt            = dumptype_get_encrypt(dtype);
+    disk->srv_decrypt_opt    = dumptype_get_srv_decrypt_opt(dtype);
+    disk->clnt_decrypt_opt   = dumptype_get_clnt_decrypt_opt(dtype);
+    disk->srv_encrypt        = dumptype_get_srv_encrypt(dtype);
+    disk->clnt_encrypt       = dumptype_get_clnt_encrypt(dtype);
+    disk->amandad_path       = dumptype_get_amandad_path(dtype);
+    disk->client_username    = dumptype_get_client_username(dtype);
+    disk->ssh_keys           = dumptype_get_ssh_keys(dtype);
+    disk->comprate[0]       = dumptype_get_comprate(dtype)[0];
+    disk->comprate[1]       = dumptype_get_comprate(dtype)[1];
+
+    /*
+     * Boolean parameters with no value (Appears here as value 2) defaults
+     * to TRUE for backward compatibility and for logical consistency.
+     */
+    disk->record            = dumptype_get_record(dtype) != 0;
+    disk->skip_incr         = dumptype_get_skip_incr(dtype) != 0;
+    disk->skip_full         = dumptype_get_skip_full(dtype) != 0;
+    disk->to_holdingdisk     = dumptype_get_to_holdingdisk(dtype);
+    disk->kencrypt          = dumptype_get_kencrypt(dtype) != 0;
+    disk->index                     = dumptype_get_index(dtype) != 0; 
+
+    disk->todo              = 1;
 
     skip_whitespace(s, ch);
     fp = s - 1;
     if(ch && ch != '#') {              /* get optional spindle number */
        char *fp1;
        int is_digit=1;
+
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        fp1=fp;
@@ -505,11 +614,11 @@ parse_diskline(lst, filename, diskf, line_num_p, line_p)
            }
        }
        if(is_digit == 0) {
-           parserror(filename, line_num, "non-integer spindle `%s'", fp);
-           if(host == NULL) amfree(hostname);
+           disk_parserror(filename, line_num, "non-integer spindle `%s'", fp);
+           amfree(hostname);
            amfree(disk->name);
            amfree(disk);
-           return 1;
+           return (-1);
        }
        disk->spindle = atoi(fp);
        skip_integer(s, ch);
@@ -521,33 +630,33 @@ parse_diskline(lst, filename, diskf, line_num_p, line_p)
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        if((netif = lookup_interface(upcase(fp))) == NULL) {
-           parserror(filename, line_num,
+           disk_parserror(filename, line_num,
                "undefined network interface `%s'", fp);
-           if(host == NULL) amfree(hostname);
+           amfree(hostname);
            amfree(disk->name);
            amfree(disk);
            return (-1);
        }
     } else {
-       netif = lookup_interface("");
+       netif = lookup_interface("default");
     }
 
     skip_whitespace(s, ch);
     if(ch && ch != '#') {              /* now we have garbage, ignore it */
-       parserror(filename, line_num, "end of line expected");
+       disk_parserror(filename, line_num, "end of line expected");
     }
 
-    if(dtype->ignore || dtype->strategy == DS_SKIP) {
-       if(host == NULL) amfree(hostname);
+    if(dumptype_get_ignore(dtype) || dumptype_get_strategy(dtype) == DS_SKIP) {
+       amfree(hostname);
        amfree(disk->name);
        amfree(disk);
-       return (1);
+       return (0);
     }
 
     /* success, add disk to lists */
 
     if(host == NULL) {                 /* new host */
-       host = alloc(sizeof(am_host_t));
+       host = alloc(SIZEOF(am_host_t));
        malloc_mark(host);
        host->next = hostlist;
        hostlist = host;
@@ -576,7 +685,7 @@ parse_diskline(lst, filename, diskf, line_num_p, line_p)
 }
 
 
-printf_arglist_function2(static void parserror, const char *, filename,
+printf_arglist_function2(void disk_parserror, const char *, filename,
     int, line_num, const char *, format)
 {
     va_list argp;
@@ -591,14 +700,16 @@ printf_arglist_function2(static void parserror, const char *, filename,
 }
 
 
-void dump_queue(st, q, npr, f)
-char *st;
-disklist_t q;
-int npr;       /* we print first npr disks on queue, plus last two */
-FILE *f;
+void
+dump_queue(
+    char *     st,
+    disklist_t q,
+    int                npr,    /* we print first npr disks on queue, plus last two */
+    FILE *     f)
 {
     disk_t *d,*p;
     int pos;
+    char *qname;
 
     if(empty(q)) {
        fprintf(f, "%s QUEUE: empty\n", st);
@@ -606,8 +717,10 @@ FILE *f;
     }
     fprintf(f, "%s QUEUE:\n", st);
     for(pos = 0, d = q.head, p = NULL; d != NULL; p = d, d = d->next, pos++) {
+       qname = quote_string(d->name);
        if(pos < npr) fprintf(f, "%3d: %-10s %-4s\n",
-                             pos, d->host->hostname, d->name);
+                             pos, d->host->hostname, qname);
+       amfree(qname);
     }
     if(pos > npr) {
        if(pos > npr+2) fprintf(f, "  ...\n");
@@ -620,16 +733,17 @@ FILE *f;
     }
 }
 
-char *optionstr(dp, their_features, fdout)
-disk_t *dp;
-am_feature_t * their_features;
-FILE *fdout;
+char *
+optionstr(
+    disk_t *           dp,
+    am_feature_t *     their_features,
+    FILE *             fdout)
 {
     char *auth_opt = NULL;
     char *kencrypt_opt = "";
     char *compress_opt = "";
-    char *encrypt_opt = "";
-    char *decrypt_opt ="";
+    char *encrypt_opt = stralloc("");
+    char *decrypt_opt = stralloc("");
     char *record_opt = "";
     char *index_opt = "";
     char *exclude_file = NULL;
@@ -643,9 +757,15 @@ FILE *fdout;
     sle_t *excl;
     int nb_exclude_file;
     int nb_include_file;
+    char *qdpname;
+    char *qname;
+    int err=0;
 
-    if(dp->host
-       && am_has_feature(dp->host->features, fe_options_auth)) {
+    assert(dp != NULL);
+    assert(dp->host != NULL);
+
+    qdpname = quote_string(dp->name);
+    if(am_has_feature(dp->host->features, fe_options_auth)) {
        auth_opt = vstralloc("auth=", dp->security_driver, ";", NULL);
     } else if(strcasecmp(dp->security_driver, "bsd") == 0) {
        if(am_has_feature(dp->host->features, fe_options_bsd_auth))
@@ -653,7 +773,7 @@ FILE *fdout;
        else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support auth or bsd-auth\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     } else if(strcasecmp(dp->security_driver, "krb4") == 0) {
        if(am_has_feature(dp->host->features, fe_options_krb4_auth))
@@ -661,7 +781,7 @@ FILE *fdout;
        else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support auth or krb4-auth\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
        if(dp->kencrypt) {
            if(am_has_feature(dp->host->features, fe_options_kencrypt)) {
@@ -670,7 +790,7 @@ FILE *fdout;
            else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support kencrypt\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
            }
        }
     }
@@ -683,7 +803,7 @@ FILE *fdout;
        else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support fast compression\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
        break;
     case COMP_BEST:
@@ -693,7 +813,7 @@ FILE *fdout;
        else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support best compression\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
        break;
     case COMP_CUST:
@@ -702,15 +822,16 @@ FILE *fdout;
          if (BSTRNCMP(compress_opt, "comp-cust=;") == 0){
            if(fdout) {
              fprintf(fdout,
-                     "WARNING: %s:%s client custom compression with no compression program specified\n",
-                     dp->host->hostname, dp->name);
+                     "ERROR: %s:%s client custom compression with no compression program specified\n",
+                     dp->host->hostname, qdpname);
            }
+           err++;
          }
        }
        else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support client custom compression\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
        break;
     case COMP_SERV_FAST:
@@ -729,15 +850,16 @@ FILE *fdout;
          if (BSTRNCMP(compress_opt, "srvcomp-cust=;") == 0){
            if(fdout) {
              fprintf(fdout,
-                     "WARNING: %s:%s server custom compression with no compression program specified\n",
-                     dp->host->hostname, dp->name);
+                     "ERROR: %s:%s server custom compression with no compression program specified\n",
+                     dp->host->hostname, qdpname);
            }
+           err++;
          }
        }
        else if(fdout) {
          fprintf(fdout,
                  "WARNING: %s:%s does not support server custom compression\n",
-                 dp->host->hostname, dp->name);
+                 dp->host->hostname, qdpname);
        }
        break;
     }
@@ -745,56 +867,71 @@ FILE *fdout;
     switch(dp->encrypt) {
     case ENCRYPT_CUST:
       if(am_has_feature(their_features, fe_options_encrypt_cust)) {
-        encrypt_opt = vstralloc("encrypt-cust=", dp->clnt_encrypt, ";", NULL);
+        encrypt_opt = newvstralloc(encrypt_opt, "encrypt-cust=",
+                                   dp->clnt_encrypt, ";", NULL);
         if (BSTRNCMP(encrypt_opt, "encrypt-cust=;") == 0) {
            if(fdout) {
              fprintf(fdout,
-                     "WARNING: %s:%s encrypt client with no encryption program specified\n",
-                     dp->host->hostname, dp->name);
+                     "ERROR: %s:%s encrypt client with no encryption program specified\n",
+                     dp->host->hostname, qdpname);
+           }
+           err++;
+         }
+        if ( dp->compress == COMP_SERV_FAST || 
+             dp->compress == COMP_SERV_BEST ||
+             dp->compress == COMP_SERV_CUST ) {
+          if(fdout) {
+             fprintf(fdout,
+                     "ERROR: %s:Client encryption with server compression is not supported. See amanda.conf(5) for detail.\n", dp->host->hostname);
            }
+           err++;
          }
         if(dp->clnt_decrypt_opt) {
           if(am_has_feature(their_features, fe_options_client_decrypt_option)) {
-            decrypt_opt = vstralloc("client-decrypt-option=", dp->clnt_decrypt_opt, ";", NULL);
+            decrypt_opt = newvstralloc(decrypt_opt, "client-decrypt-option=",
+                                       dp->clnt_decrypt_opt, ";", NULL);
           }
           else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support client decrypt option\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
           }
         }
       }
       else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support client data encryption\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
      }
         break;
     case ENCRYPT_SERV_CUST:
       if(am_has_feature(their_features, fe_options_encrypt_serv_cust)) {
-        encrypt_opt = vstralloc("encrypt-serv-cust=", dp->srv_encrypt, ";", NULL);
+        encrypt_opt = newvstralloc(encrypt_opt, "encrypt-serv-cust=",
+                                   dp->srv_encrypt, ";", NULL);
         if (BSTRNCMP(encrypt_opt, "encrypt-serv-cust=;") == 0){
            if(fdout) {
              fprintf(fdout,
-                     "WARNING: %s:%s encrypt server with no encryption program specified\n",
-                     dp->host->hostname, dp->name);
+                     "ERROR: %s:%s encrypt server with no encryption program specified\n",
+                     dp->host->hostname, qdpname);
            }
+           err++;
          }
         if(dp->srv_decrypt_opt) {
           if(am_has_feature(their_features, fe_options_server_decrypt_option)) {
-            decrypt_opt = vstralloc("server-decrypt-option=", dp->srv_decrypt_opt, ";", NULL);
+            decrypt_opt = newvstralloc(decrypt_opt, "server-decrypt-option=",
+                                       dp->srv_decrypt_opt, ";", NULL);
           }
           else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support server decrypt option\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
           }
         }
       }
       else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support server data encryption\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
       }
         break;
     }
@@ -805,7 +942,7 @@ FILE *fdout;
        }
        else if(fdout) {
            fprintf(fdout, "WARNING: %s:%s does not support no record\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     }
 
@@ -815,7 +952,7 @@ FILE *fdout;
        }
        else if(fdout) {
            fprintf(fdout, "WARNING: %s:%s does not support index\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     }
 
@@ -831,23 +968,25 @@ FILE *fdout;
               dp->exclude_file->nb_element == 1) {
                for(excl = dp->exclude_file->first; excl != NULL;
                                                    excl = excl->next) {
-                   exc = newvstralloc( exc, "exclude-file=", excl->name,
-                                       ";", NULL);
+                   qname = quote_string(excl->name);
+                   exc = newvstralloc( exc, "exclude-file=", qname, ";", NULL);
                    strappend(exclude_file, exc);
+                   amfree(qname);
                }
            } else {
-               exc = newvstralloc(exc, "exclude-file=",
-                                  dp->exclude_file->last->name, ";", NULL);
+               qname = quote_string(dp->exclude_file->last->name);
+               exc = newvstralloc(exc, "exclude-file=", qname, ";", NULL);
                strappend(exclude_file, exc);
                if(fdout) {
                    fprintf(fdout,
                       "WARNING: %s:%s does not support multiple exclude\n",
-                      dp->host->hostname, dp->name);
+                      dp->host->hostname, qdpname);
                }
+               amfree(qname);
            }
        } else if(fdout) {
            fprintf(fdout, "WARNING: %s:%s does not support exclude file\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     }
     exclude_list = stralloc("");
@@ -857,23 +996,25 @@ FILE *fdout;
               (dp->exclude_list->nb_element == 1 && nb_exclude_file == 0)) {
                for(excl = dp->exclude_list->first; excl != NULL;
                                                    excl = excl->next) {
-                   exc = newvstralloc( exc, "exclude-list=", excl->name,
-                                       ";", NULL);
+                   qname = quote_string(excl->name);
+                   exc = newvstralloc( exc, "exclude-list=", qname, ";", NULL);
                    strappend(exclude_list, exc);
+                   amfree(qname);
                }
            } else {
-               exc = newvstralloc(exc, "exclude-list=",
-                                  dp->exclude_list->last->name, ";", NULL);
+               qname = quote_string(dp->exclude_list->last->name);
+               exc = newvstralloc(exc, "exclude-list=", qname, ";", NULL);
                strappend(exclude_list, exc);
                if(fdout) {
                        fprintf(fdout,
                         "WARNING: %s:%s does not support multiple exclude\n",
-                        dp->host->hostname, dp->name);
+                        dp->host->hostname, qdpname);
                }
+               amfree(qname);
            }
        } else if(fdout) {
            fprintf(fdout, "WARNING: %s:%s does not support exclude list\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     }
 
@@ -886,23 +1027,25 @@ FILE *fdout;
               dp->include_file->nb_element == 1) {
                for(excl = dp->include_file->first; excl != NULL;
                                                    excl = excl->next) {
-                   exc = newvstralloc( exc, "include-file=", excl->name,
-                                       ";", NULL);
+                   qname = quote_string(excl->name);
+                   exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
                    strappend(include_file, exc);
+                   amfree(qname);
                }
            } else {
-               exc = newvstralloc(exc, "include-file=",
-                                  dp->include_file->last->name, ";", NULL);
+               qname = quote_string(dp->include_file->last->name);
+               exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
                strappend(include_file, exc);
                if(fdout) {
                    fprintf(fdout,
                         "WARNING: %s:%s does not support multiple include\n",
-                        dp->host->hostname, dp->name);
+                        dp->host->hostname, qdpname);
                }
+               amfree(qname);
            }
        } else if(fdout) {
            fprintf(fdout, "WARNING: %s:%s does not support include file\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     }
     include_list = stralloc("");
@@ -912,23 +1055,25 @@ FILE *fdout;
               (dp->include_list->nb_element == 1 && nb_include_file == 0)) {
                for(excl = dp->include_list->first; excl != NULL;
                                                    excl = excl->next) {
-                   exc = newvstralloc( exc, "include-list=", excl->name,
-                                       ";", NULL);
+                   qname = quote_string(excl->name);
+                   exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
                    strappend(include_list, exc);
+                   amfree(qname);
                }
            } else {
-               exc = newvstralloc(exc, "include-list=",
-                                  dp->include_list->last->name, ";", NULL);
+               qname = quote_string(dp->include_list->last->name);
+               exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
                strappend(include_list, exc);
                if(fdout) {
                        fprintf(fdout,
                         "WARNING: %s:%s does not support multiple include\n",
-                        dp->host->hostname, dp->name);
+                        dp->host->hostname, qdpname);
                }
+               amfree(qname);
            }
        } else if(fdout) {
            fprintf(fdout, "WARNING: %s:%s does not support include list\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     }
 
@@ -939,7 +1084,7 @@ FILE *fdout;
        else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support optional exclude\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     }
     if(dp->include_optional) {
@@ -949,7 +1094,7 @@ FILE *fdout;
        else if(fdout) {
            fprintf(fdout,
                    "WARNING: %s:%s does not support optional include\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qdpname);
        }
     }
 
@@ -968,20 +1113,34 @@ FILE *fdout;
                       excl_opt,
                       incl_opt,
                       NULL);
+    amfree(qdpname);
     amfree(auth_opt);
     amfree(exclude_list);
     amfree(exclude_file);
     amfree(include_file);
     amfree(include_list);
     amfree(exc);
+    amfree(decrypt_opt);
+    amfree(encrypt_opt);
 
-    return result;
+    /* result contains at least 'auth=...' */
+    if ( err ) {
+       amfree(result);
+       return NULL;
+    } else {
+       return result;
+    }
 }
 
  
-void match_disklist(disklist_t *origqp, int sargc, char **sargv)
+char *
+match_disklist(
+    disklist_t *origqp,
+    int                sargc,
+    char **    sargv)
 {
     char *prevhost = NULL;
+    char *errstr = NULL;
     int i;
     int match_a_host;
     int match_a_disk;
@@ -989,7 +1148,7 @@ void match_disklist(disklist_t *origqp, int sargc, char **sargv)
     disk_t *dp;
 
     if(sargc <= 0)
-       return;
+       return NULL;
 
     for(dp = origqp->head; dp != NULL; dp = dp->next) {
        if(dp->todo == 1)
@@ -1011,6 +1170,7 @@ void match_disklist(disklist_t *origqp, int sargc, char **sargv)
                (dp->device && match_disk(sargv[i], dp->device)))) {
                if(match_a_host) {
                    error("Argument %s match a host and a disk",sargv[i]);
+                   /*NOTREACHED*/
                }
                else {
                    if(dp->todo == -1) {
@@ -1034,8 +1194,7 @@ void match_disklist(disklist_t *origqp, int sargc, char **sargv)
                prev_match = 1;
            }
            else {
-               prev_match = 0;
-               /*error("%s match nothing",sargv[i]);*/
+               vstrextend(&errstr, "Argument '", sargv[i], "' match neither a host nor a disk.\n", NULL);
            }
        }
     }
@@ -1052,18 +1211,20 @@ void match_disklist(disklist_t *origqp, int sargc, char **sargv)
        if(dp->todo == -1)
            dp->todo = 0;
     }
+
+    return errstr;
 }
 
+
 #ifdef TEST
 
-static void dump_disk P((const disk_t *));
-static void dump_disklist P((const disklist_t *));
-int main P((int, char *[]));
+static void dump_disk(const disk_t *);
+static void dump_disklist(const disklist_t *);
+int main(int, char *[]);
 
 static void
-dump_disk(dp)
-    const disk_t *dp;
+dump_disk(
+    const disk_t *     dp)
 {
     printf("  DISK %s (HOST %s, LINE %d) TYPE %s NAME %s SPINDLE %d\n",
           dp->name, dp->host->hostname, dp->line, dp->dtype_name,
@@ -1072,8 +1233,8 @@ dump_disk(dp)
 }
 
 static void
-dump_disklist(lst)
-    const disklist_t *lst;
+dump_disklist(
+    const disklist_t * lst)
 {
     const disk_t *dp, *prev;
     const am_host_t *hp;
@@ -1108,9 +1269,9 @@ dump_disklist(lst)
 }
 
 int
-main(argc, argv)
-     int argc;
-     char *argv[];
+main(
+    int                argc,
+    char **    argv)
 {
   char *conffile;
   char *conf_diskfile;
@@ -1123,6 +1284,8 @@ main(argc, argv)
 
   set_pname("diskfile");
 
+  dbopen(DBG_SUBDIR_SERVER);
+
   /* Don't die when child closes pipe */
   signal(SIGPIPE, SIG_IGN);
 
index f53441c9eb77f3feb335a18782bf3d602a7d8cf6..c8ad6742eea7a963e25fb7bce40b728cccfabfd5 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: diskfile.h,v 1.32 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: diskfile.h,v 1.38 2006/06/22 20:41:33 martinea Exp $
  *
  * interface for disklist file reading code
  */
@@ -49,58 +49,61 @@ typedef struct amhost_s {
 } am_host_t;
 
 typedef struct disk_s {
-    int line;                          /* line number of last definition */
+    int                line;                   /* line number of last definition */
     struct disk_s *prev, *next;                /* doubly linked disk list */
 
-    am_host_t *host;                   /* host list */
+    am_host_t  *host;                  /* host list */
     struct disk_s *hostnext;
 
-    char *name;                                /* label name for disk */
-    char *device;                      /* device name for disk, eg "sd0g" */
-    char *dtype_name;                  /* name of dump type   XXX shouldn't need this */
-    char *program;                     /* dump program, eg DUMP, GNUTAR */
-    char *srvcompprog;                  /* custom compression server filter */
-    char *clntcompprog;                 /* custom compression client filter */
-    char *srv_encrypt;                  /* custom encryption server filter */
-    char *clnt_encrypt;                 /* custom encryption client filter */
-    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 */
-    int exclude_optional;              /* exclude list are optional */
-    int include_optional;              /* include list are optional */
-    long priority;                     /* priority of disk */
-    long tape_splitsize;               /* size of dumpfile chunks on tape */
-    char *split_diskbuffer;            /* place where we can buffer PORT-WRITE dumps other than RAM */
-    long fallback_splitsize;           /* size for in-RAM PORT-WRITE buffers */
-    long dumpcycle;                    /* days between fulls */
-    long frequency;                    /* XXX - not used */
-    char *security_driver;             /* type of authentication (per disk) */
-    int maxdumps;                      /* max number of parallel dumps (per system) */
-    int maxpromoteday;                 /* maximum of promote day */
-    int bumppercent;
-    int bumpsize;
-    int bumpdays;
-    double bumpmult;
-    time_t start_t;                    /* start this dump after this time */
-    int strategy;                      /* what dump strategy to use */
-    int estimate;                      /* what estimate strategy to use */
-    int compress;                      /* type of compression to use */
-    int encrypt;                       /* type of encryption to use */
-    char *srv_decrypt_opt;             /* server-side decryption option parameter to use */
-    char *clnt_decrypt_opt;             /* client-side decryption option parameter to use */
-    float comprate[2];                 /* default compression rates */
+    char       *name;                  /* label name for disk */
+    char       *device;                /* device name for disk, eg "sd0g" */
+    char       *dtype_name;            /* name of dump type   XXX shouldn't need this */
+    char       *program;               /* dump program, eg DUMP, STAR, GNUTAR */
+    char       *srvcompprog;           /* custom compression server filter */
+    char       *clntcompprog;          /* custom compression client filter */
+    char       *srv_encrypt;           /* custom encryption server filter */
+    char       *clnt_encrypt;          /* custom encryption client filter */
+    char       *amandad_path;          /* amandad path on the client */
+    char       *client_username;       /* username 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 */
+    int                exclude_optional;       /* exclude list are optional */
+    int                include_optional;       /* include list are optional */
+    int                priority;               /* priority of disk */
+    off_t      tape_splitsize;         /* size of dumpfile chunks on tape */
+    char       *split_diskbuffer;      /* place where we can buffer PORT-WRITE dumps other than RAM */
+    off_t      fallback_splitsize;     /* size for in-RAM PORT-WRITE buffers */
+    int                dumpcycle;              /* days between fulls */
+    long       frequency;              /* XXX - not used */
+    char       *security_driver;       /* type of authentication (per disk) */
+    int                maxdumps;               /* max number of parallel dumps (per system) */
+    int                maxpromoteday;          /* maximum of promote day */
+    int                bumppercent;
+    off_t      bumpsize;
+    int                bumpdays;
+    double     bumpmult;
+    time_t     start_t;                /* start this dump after this time */
+    int                strategy;               /* what dump strategy to use */
+    int                estimate;               /* what estimate strategy to use */
+    int                compress;               /* type of compression to use */
+    int                encrypt;                /* type of encryption to use */
+    char       *srv_decrypt_opt;       /* server-side decryption option parameter to use */
+    char       *clnt_decrypt_opt;      /* client-side decryption option parameter to use */
+    double     comprate[2];            /* default compression rates */
     /* flag options */
-    unsigned int record:1;             /* record dump in /etc/dumpdates ? */
-    unsigned int skip_incr:1;          /* incs done externally ? */
-    unsigned int skip_full:1;          /* fulls done externally ? */
-    unsigned int no_hold:1;            /* don't use holding disk ? */
-    unsigned int kencrypt:1;
-    unsigned int index:1;              /* produce an index ? */
-    int spindle;                       /* spindle # - for parallel dumps */
-    int inprogress;                    /* being dumped now? */
-    int todo;
-    void *up;                          /* generic user pointer */
+    int                record;                 /* record dump in /etc/dumpdates ? */
+    int                skip_incr;              /* incs done externally ? */
+    int                skip_full;              /* fulls done externally ? */
+    int                to_holdingdisk;         /* use holding disk ? */
+    int                kencrypt;
+    int                index;                  /* produce an index ? */
+    int                spindle;                /* spindle # - for parallel dumps */
+    int                inprogress;             /* being dumped now? */
+    int                todo;
+    void       *up;                    /* generic user pointer */
 } disk_t;
 
 typedef struct disklist_s {
@@ -110,26 +113,26 @@ typedef struct disklist_s {
 #define empty(dlist)   ((dlist).head == NULL)
 
 
-int read_diskfile P((const char *, disklist_t *));
+int read_diskfile(const char *, disklist_t *);
 
-am_host_t *lookup_host P((const char *hostname));
-disk_t *lookup_disk P((const char *hostname, const char *diskname));
+am_host_t *lookup_host(const char *hostname);
+disk_t *lookup_disk(const char *hostname, const char *diskname);
 
-disk_t *add_disk P((disklist_t *list, char *hostname, char *diskname));
+disk_t *add_disk(disklist_t *list, char *hostname, char *diskname);
 
-void enqueue_disk P((disklist_t *list, disk_t *disk));
-void headqueue_disk P((disklist_t *list, disk_t *disk));
-void insert_disk P((disklist_t *list, disk_t *disk, int (*f)(disk_t *a, disk_t *b)));
-int  find_disk P((disklist_t *list, disk_t *disk));
-void sort_disk P((disklist_t *in, disklist_t *out, int (*f)(disk_t *a, disk_t *b)));
-disk_t *dequeue_disk P((disklist_t *list));
-void remove_disk P((disklist_t *list, disk_t *disk));
+void enqueue_disk(disklist_t *list, disk_t *disk);
+void headqueue_disk(disklist_t *list, disk_t *disk);
+void insert_disk(disklist_t *list, disk_t *disk, int (*f)(disk_t *a, disk_t *b));
+int  find_disk(disklist_t *list, disk_t *disk);
+void sort_disk(disklist_t *in, disklist_t *out, int (*f)(disk_t *a, disk_t *b));
+disk_t *dequeue_disk(disklist_t *list);
+void remove_disk(disklist_t *list, disk_t *disk);
 
-void dump_queue P((char *str, disklist_t q, int npr, FILE *f));
+void dump_queue(char *str, disklist_t q, int npr, FILE *f);
 
-char *optionstr P((disk_t *dp, am_feature_t *their_features, FILE *fdout));
+char *optionstr(disk_t *dp, am_feature_t *their_features, FILE *fdout);
 
-void match_disklist P((disklist_t *origqp, int sargc, char **sargv));
-void free_disklist P((disklist_t *dl));
+char *match_disklist(disklist_t *origqp, int sargc, char **sargv);
+void free_disklist(disklist_t *dl);
 
 #endif /* ! DISKFILE_H */
index 55f1789be0b1aebccc2702bb337756f4bd09229a..6ee07a9e4645a7727269eb3a4bd690d51eaff25a 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: driver.c,v 1.165.2.2 2006/04/23 23:04:33 martinea Exp $
+ * $Id: driver.c,v 1.198 2006/08/24 01:57:16 paddy_s Exp $
  *
  * controlling process for the Amanda backup system
  */
@@ -34,7 +34,7 @@
  *     tape.  Probably not effective though, should do this in planner.
  */
 
-/*#define HOLD_DEBUG*/
+#define HOLD_DEBUG
 
 #include "amanda.h"
 #include "clock.h"
@@ -53,61 +53,63 @@ static disklist_t waitq, runq, tapeq, roomq;
 static int pending_aborts;
 static disk_t *taper_disk;
 static int degraded_mode;
-static unsigned long reserved_space;
-static unsigned long total_disksize;
+static off_t reserved_space;
+static off_t total_disksize;
 static char *dumper_program;
 static char *chunker_program;
 static int  inparallel;
 static int nodump = 0;
-static unsigned long tape_length, tape_left = 0;
+static off_t tape_length = (off_t)0;
+static off_t tape_left = (off_t)0;
 static int current_tape = 1;
 static int conf_taperalgo;
 static int conf_runtapes;
 static time_t sleep_time;
 static int idle_reason;
-static char *datestamp;
-static char *timestamp;
+static char *driver_timestamp;
+static char *hd_driver_timestamp;
 static am_host_t *flushhost = NULL;
 static int need_degraded=0;
 
 static event_handle_t *dumpers_ev_time = NULL;
 static event_handle_t *schedule_ev_read = NULL;
 
-static void allocate_bandwidth P((interface_t *ip, int kps));
-static int assign_holdingdisk P((assignedhd_t **holdp, disk_t *diskp));
-static void adjust_diskspace P((disk_t *diskp, cmd_t cmd));
-static void delete_diskspace P((disk_t *diskp));
-static assignedhd_t **build_diskspace P((char *destname));
-static int client_constrained P((disk_t *dp));
-static void deallocate_bandwidth P((interface_t *ip, int kps));
-static void dump_schedule P((disklist_t *qp, char *str));
-static int dump_to_tape P((disk_t *dp));
-static assignedhd_t **find_diskspace P((unsigned long size, int *cur_idle,
-                                       assignedhd_t *preferred));
-static int free_kps P((interface_t *ip));
-static unsigned long free_space P((void));
-static void dumper_result P((disk_t *dp));
-static void handle_dumper_result P((void *));
-static void handle_chunker_result P((void *));
-static void handle_dumpers_time P((void *));
-static void handle_taper_result P((void *));
-static void holdingdisk_state P((char *time_str));
-static dumper_t *idle_dumper P((void));
-static void interface_state P((char *time_str));
-static int num_busy_dumpers P((void));
-static int queue_length P((disklist_t q));
-static disklist_t read_flush P((void));
-static void read_schedule P((void *cookie));
-static void short_dump_state P((void));
-static void startaflush P((void));
-static void start_degraded_mode P((disklist_t *queuep));
-static void start_some_dumps P((disklist_t *rq));
-static void continue_port_dumps();
-static void update_failed_dump_to_tape P((disk_t *));
+static int wait_children(int count);
+static void wait_for_children(void);
+static void allocate_bandwidth(interface_t *ip, unsigned long kps);
+static int assign_holdingdisk(assignedhd_t **holdp, disk_t *diskp);
+static void adjust_diskspace(disk_t *diskp, cmd_t cmd);
+static void delete_diskspace(disk_t *diskp);
+static assignedhd_t **build_diskspace(char *destname);
+static int client_constrained(disk_t *dp);
+static void deallocate_bandwidth(interface_t *ip, unsigned long kps);
+static void dump_schedule(disklist_t *qp, char *str);
+static int dump_to_tape(disk_t *dp);
+static assignedhd_t **find_diskspace(off_t size, int *cur_idle,
+                                       assignedhd_t *preferred);
+static unsigned long free_kps(interface_t *ip);
+static off_t free_space(void);
+static void dumper_result(disk_t *dp);
+static void handle_dumper_result(void *);
+static void handle_chunker_result(void *);
+static void handle_dumpers_time(void *);
+static void handle_taper_result(void *);
+static void holdingdisk_state(char *time_str);
+static dumper_t *idle_dumper(void);
+static void interface_state(char *time_str);
+static int queue_length(disklist_t q);
+static disklist_t read_flush(void);
+static void read_schedule(void *cookie);
+static void short_dump_state(void);
+static void startaflush(void);
+static void start_degraded_mode(disklist_t *queuep);
+static void start_some_dumps(disklist_t *rq);
+static void continue_port_dumps(void);
+static void update_failed_dump_to_tape(disk_t *);
 #if 0
-static void dump_state P((const char *str));
+static void dump_state(const char *str);
 #endif
-int main P((int main_argc, char **main_argv));
+int main(int main_argc, char **main_argv);
 
 static const char *idle_strings[] = {
 #define NOT_IDLE               0
@@ -131,9 +133,9 @@ static const char *idle_strings[] = {
 };
 
 int
-main(main_argc, main_argv)
-     int main_argc;
-     char **main_argv;
+main(
+    int                main_argc,
+    char **    main_argv)
 {
     disklist_t origq;
     disk_t *diskp;
@@ -151,17 +153,23 @@ main(main_argc, main_argv)
     int result_argc;
     char *result_argv[MAX_ARGS+1];
     char *taper_program;
-    amwait_t retstat;
     char *conf_tapetype;
     tapetype_t *tape;
+    char *line;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
 
-    setvbuf(stdout, (char *)NULL, _IOLBF, 0);
-    setvbuf(stderr, (char *)NULL, _IOLBF, 0);
+    setvbuf(stdout, (char *)NULL, (int)_IOLBF, 0);
+    setvbuf(stderr, (char *)NULL, (int)_IOLBF, 0);
 
     set_pname("driver");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
+    atexit(wait_for_children);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -172,23 +180,29 @@ main(main_argc, main_argv)
 
     startclock();
 
+    parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
     printf("%s: pid %ld executable %s version %s\n",
-          get_pname(), (long) getpid(), main_argv[0], version());
+          get_pname(), (long) getpid(), my_argv[0], version());
 
-    if (main_argc > 1) {
-       config_name = stralloc(main_argv[1]);
+    if (my_argc > 1) {
+       config_name = stralloc(my_argv[1]);
        config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
-       if(main_argc > 2) {
-           if(strncmp(main_argv[2], "nodump", 6) == 0) {
+       if(my_argc > 2) {
+           if(strncmp(my_argv[2], "nodump", 6) == 0) {
                nodump = 1;
            }
        }
 
     } else {
+
        char my_cwd[STR_SIZE];
 
-       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
            error("cannot determine current working directory");
+           /*NOTREACHED*/
        }
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
@@ -201,13 +215,48 @@ main(main_argc, main_argv)
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if(read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
     amfree(conffile);
 
-    amfree(datestamp);
-    datestamp = construct_datestamp(NULL);
-    timestamp = construct_timestamp(NULL);
-    log_add(L_START,"date %s", datestamp);
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
+    amfree(driver_timestamp);
+    /* read timestamp from stdin */
+    while ((line = agets(stdin)) != NULL) {
+       if (line[0] != '\0')
+           break;
+       amfree(line);
+    }
+    if ( line == NULL ) {
+      error("Did not get DATE line from planner");
+      /*NOTREACHED*/
+    }
+    driver_timestamp = alloc(15);
+    strncpy(driver_timestamp, &line[5], 14);
+    driver_timestamp[14] = '\0';
+    amfree(line);
+    log_add(L_START,"date %s", driver_timestamp);
+
+    /* check that we don't do many dump in a day and usetimestamps is off */
+    if(strlen(driver_timestamp) == 8) {
+       char *conf_logdir = getconf_str(CNF_LOGDIR);
+       char *logfile    = vstralloc(conf_logdir, "/log.",
+                                    driver_timestamp, ".0", NULL);
+       char *oldlogfile = vstralloc(conf_logdir, "/oldlog/log.",
+                                    driver_timestamp, ".0", NULL);
+       if(access(logfile, F_OK) == 0 || access(oldlogfile, F_OK) == 0) {
+           log_add(L_WARNING, "WARNING: This is not the first amdump run today. Enable the usetimestamps option in the configuration file if you want to run amdump more than once per calendar day.");
+       }
+       amfree(oldlogfile);
+       amfree(logfile);
+       hd_driver_timestamp = construct_timestamp(NULL);
+    }
+    else {
+       hd_driver_timestamp = stralloc(driver_timestamp);
+    }
 
     taper_program = vstralloc(libexecdir, "/", "taper", versionsuffix(), NULL);
     dumper_program = vstralloc(libexecdir, "/", "dumper", versionsuffix(),
@@ -215,20 +264,12 @@ main(main_argc, main_argv)
     chunker_program = vstralloc(libexecdir, "/", "chunker", versionsuffix(),
                               NULL);
 
-    conf_taperalgo = getconf_int(CNF_TAPERALGO);
+    conf_taperalgo = getconf_taperalgo(CNF_TAPERALGO);
     conf_tapetype = getconf_str(CNF_TAPETYPE);
     conf_runtapes = getconf_int(CNF_RUNTAPES);
     tape = lookup_tapetype(conf_tapetype);
-    tape_length = tape->length;
-    printf("driver: tape size %ld\n", tape_length);
-
-    /* taper takes a while to get going, so start it up right away */
-
-    init_driverio();
-    if(conf_runtapes > 0) {
-       startup_tape_process(taper_program);
-       taper_cmd(START_TAPER, datestamp, NULL, 0, NULL);
-    }
+    tape_length = tapetype_get_length(tape);
+    printf("driver: tape size " OFF_T_FMT "\n", (OFF_T_FMT_TYPE)tape_length);
 
     /* start initializing: read in databases */
 
@@ -238,73 +279,90 @@ main(main_argc, main_argv)
     } else {
        conf_diskfile = stralloc2(config_dir, conf_diskfile);
     }
-    if (read_diskfile(conf_diskfile, &origq) < 0)
+    if (read_diskfile(conf_diskfile, &origq) < 0) {
        error("could not load disklist \"%s\"", conf_diskfile);
+       /*NOTREACHED*/
+    }
     amfree(conf_diskfile);
 
     /* set up any configuration-dependent variables */
 
     inparallel = getconf_int(CNF_INPARALLEL);
 
-    reserve = getconf_int(CNF_RESERVE);
+    reserve = (unsigned long)getconf_int(CNF_RESERVE);
 
-    total_disksize = 0;
+    total_disksize = (off_t)0;
     for(hdp = getconf_holdingdisks(), dsk = 0; hdp != NULL; hdp = hdp->next, dsk++) {
-       hdp->up = (void *)alloc(sizeof(holdalloc_t));
+       hdp->up = (void *)alloc(SIZEOF(holdalloc_t));
        holdalloc(hdp)->allocated_dumpers = 0;
-       holdalloc(hdp)->allocated_space = 0L;
+       holdalloc(hdp)->allocated_space = (off_t)0;
 
-       if(get_fs_stats(hdp->diskdir, &fs) == -1
-          || access(hdp->diskdir, W_OK) == -1) {
+       if(get_fs_stats(holdingdisk_get_diskdir(hdp), &fs) == -1
+          || access(holdingdisk_get_diskdir(hdp), W_OK) == -1) {
            log_add(L_WARNING, "WARNING: ignoring holding disk %s: %s\n",
-                   hdp->diskdir, strerror(errno));
+                   holdingdisk_get_diskdir(hdp), strerror(errno));
            hdp->disksize = 0L;
            continue;
        }
 
-       if(fs.avail != -1) {
-           if(hdp->disksize > 0) {
+       if(fs.avail != (off_t)-1) {
+           if(hdp->disksize > (off_t)0) {
                if(hdp->disksize > fs.avail) {
                    log_add(L_WARNING,
-                           "WARNING: %s: %ld KB requested, but only %ld KB available.",
-                           hdp->diskdir, hdp->disksize, fs.avail);
+                           "WARNING: %s: " OFF_T_FMT " KB requested, "
+                           "but only " OFF_T_FMT " KB available.",
+                           holdingdisk_get_diskdir(hdp),
+                           (OFF_T_FMT_TYPE)hdp->disksize,
+                           (OFF_T_FMT_TYPE)fs.avail);
                            hdp->disksize = fs.avail;
                }
            }
-           else if(fs.avail + hdp->disksize < 0) {
+           else if((fs.avail + hdp->disksize) < (off_t)0) {
                log_add(L_WARNING,
-                       "WARNING: %s: not %ld KB free.",
-                       hdp->diskdir, -hdp->disksize);
-               hdp->disksize = 0L;
+                       "WARNING: %s: not " OFF_T_FMT " KB free.",
+                       holdingdisk_get_diskdir(hdp), -hdp->disksize);
+               hdp->disksize = (off_t)0;
                continue;
            }
            else
                hdp->disksize += fs.avail;
        }
 
-       printf("driver: adding holding disk %d dir %s size %ld chunksize %ld\n",
-              dsk, hdp->diskdir, hdp->disksize, hdp->chunksize);
+       printf("driver: adding holding disk %d dir %s size "
+               OFF_T_FMT " chunksize " OFF_T_FMT "\n",
+              dsk, holdingdisk_get_diskdir(hdp),
+              (OFF_T_FMT_TYPE)hdp->disksize,
+              (OFF_T_FMT_TYPE)(holdingdisk_get_chunksize(hdp)));
 
        newdir = newvstralloc(newdir,
-                             hdp->diskdir, "/", timestamp,
+                             holdingdisk_get_diskdir(hdp), "/", hd_driver_timestamp,
                              NULL);
        if(!mkholdingdir(newdir)) {
-           hdp->disksize = 0L;
+           hdp->disksize = (off_t)0;
        }
        total_disksize += hdp->disksize;
     }
 
-    reserved_space = total_disksize * (reserve / 100.0);
+    reserved_space = total_disksize * (off_t)(reserve / 100);
 
-    printf("reserving %ld out of %ld for degraded-mode dumps\n",
-               reserved_space, free_space());
+    printf("reserving " OFF_T_FMT " out of " OFF_T_FMT
+          " for degraded-mode dumps\n",
+          (OFF_T_FMT_TYPE)reserved_space, (OFF_T_FMT_TYPE)free_space());
 
     amfree(newdir);
 
     if(inparallel > MAX_DUMPERS) inparallel = MAX_DUMPERS;
 
+    /* taper takes a while to get going, so start it up right away */
+
+    init_driverio();
+    if(conf_runtapes > 0) {
+        startup_tape_process(taper_program);
+        taper_cmd(START_TAPER, driver_timestamp, NULL, 0, NULL);
+    }
+
     /* fire up the dumpers now while we are waiting */
-    if(!nodump) startup_dump_processes(dumper_program, inparallel);
+    if(!nodump) startup_dump_processes(dumper_program, inparallel, driver_timestamp);
 
     /*
      * Read schedule from stdin.  Usually, this is a pipe from planner,
@@ -323,11 +381,11 @@ main(main_argc, main_argv)
 
     log_add(L_STATS, "startup time %s", walltime_str(curclock()));
 
-    printf("driver: start time %s inparallel %d bandwidth %d diskspace %lu",
-          walltime_str(curclock()), inparallel, free_kps((interface_t *)0),
-          free_space());
+    printf("driver: start time %s inparallel %d bandwidth %lu diskspace "
+          OFF_T_FMT " ", walltime_str(curclock()), inparallel,
+          free_kps((interface_t *)0), (OFF_T_FMT_TYPE)free_space());
     printf(" dir %s datestamp %s driver: drain-ends tapeq %s big-dumpers %s\n",
-          "OBSOLETE", datestamp, taperalgo2str(conf_taperalgo),
+          "OBSOLETE", driver_timestamp, taperalgo2str(conf_taperalgo),
           getconf_str(CNF_DUMPORDER));
     fflush(stdout);
 
@@ -352,7 +410,7 @@ main(main_argc, main_argv)
     if(!need_degraded) startaflush();
 
     if(!nodump)
-       schedule_ev_read = event_register(0, EV_READFD, read_schedule, NULL);
+       schedule_ev_read = event_register((event_id_t)0, EV_READFD, read_schedule, NULL);
 
     short_dump_state();
     event_loop(0);
@@ -361,7 +419,13 @@ main(main_argc, main_argv)
 
     while(!empty(runq) && taper > 0) {
        diskp = dequeue_disk(&runq);
-       if(!degraded_mode) {
+       if (diskp->to_holdingdisk == HOLD_REQUIRED) {
+           log_add(L_FAIL, "%s %s %s %d [%s]",
+               diskp->host->hostname, diskp->name, sched(diskp)->datestamp,
+               sched(diskp)->level,
+               "can't dump required holdingdisk");
+       }
+       else if (!degraded_mode) {
            int rc = dump_to_tape(diskp);
            if(rc == 1)
                log_add(L_INFO,
@@ -380,9 +444,9 @@ main(main_argc, main_argv)
            log_add(L_FAIL, "%s %s %s %d [%s]",
                diskp->host->hostname, diskp->name, sched(diskp)->datestamp,
                sched(diskp)->level,
-               diskp->no_hold ?
-                   "can't dump no-hold disk in degraded mode" :
-                   "no more holding disk space");
+               diskp->to_holdingdisk == HOLD_AUTO ?
+                   "no more holding disk space" :
+                   "can't dump no-hold disk in degraded mode");
     }
 
     short_dump_state();                                /* for amstatus */
@@ -393,7 +457,8 @@ main(main_argc, main_argv)
 
     if(!nodump) {
        for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
-           dumper_cmd(dumper, QUIT, NULL);
+           if(dumper->fd >= 0)
+               dumper_cmd(dumper, QUIT, NULL);
        }
     }
 
@@ -402,53 +467,10 @@ main(main_argc, main_argv)
     }
 
     /* wait for all to die */
-
-    while(1) {
-       char number[NUM_STR_SIZE];
-       pid_t pid;
-       char *who;
-       char *what;
-       int code=0;
-
-       if((pid = wait(&retstat)) == -1) {
-           if(errno == EINTR) continue;
-           else break;
-       }
-       what = NULL;
-       if(! WIFEXITED(retstat)) {
-           what = "signal";
-           code = WTERMSIG(retstat);
-       } else if(WEXITSTATUS(retstat) != 0) {
-           what = "code";
-           code = WEXITSTATUS(retstat);
-       }
-       who = NULL;
-       for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
-           if(pid == dumper->pid) {
-               who = stralloc(dumper->name);
-               break;
-           }
-       }
-       if(who == NULL && pid == taper_pid) {
-           who = stralloc("taper");
-       }
-       if(what != NULL && who == NULL) {
-           snprintf(number, sizeof(number), "%ld", (long)pid);
-           who = stralloc2("unknown pid ", number);
-       }
-       if(who && what) {
-           log_add(L_WARNING, "%s exited with %s %d\n", who, what, code);
-           printf("driver: %s exited with %s %d\n", who, what, code);
-       }
-       amfree(who);
-    }
-
-    for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
-       amfree(dumper->name);
-    }
+    wait_children(600);
 
     for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
-       cleanup_holdingdisk(hdp->diskdir, 0);
+       cleanup_holdingdisk(holdingdisk_get_diskdir(hdp), 0);
        amfree(hdp->up);
     }
     amfree(newdir);
@@ -456,10 +478,10 @@ main(main_argc, main_argv)
     check_unfree_serial();
     printf("driver: FINISHED time %s\n", walltime_str(curclock()));
     fflush(stdout);
-    log_add(L_FINISH,"date %s time %s", datestamp, walltime_str(curclock()));
-    amfree(datestamp);
-    amfree(timestamp);
+    log_add(L_FINISH,"date %s time %s", driver_timestamp, walltime_str(curclock()));
+    amfree(driver_timestamp);
 
+    free_new_argv(new_argc, new_argv);
     amfree(dumper_program);
     amfree(taper_program);
     amfree(config_dir);
@@ -471,16 +493,153 @@ main(main_argc, main_argv)
        malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
     }
 
+    dbclose();
+
     return 0;
 }
 
+/* sleep up to count seconds, and wait for terminating child process */
+/* if sleep is negative, this function will not timeout              */
+/* exit once all child process are finished or the timout expired    */
+/* return 0 if no more children to wait                              */
+/* return 1 if some children are still alive                         */
+static int
+wait_children(int count)
+{
+    pid_t     pid;
+    amwait_t  retstat;
+    char     *who;
+    char     *what;
+    int       code=0;
+    dumper_t *dumper;
+    int       wait_errno;
+
+    do {
+       do {
+           pid = waitpid((pid_t)-1, &retstat, WNOHANG);
+           wait_errno = errno;
+           if (pid > 0) {
+               what = NULL;
+               if (! WIFEXITED(retstat)) {
+                   what = "signal";
+                   code = WTERMSIG(retstat);
+               } else if (WEXITSTATUS(retstat) != 0) {
+                   what = "code";
+                   code = WEXITSTATUS(retstat);
+               }
+               who = NULL;
+               for (dumper = dmptable; dumper < dmptable + inparallel;
+                    dumper++) {
+                   if (pid == dumper->pid) {
+                       who = stralloc(dumper->name);
+                       dumper->pid = -1;
+                       break;
+                   }
+                   if (pid == dumper->chunker->pid) {
+                       who = stralloc(dumper->chunker->name);
+                       dumper->chunker->pid = -1;
+                       break;
+                   }
+               }
+               if (who == NULL && pid == taper_pid) {
+                   who = stralloc("taper");
+                   taper_pid = -1;
+               }
+               if(what != NULL && who == NULL) {
+                   who = stralloc("unknown");
+               }
+               if(who && what) {
+                   log_add(L_WARNING, "%s pid %u exited with %s %d\n", who, 
+                           (unsigned)pid, what, code);
+                   printf("driver: %s pid %u exited with %s %d\n", who,
+                          (unsigned)pid, what, code);
+               }
+               amfree(who);
+           }
+       } while (pid > 0 || wait_errno == EINTR);
+       if (errno != ECHILD)
+           sleep(1);
+       if (count > 0)
+           count--;
+    } while ((errno != ECHILD) && (count != 0));
+    return (errno != ECHILD);
+}
+
 static void
-startaflush()
+kill_children(int signal)
+{
+    dumper_t *dumper;
+
+    if(!nodump) {
+        for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
+           if (!dumper->down && dumper->pid > 1) {
+               printf("driver: sending signal %d to %s pid %u\n", signal,
+                      dumper->name, (unsigned)dumper->pid);
+               if (kill(dumper->pid, signal) == -1 && errno == ESRCH) {
+                   if (dumper->chunker)
+                       dumper->chunker->pid = 0;
+               }
+               if (dumper->chunker && dumper->chunker->pid > 1) {
+                   printf("driver: sending signal %d to %s pid %u\n", signal,
+                          dumper->chunker->name,
+                          (unsigned)dumper->chunker->pid);
+                   if (kill(dumper->chunker->pid, signal) == -1 &&
+                       errno == ESRCH)
+                       dumper->chunker->pid = 0;
+               }
+           }
+        }
+    }
+
+    if(taper_pid > 1)
+       printf("driver: sending signal %d to %s pid %u\n", signal,
+              "taper", (unsigned)taper_pid);
+       if (kill(taper_pid, signal) == -1 && errno == ESRCH)
+           taper_pid = 0;
+}
+
+static void
+wait_for_children(void)
+{
+    dumper_t *dumper;
+
+    if(!nodump) {
+       for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
+           if (dumper->pid > 1 && dumper->fd >= 0) {
+               dumper_cmd(dumper, QUIT, NULL);
+               if (dumper->chunker && dumper->chunker->pid > 1 &&
+                   dumper->chunker->fd >= 0)
+                   chunker_cmd(dumper->chunker, QUIT, NULL);
+           }
+       }
+    }
+
+    if(taper_pid > 1 && taper > 0) {
+       taper_cmd(QUIT, NULL, NULL, 0, NULL);
+    }
+
+    if(wait_children(60) == 0)
+       return;
+
+    kill_children(SIGHUP);
+    if(wait_children(60) == 0)
+       return;
+
+    kill_children(SIGKILL);
+    if(wait_children(-1) == 0)
+       return;
+
+}
+
+static void
+startaflush(void)
 {
     disk_t *dp = NULL;
     disk_t *fit = NULL;
     char *datestamp;
-    unsigned int extra_tapes = 0;
+    int extra_tapes = 0;
+    char *qname;
+
     if(!degraded_mode && !taper_busy && !empty(tapeq)) {
        
        datestamp = sched(tapeq.head)->datestamp;
@@ -491,10 +650,11 @@ startaflush()
        case ALGO_FIRSTFIT:
                fit = tapeq.head;
                while (fit != NULL) {
-                   extra_tapes = (fit->tape_splitsize > 0) ? 
-                                               conf_runtapes - current_tape : 0;
-                   if(sched(fit)->act_size <= (tape_left + tape_length*extra_tapes) &&
-                      strcmp(sched(fit)->datestamp, datestamp) <= 0) {
+                   extra_tapes = (fit->tape_splitsize > (off_t)0) ? 
+                                       conf_runtapes - current_tape : 0;
+                   if(sched(fit)->act_size <= (tape_left +
+                            tape_length * (off_t)extra_tapes) &&
+                            strcmp(sched(fit)->datestamp, datestamp) <= 0) {
                        dp = fit;
                        fit = NULL;
                    }
@@ -518,9 +678,10 @@ startaflush()
        case ALGO_LARGESTFIT:
                fit = tapeq.head;
                while (fit != NULL) {
-                   extra_tapes = (fit->tape_splitsize > 0) ? 
-                                               conf_runtapes - current_tape : 0;
-                   if(sched(fit)->act_size <= (tape_left + tape_length*extra_tapes) &&
+                   extra_tapes = (fit->tape_splitsize > (off_t)0) ? 
+                                       conf_runtapes - current_tape : 0;
+                   if(sched(fit)->act_size <=
+                      (tape_left + tape_length * (off_t)extra_tapes) &&
                       (!dp || sched(fit)->act_size > sched(dp)->act_size) &&
                       strcmp(sched(fit)->datestamp, datestamp) <= 0) {
                        dp = fit;
@@ -552,21 +713,25 @@ startaflush()
            if(dp) remove_disk(&tapeq, dp);
        }
        if(taper_ev_read == NULL) {
-           taper_ev_read = event_register(taper, EV_READFD,
+           taper_ev_read = event_register((event_id_t)taper, EV_READFD,
                                           handle_taper_result, NULL);
        }
-       if (dp != NULL) {
+       if (dp) {
            taper_disk = dp;
            taper_busy = 1;
+           qname = quote_string(dp->name);
            taper_cmd(FILE_WRITE, dp, sched(dp)->destname, sched(dp)->level,
-                 sched(dp)->datestamp);
-           fprintf(stderr,"driver: startaflush: %s %s %s %ld %ld\n",
-                   taperalgo2str(conf_taperalgo), dp->host->hostname,
-                   dp->name, sched(taper_disk)->act_size, tape_left);
+                     sched(dp)->datestamp);
+           fprintf(stderr,"driver: startaflush: %s %s %s "
+                   OFF_T_FMT " " OFF_T_FMT "\n",
+                   taperalgo2str(conf_taperalgo), dp->host->hostname, qname,
+                   (OFF_T_FMT_TYPE)sched(taper_disk)->act_size,
+                   (OFF_T_FMT_TYPE)tape_left);
            if(sched(dp)->act_size <= tape_left)
                tape_left -= sched(dp)->act_size;
            else
-               tape_left = 0;
+               tape_left = (off_t)0;
+           amfree(qname);
        } else {
            error("FATAL: Taper marked busy and no work found.");
            /*NOTREACHED*/
@@ -579,8 +744,8 @@ startaflush()
 
 
 static int
-client_constrained(dp)
-    disk_t *dp;
+client_constrained(
+    disk_t *   dp)
 {
     disk_t *dp2;
 
@@ -605,8 +770,8 @@ client_constrained(dp)
 }
 
 static void
-start_some_dumps(rq)
-    disklist_t *rq;
+start_some_dumps(
+    disklist_t *       rq)
 {
     int cur_idle;
     disk_t *diskp, *delayed_diskp, *diskp_accept;
@@ -635,7 +800,6 @@ start_some_dumps(rq)
        }
 
        if (dumper->ev_read != NULL) {
-/*         assert(dumper->ev_read == NULL);*/
            event_release(dumper->ev_read);
            dumper->ev_read = NULL;
        }
@@ -666,7 +830,7 @@ start_some_dumps(rq)
        cur_idle = NOT_IDLE;
 
        dumporder = getconf_str(CNF_DUMPORDER);
-       if(strlen(dumporder) > (dumper-dmptable)) {
+       if(strlen(dumporder) > (size_t)(dumper-dmptable)) {
            dumptype = dumporder[dumper-dmptable];
        }
        else {
@@ -679,10 +843,6 @@ start_some_dumps(rq)
        for(diskp = rq->head; diskp != NULL; diskp = diskp->next) {
            assert(diskp->host != NULL && sched(diskp) != NULL);
 
-           /* round estimate to next multiple of DISK_BLOCK_KB */
-           sched(diskp)->est_size = am_round(sched(diskp)->est_size,
-                                             DISK_BLOCK_KB);
-
            if (diskp->host->start_t > now) {
                cur_idle = max(cur_idle, IDLE_START_WAIT);
                if (delayed_diskp == NULL || sleep_time > diskp->host->start_t) {
@@ -700,12 +860,11 @@ start_some_dumps(rq)
                cur_idle = max(cur_idle, IDLE_NO_BANDWIDTH);
            } else if(sched(diskp)->no_space) {
                cur_idle = max(cur_idle, IDLE_NO_DISKSPACE);
+           } else if (diskp->to_holdingdisk == HOLD_NEVER) {
+               cur_idle = max(cur_idle, IDLE_NO_HOLD);
            } else if ((holdp =
-               find_diskspace(sched(diskp)->est_size,&cur_idle,NULL)) == NULL) {
+               find_diskspace(sched(diskp)->est_size, &cur_idle, NULL)) == NULL) {
                cur_idle = max(cur_idle, IDLE_NO_DISKSPACE);
-           } else if (diskp->no_hold) {
-               free_assignedhd(holdp);
-               cur_idle = max(cur_idle, IDLE_NO_HOLD);
            } else if (client_constrained(diskp)) {
                free_assignedhd(holdp);
                cur_idle = max(cur_idle, IDLE_CLIENT_CONSTRAINED);
@@ -762,11 +921,11 @@ start_some_dumps(rq)
        if (diskp == NULL && delayed_diskp != NULL) {
            assert(sleep_time > now);
            sleep_time -= now;
-           dumpers_ev_time = event_register(sleep_time, EV_TIME,
+           dumpers_ev_time = event_register((event_id_t)sleep_time, EV_TIME,
                handle_dumpers_time, &runq);
            return;
        } else if (diskp != NULL) {
-           sched(diskp)->act_size = 0;
+           sched(diskp)->act_size = (off_t)0;
            allocate_bandwidth(diskp->host->netif, sched(diskp)->est_kps);
            sched(diskp)->activehd = assign_holdingdisk(holdp, diskp);
            amfree(holdp);
@@ -777,42 +936,57 @@ start_some_dumps(rq)
            sched(diskp)->dumper = dumper;
            sched(diskp)->timestamp = now;
 
-           dumper->ev_read = event_register(dumper->fd, EV_READFD,
-               handle_dumper_result, dumper);
            dumper->busy = 1;           /* dumper is now busy */
            dumper->dp = diskp;         /* link disk to dumper */
            remove_disk(rq, diskp);             /* take it off the run queue */
 
-           sched(diskp)->origsize = -1;
-           sched(diskp)->dumpsize = -1;
-           sched(diskp)->dumptime = -1;
-           sched(diskp)->tapetime = -1;
+           sched(diskp)->origsize = (off_t)-1;
+           sched(diskp)->dumpsize = (off_t)-1;
+           sched(diskp)->dumptime = (time_t)0;
+           sched(diskp)->tapetime = (time_t)0;
            chunker = dumper->chunker;
            chunker->result = LAST_TOK;
            dumper->result = LAST_TOK;
            startup_chunk_process(chunker,chunker_program);
-           chunker_cmd(chunker, START, (void *)datestamp);
+           chunker_cmd(chunker, START, (void *)driver_timestamp);
            chunker->dumper = dumper;
            chunker_cmd(chunker, PORT_WRITE, diskp);
            cmd = getresult(chunker->fd, 1, &result_argc, result_argv, MAX_ARGS+1);
            if(cmd != PORT) {
+               assignedhd_t **h=NULL;
+               int activehd;
+
                printf("driver: did not get PORT from %s for %s:%s\n",
                       chunker->name, diskp->host->hostname, diskp->name);
                fflush(stdout);
-               return ;        /* fatal problem */
-           }
-           chunker->ev_read = event_register(chunker->fd, EV_READFD,
-                   handle_chunker_result, chunker);
-           dumper->output_port = atoi(result_argv[2]);
 
-           dumper_cmd(dumper, PORT_DUMP, diskp);
+               deallocate_bandwidth(diskp->host->netif, sched(diskp)->est_kps);
+               h = sched(diskp)->holdp;
+               activehd = sched(diskp)->activehd;
+               h[activehd]->used = 0;
+               holdalloc(h[activehd]->disk)->allocated_dumpers--;
+               adjust_diskspace(diskp, DONE);
+               delete_diskspace(diskp);
+               diskp->host->inprogress--;
+               diskp->inprogress = 0;
+               sched(diskp)->dumper = NULL;
+               dumper->busy = 0;
+               dumper->dp = NULL;
+               sched(diskp)->attempted++;
+               free_serial_dp(diskp);
+               if(sched(diskp)->attempted < 2)
+                   enqueue_disk(rq, diskp);
+           }
+           else {
+               dumper->ev_read = event_register((event_id_t)dumper->fd, EV_READFD,
+                                                handle_dumper_result, dumper);
+               chunker->ev_read = event_register((event_id_t)chunker->fd, EV_READFD,
+                                                  handle_chunker_result, chunker);
+               dumper->output_port = atoi(result_argv[2]);
 
+               dumper_cmd(dumper, PORT_DUMP, diskp);
+           }
            diskp->host->start_t = now + 15;
-       } else if (/* cur_idle != NOT_IDLE && */
-           (num_busy_dumpers() > 0 || taper_busy)) {
-           /*
-            * We are constrained.
-            */
        }
     }
 }
@@ -822,9 +996,10 @@ start_some_dumps(rq)
  * be because a disk has a delayed start, or amanda is constrained
  * by network or disk limits.
  */
+
 static void
-handle_dumpers_time(cookie)
-    void *cookie;
+handle_dumpers_time(
+    void *     cookie)
 {
     disklist_t *runq = cookie;
     event_release(dumpers_ev_time);
@@ -833,29 +1008,34 @@ handle_dumpers_time(cookie)
 }
 
 static void
-dump_schedule(qp, str)
-    disklist_t *qp;
-    char *str;
+dump_schedule(
+    disklist_t *qp,
+    char *     str)
 {
     disk_t *dp;
+    char *qname;
 
     printf("dump of driver schedule %s:\n--------\n", str);
 
     for(dp = qp->head; dp != NULL; dp = dp->next) {
-       printf("  %-20s %-25s lv %d t %5ld s %8lu p %d\n",
-              dp->host->hostname, dp->name, sched(dp)->level,
-              sched(dp)->est_time, sched(dp)->est_size, sched(dp)->priority);
+        qname = quote_string(dp->name);
+       printf("  %-20s %-25s lv %d t %5lu s " OFF_T_FMT " p %d\n",
+              dp->host->hostname, qname, sched(dp)->level,
+              sched(dp)->est_time,
+              (OFF_T_FMT_TYPE)sched(dp)->est_size, sched(dp)->priority);
+        amfree(qname);
     }
     printf("--------\n");
 }
 
 static void
-start_degraded_mode(queuep)
-    disklist_t *queuep;
+start_degraded_mode(
+    /*@keep@*/ disklist_t *queuep)
 {
     disk_t *dp;
     disklist_t newq;
-    unsigned long est_full_size;
+    off_t est_full_size;
+    char *qname;
 
     if (taper_ev_read != NULL) {
        event_release(taper_ev_read);
@@ -866,10 +1046,11 @@ start_degraded_mode(queuep)
 
     dump_schedule(queuep, "before start degraded mode");
 
-    est_full_size = 0;
+    est_full_size = (off_t)0;
     while(!empty(*queuep)) {
        dp = dequeue_disk(queuep);
 
+       qname = quote_string(dp->name);
        if(sched(dp)->level != 0)
            /* go ahead and do the disk as-is */
            enqueue_disk(&newq, dp);
@@ -882,27 +1063,30 @@ start_degraded_mode(queuep)
            else if(sched(dp)->degr_level != -1) {
                sched(dp)->level = sched(dp)->degr_level;
                sched(dp)->dumpdate = sched(dp)->degr_dumpdate;
-               sched(dp)->est_size = sched(dp)->degr_size;
+               sched(dp)->est_nsize = sched(dp)->degr_nsize;
+               sched(dp)->est_csize = sched(dp)->degr_csize;
                sched(dp)->est_time = sched(dp)->degr_time;
                sched(dp)->est_kps  = sched(dp)->degr_kps;
                enqueue_disk(&newq, dp);
            }
            else {
                log_add(L_FAIL,"%s %s %s %d [can't switch to incremental dump]",
-                       dp->host->hostname, dp->name, sched(dp)->datestamp,
+                       dp->host->hostname, qname, sched(dp)->datestamp,
                        sched(dp)->level);
            }
        }
+        amfree(qname);
     }
 
-    *queuep = newq;
+    /*@i@*/ *queuep = newq;
     degraded_mode = 1;
 
     dump_schedule(queuep, "after start degraded mode");
 }
 
 
-static void continue_port_dumps()
+static void
+continue_port_dumps(void)
 {
     disk_t *dp, *ndp;
     assignedhd_t **h;
@@ -913,13 +1097,17 @@ static void continue_port_dumps()
     for( dp = roomq.head; dp; dp = ndp ) {
        ndp = dp->next;
        /* find last holdingdisk used by this dump */
-       for( i = 0, h = sched(dp)->holdp; h[i+1]; i++ );
+       for( i = 0, h = sched(dp)->holdp; h[i+1]; i++ ) {
+           (void)h; /* Quiet lint */
+       }
        /* find more space */
        h = find_diskspace( sched(dp)->est_size - sched(dp)->act_size,
                            &active_dumpers, h[i] );
        if( h ) {
            for(dumper = dmptable; dumper < dmptable + inparallel &&
-                                  dumper->dp != dp; dumper++);
+                                  dumper->dp != dp; dumper++) {
+               (void)dp; /* Quiet lint */
+           }
            assert( dumper < dmptable + inparallel );
            sched(dp)->activehd = assign_holdingdisk( h, dp );
            chunker_cmd( dumper->chunker, CONTINUE, dp );
@@ -965,7 +1153,7 @@ static void continue_port_dumps()
         * We abort that dump, hopefully not wasting too much time retrying it.
         */
        remove_disk( &roomq, dp );
-       chunker_cmd( sched(dp)->dumper->chunker, ABORT, NULL );
+       chunker_cmd( sched(dp)->dumper->chunker, ABORT, NULL);
        dumper_cmd( sched(dp)->dumper, ABORT, NULL );
        pending_aborts++;
     }
@@ -973,15 +1161,18 @@ static void continue_port_dumps()
 
 
 static void
-handle_taper_result(void *cookie)
+handle_taper_result(
+    void *     cookie)
 {
     disk_t *dp;
-    int filenum;
+    off_t filenum;
     cmd_t cmd;
     int result_argc;
     char *result_argv[MAX_ARGS+1];
     int avail_tapes = 0;
     
+    (void)cookie;      /* Quiet unused parameter warning */
+
     assert(cookie == NULL);
     
     do {
@@ -996,12 +1187,13 @@ handle_taper_result(void *cookie)
        case DONE:      /* DONE <handle> <label> <tape file> <err mess> */
            if(result_argc != 5) {
                error("error: [taper DONE result_argc != 5: %d", result_argc);
+               /*NOTREACHED*/
            }
             
            dp = serial2disk(result_argv[2]);
            free_serial(result_argv[2]);
             
-           filenum = atoi(result_argv[4]);
+           filenum = OFF_T_ATOI(result_argv[4]);
            if(cmd == DONE) {
                update_info_taper(dp, result_argv[3], filenum,
                                   sched(dp)->level);
@@ -1031,6 +1223,7 @@ handle_taper_result(void *cookie)
            if (result_argc < 2) {
                error("error [taper TRYAGAIN result_argc < 2: %d]",
                      result_argc);
+               /*NOTREACHED*/
            }
            dp = serial2disk(result_argv[2]);
            free_serial(result_argv[2]);
@@ -1041,7 +1234,7 @@ handle_taper_result(void *cookie)
            /* See how many tapes we have left, but we alwyays
               retry once (why?) */
            current_tape++;
-           if(dp->tape_splitsize > 0)
+           if(dp->tape_splitsize > (off_t)0)
                avail_tapes = conf_runtapes - current_tape;
            else
                avail_tapes = 0;
@@ -1073,6 +1266,7 @@ handle_taper_result(void *cookie)
             if (result_argc != 3) {
                 error("error [taper SPLIT_CONTINUE result_argc != 3: %d]",
                       result_argc);
+               /*NOTREACHED*/
             }
             
             break;
@@ -1080,6 +1274,7 @@ handle_taper_result(void *cookie)
             if (result_argc != 3) {
                 error("error [taper SPLIT_NEEDNEXT result_argc != 3: %d]",
                       result_argc);
+               /*NOTREACHED*/
             }
             
             /* Update our tape counter and reset tape_left */
@@ -1089,7 +1284,7 @@ handle_taper_result(void *cookie)
             /* Reduce the size of the dump by amount written and reduce
                tape_left by the amount left over */
             dp = serial2disk(result_argv[2]);
-            sched(dp)->act_size -= atoi(result_argv[3]);
+            sched(dp)->act_size -= OFF_T_ATOI(result_argv[3]);
             if (sched(dp)->act_size < tape_left)
                 tape_left -= sched(dp)->act_size;
             else
@@ -1104,14 +1299,14 @@ handle_taper_result(void *cookie)
                    walltime_str(curclock()), dp->host->hostname, dp->name);
             fflush(stdout);
             log_add(L_WARNING, "Taper  error: %s", result_argv[3]);
-            /* FALLSTHROUGH */
+            /*FALLTHROUGH*/
 
         case BOGUS:
             if (cmd == BOGUS) {
                log_add(L_WARNING, "Taper protocol error");
             }
             /*
-             * Since we've gotten a taper error, we can't send anything more
+             * Since we received a taper error, we can't send anything more
              * to the taper.  Go into degraded mode to try to get everthing
              * onto disk.  Later, these dumps can be flushed to a new tape.
              * The tape queue is zapped so that it appears empty in future
@@ -1137,6 +1332,7 @@ handle_taper_result(void *cookie)
        default:
             error("driver received unexpected token (%s) from taper",
                   cmdstr[cmd]);
+           /*NOTREACHED*/
        }
        /*
         * Wakeup any dumpers that are sleeping because of network
@@ -1148,7 +1344,7 @@ handle_taper_result(void *cookie)
 }
 
 static dumper_t *
-idle_dumper()
+idle_dumper(void)
 {
     dumper_t *dumper;
 
@@ -1158,29 +1354,16 @@ idle_dumper()
     return NULL;
 }
 
-static int
-num_busy_dumpers()
-{
-    dumper_t *dumper;
-    int n;
-
-    n = 0;
-    for(dumper = dmptable; dumper < dmptable+inparallel; dumper++)
-       if(dumper->busy) n += 1;
-
-    return n;
-}
-
-
 static void
-dumper_result(dp)
-    disk_t *dp;
+dumper_result(
+    disk_t *   dp)
 {
     dumper_t *dumper;
     chunker_t *chunker;
     assignedhd_t **h=NULL;
-    int activehd, i, dummy;
-    long size;
+    int activehd, i;
+    off_t dummy;
+    off_t size;
     int is_partial;
 
     dumper = sched(dp)->dumper;
@@ -1194,6 +1377,13 @@ dumper_result(dp)
     if(dumper->result == DONE && chunker->result == DONE) {
        update_info_dumper(dp, sched(dp)->origsize,
                           sched(dp)->dumpsize, sched(dp)->dumptime);
+       log_add(L_STATS, "estimate %s %s %s %d [sec %ld nkb " OFF_T_FMT
+               " ckb " OFF_T_FMT " kps %d]",
+               dp->host->hostname, dp->name, sched(dp)->datestamp,
+               sched(dp)->level,
+               sched(dp)->est_time, (OFF_T_FMT_TYPE)sched(dp)->est_nsize, 
+                (OFF_T_FMT_TYPE)sched(dp)->est_csize,
+               sched(dp)->est_kps);
     }
 
     deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
@@ -1201,7 +1391,7 @@ dumper_result(dp)
     is_partial = dumper->result != DONE || chunker->result != DONE;
     rename_tmp_holding(sched(dp)->destname, !is_partial);
 
-    dummy = 0;
+    dummy = (off_t)0;
     for( i = 0, h = sched(dp)->holdp; i < activehd; i++ ) {
        dummy += h[i]->used;
     }
@@ -1218,7 +1408,7 @@ dumper_result(dp)
        delete_diskspace(dp);
        enqueue_disk(&runq, dp);
     }
-    else if(size > DISK_BLOCK_KB) {
+    else if(size > (off_t)DISK_BLOCK_KB) {
        sched(dp)->attempted = 0;
        enqueue_disk(&tapeq, dp);
        startaflush();
@@ -1237,6 +1427,8 @@ dumper_result(dp)
     chunker->down = 1;
     
     dp = NULL;
+    if (chunker->result == ABORT_FINISHED)
+       pending_aborts--;
     continue_port_dumps();
     /*
      * Wakeup any dumpers that are sleeping because of network
@@ -1247,14 +1439,15 @@ dumper_result(dp)
 
 
 static void
-handle_dumper_result(cookie)
-    void *cookie;
+handle_dumper_result(
+    void *     cookie)
 {
     /*static int pending_aborts = 0;*/
     dumper_t *dumper = cookie;
     disk_t *dp, *sdp;
     cmd_t cmd;
     int result_argc;
+    char *qname;
     char *result_argv[MAX_ARGS+1];
 
     assert(dumper != NULL);
@@ -1270,24 +1463,29 @@ handle_dumper_result(cookie)
        if(cmd != BOGUS) {
            /* result_argv[2] always contains the serial number */
            sdp = serial2disk(result_argv[2]);
-           assert(sdp == dp);
+           if (sdp != dp) {
+               error("%s: Invalid serial number", get_pname(), result_argv[2]);
+               /*NOTREACHED*/
+           }
        }
 
+       qname = quote_string(dp->name);
        switch(cmd) {
 
        case DONE: /* DONE <handle> <origsize> <dumpsize> <dumptime> <errstr> */
            if(result_argc != 6) {
                error("error [dumper DONE result_argc != 6: %d]", result_argc);
+               /*NOTREACHED*/
            }
 
            /*free_serial(result_argv[2]);*/
 
-           sched(dp)->origsize = (long)atof(result_argv[3]);
-           sched(dp)->dumptime = (long)atof(result_argv[5]);
+           sched(dp)->origsize = OFF_T_ATOI(result_argv[3]);
+           sched(dp)->dumptime = TIME_T_ATOI(result_argv[5]);
 
            printf("driver: finished-cmd time %s %s dumped %s:%s\n",
                   walltime_str(curclock()), dumper->name,
-                  dp->host->hostname, dp->name);
+                  dp->host->hostname, qname);
            fflush(stdout);
 
            dumper->result = cmd;
@@ -1329,8 +1527,10 @@ handle_dumper_result(cookie)
            /* either EOF or garbage from dumper.  Turn it off */
            log_add(L_WARNING, "%s pid %ld is messed up, ignoring it.\n",
                    dumper->name, (long)dumper->pid);
-           event_release(dumper->ev_read);
-           dumper->ev_read = NULL;
+           if (dumper->ev_read) {
+               event_release(dumper->ev_read);
+               dumper->ev_read = NULL;
+           }
            aclose(dumper->fd);
            dumper->busy = 0;
            dumper->down = 1;   /* mark it down so it isn't used again */
@@ -1338,12 +1538,12 @@ handle_dumper_result(cookie)
                /* if it was dumping something, zap it and try again */
                if(sched(dp)->attempted) {
                log_add(L_FAIL, "%s %s %s %d [%s died]",
-                       dp->host->hostname, dp->name, sched(dp)->datestamp,
+                       dp->host->hostname, qname, sched(dp)->datestamp,
                        sched(dp)->level, dumper->name);
                }
                else {
                log_add(L_WARNING, "%s died while dumping %s:%s lev %d.",
-                       dumper->name, dp->host->hostname, dp->name,
+                       dumper->name, dp->host->hostname, qname,
                        sched(dp)->level);
                }
            }
@@ -1353,8 +1553,11 @@ handle_dumper_result(cookie)
        default:
            assert(0);
        }
+        amfree(qname);
+
        /* send the dumper result to the chunker */
-       if(dumper->chunker->down == 0 && dumper->chunker->fd != -1) {
+       if(dumper->chunker->down == 0 && dumper->chunker->fd != -1 &&
+          dumper->chunker->result == LAST_TOK) {
            if(cmd == DONE) {
                chunker_cmd(dumper->chunker, DONE, dp);
            }
@@ -1371,8 +1574,8 @@ handle_dumper_result(cookie)
 
 
 static void
-handle_chunker_result(cookie)
-    void *cookie;
+handle_chunker_result(
+    void *     cookie)
 {
     /*static int pending_aborts = 0;*/
     chunker_t *chunker = cookie;
@@ -1384,7 +1587,7 @@ handle_chunker_result(cookie)
     char *result_argv[MAX_ARGS+1];
     int dummy;
     int activehd = -1;
-
+    char *qname;
 
     assert(chunker != NULL);
     dumper = chunker->dumper;
@@ -1409,7 +1612,10 @@ handle_chunker_result(cookie)
        if(cmd != BOGUS) {
            /* result_argv[2] always contains the serial number */
            sdp = serial2disk(result_argv[2]);
-           assert(sdp == dp);
+           if (sdp != dp) {
+               error("%s: Invalid serial number", get_pname(), result_argv[2]);
+               /*NOTREACHED*/
+           }
        }
 
        switch(cmd) {
@@ -1419,15 +1625,18 @@ handle_chunker_result(cookie)
            if(result_argc != 4) {
                error("error [chunker %s result_argc != 4: %d]", cmdstr[cmd],
                      result_argc);
+               /*NOTREACHED*/
            }
            /*free_serial(result_argv[2]);*/
 
-           sched(dp)->dumpsize = (long)atof(result_argv[3]);
+           sched(dp)->dumpsize = (off_t)atof(result_argv[3]);
 
+           qname = quote_string(dp->name);
            printf("driver: finished-cmd time %s %s chunked %s:%s\n",
                   walltime_str(curclock()), chunker->name,
-                  dp->host->hostname, dp->name);
+                  dp->host->hostname, qname);
            fflush(stdout);
+            amfree(qname);
 
            event_release(chunker->ev_read);
 
@@ -1436,9 +1645,10 @@ handle_chunker_result(cookie)
            break;
 
        case TRYAGAIN: /* TRY-AGAIN <handle> <errstr> */
-           assert(0);
            event_release(chunker->ev_read);
 
+           chunker->result = cmd;
+
            break;
        case FAILED: /* FAILED <handle> <errstr> */
            /*free_serial(result_argv[2]);*/
@@ -1450,15 +1660,21 @@ handle_chunker_result(cookie)
            break;
 
        case NO_ROOM: /* NO-ROOM <handle> <missing_size> */
-           assert( h && activehd >= 0 );
-           h[activehd]->used -= atoi(result_argv[3]);
-           h[activehd]->reserved -= atoi(result_argv[3]);
-           holdalloc(h[activehd]->disk)->allocated_space -= atoi(result_argv[3]);
-           h[activehd]->disk->disksize -= atoi(result_argv[3]);
+           if (!h || activehd < 0) { /* should never happen */
+               error("!h || activehd < 0");
+               /*NOTREACHED*/
+           }
+           h[activehd]->used -= OFF_T_ATOI(result_argv[3]);
+           h[activehd]->reserved -= OFF_T_ATOI(result_argv[3]);
+           holdalloc(h[activehd]->disk)->allocated_space -= OFF_T_ATOI(result_argv[3]);
+           h[activehd]->disk->disksize -= OFF_T_ATOI(result_argv[3]);
            break;
 
        case RQ_MORE_DISK: /* RQ-MORE-DISK <handle> */
-           assert( h && activehd >= 0 );
+           if (!h || activehd < 0) { /* should never happen */
+               error("!h || activehd < 0");
+               /*NOTREACHED*/
+           }
            holdalloc(h[activehd]->disk)->allocated_dumpers--;
            h[activehd]->used = h[activehd]->reserved;
            if( h[++activehd] ) { /* There's still some allocated space left.
@@ -1467,11 +1683,10 @@ handle_chunker_result(cookie)
                chunker_cmd( chunker, CONTINUE, dp );
            } else { /* !h[++activehd] - must allocate more space */
                sched(dp)->act_size = sched(dp)->est_size; /* not quite true */
-               sched(dp)->est_size = (sched(dp)->act_size/20) * 21; /* +5% */
-               sched(dp)->est_size = am_round(sched(dp)->est_size, DISK_BLOCK_KB);
-               if(sched(dp)->est_size <=  sched(dp)->act_size + DISK_BLOCK_KB)
-                   sched(dp)->est_size = sched(dp)->act_size + 
-                                         2 * DISK_BLOCK_KB;
+               sched(dp)->est_size = (sched(dp)->act_size/(off_t)20) * (off_t)21; /* +5% */
+               sched(dp)->est_size = am_round(sched(dp)->est_size, (off_t)DISK_BLOCK_KB);
+               if (sched(dp)->est_size < sched(dp)->act_size + 2*DISK_BLOCK_KB)
+                   sched(dp)->est_size += 2 * DISK_BLOCK_KB;
                h = find_diskspace( sched(dp)->est_size - sched(dp)->act_size,
                                    &dummy,
                                    h[activehd-1] );
@@ -1513,17 +1728,22 @@ handle_chunker_result(cookie)
 
            if(dp) {
                /* if it was dumping something, zap it and try again */
-               assert( h && activehd >= 0 );
+               if (!h || activehd < 0) { /* should never happen */
+                   error("!h || activehd < 0");
+                   /*NOTREACHED*/
+               }
+               qname = quote_string(dp->name);
                if(sched(dp)->attempted) {
                    log_add(L_FAIL, "%s %s %s %d [%s died]",
-                           dp->host->hostname, dp->name, sched(dp)->datestamp,
+                           dp->host->hostname, qname, sched(dp)->datestamp,
                            sched(dp)->level, chunker->name);
                }
                else {
                    log_add(L_WARNING, "%s died while dumping %s:%s lev %d.",
-                           chunker->name, dp->host->hostname, dp->name,
+                           chunker->name, dp->host->hostname, qname,
                            sched(dp)->level);
                }
+               amfree(qname);
                dp = NULL;
            }
 
@@ -1545,7 +1765,7 @@ handle_chunker_result(cookie)
 
 
 static disklist_t
-read_flush()
+read_flush(void)
 {
     sched_t *sp;
     disk_t *dp;
@@ -1560,11 +1780,14 @@ read_flush()
     char *s;
     int ch;
     disklist_t tq;
+    char *qname = NULL;
 
     tq.head = tq.tail = NULL;
 
     for(line = 0; (inpline = agets(stdin)) != NULL; free(inpline)) {
        line++;
+       if (inpline[0] == '\0')
+           continue;
 
        s = inpline;
        ch = *s++;
@@ -1572,7 +1795,7 @@ read_flush()
        skip_whitespace(s, ch);                 /* find the command */
        if(ch == '\0') {
            error("flush line %d: syntax error (no command)", line);
-           continue;
+           /*NOTREACHED*/
        }
        command = s - 1;
        skip_non_whitespace(s, ch);
@@ -1584,13 +1807,13 @@ read_flush()
 
        if(strcmp(command,"FLUSH") != 0) {
            error("flush line %d: syntax error (%s != FLUSH)", line, command);
-           continue;
+           /*NOTREACHED*/
        }
 
        skip_whitespace(s, ch);                 /* find the hostname */
        if(ch == '\0') {
            error("flush line %d: syntax error (no hostname)", line);
-           continue;
+           /*NOTREACHED*/
        }
        hostname = s - 1;
        skip_non_whitespace(s, ch);
@@ -1599,16 +1822,17 @@ read_flush()
        skip_whitespace(s, ch);                 /* find the diskname */
        if(ch == '\0') {
            error("flush line %d: syntax error (no diskname)", line);
-           continue;
+           /*NOTREACHED*/
        }
-       diskname = s - 1;
-       skip_non_whitespace(s, ch);
-       s[-1] = '\0';
+       qname = s - 1;
+       skip_quoted_string(s, ch);
+       s[-1] = '\0';                           /* terminate the disk name */
+       diskname = unquote_string(qname);
 
        skip_whitespace(s, ch);                 /* find the datestamp */
        if(ch == '\0') {
            error("flush line %d: syntax error (no datestamp)", line);
-           continue;
+           /*NOTREACHED*/
        }
        datestamp = s - 1;
        skip_non_whitespace(s, ch);
@@ -1617,14 +1841,14 @@ read_flush()
        skip_whitespace(s, ch);                 /* find the level number */
        if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
            error("flush line %d: syntax error (bad level)", line);
-           continue;
+           /*NOTREACHED*/
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);                 /* find the filename */
        if(ch == '\0') {
            error("flush line %d: syntax error (no filename)", line);
-           continue;
+           /*NOTREACHED*/
        }
        destname = s - 1;
        skip_non_whitespace(s, ch);
@@ -1634,6 +1858,7 @@ read_flush()
        if( file.type != F_DUMPFILE) {
            if( file.type != F_CONT_DUMPFILE )
                log_add(L_INFO, "%s: ignoring cruft file.", destname);
+           amfree(diskname);
            continue;
        }
 
@@ -1642,8 +1867,10 @@ read_flush()
           strcmp(datestamp, file.datestamp) != 0) {
            log_add(L_INFO, "disk %s:%s not consistent with file %s",
                    hostname, diskname, destname);
+           amfree(diskname);
            continue;
        }
+       amfree(diskname);
 
        dp = lookup_disk(file.name, file.disk);
 
@@ -1659,13 +1886,13 @@ read_flush()
            continue;
        }
 
-       dp1 = (disk_t *)alloc(sizeof(disk_t));
+       dp1 = (disk_t *)alloc(SIZEOF(disk_t));
        *dp1 = *dp;
        dp1->next = dp1->prev = NULL;
 
        /* add it to the flushhost list */
        if(!flushhost) {
-           flushhost = alloc(sizeof(am_host_t));
+           flushhost = alloc(SIZEOF(am_host_t));
            flushhost->next = NULL;
            flushhost->hostname = stralloc("FLUSHHOST");
            flushhost->up = NULL;
@@ -1674,17 +1901,18 @@ read_flush()
        dp1->hostnext = flushhost->disks;
        flushhost->disks = dp1;
 
-       sp = (sched_t *) alloc(sizeof(sched_t));
+       sp = (sched_t *) alloc(SIZEOF(sched_t));
        sp->destname = stralloc(destname);
        sp->level = file.dumplevel;
        sp->dumpdate = NULL;
        sp->degr_dumpdate = NULL;
        sp->datestamp = stralloc(file.datestamp);
-       sp->est_size = 0;
+       sp->est_nsize = (off_t)0;
+       sp->est_csize = (off_t)0;
        sp->est_time = 0;
+       sp->est_kps = 10;
        sp->priority = 0;
        sp->degr_level = -1;
-       sp->est_kps = 10;
        sp->attempted = 0;
        sp->act_size = size_holding_files(destname, 0);
        sp->holdp = build_diskspace(destname);
@@ -1698,34 +1926,39 @@ read_flush()
     }
     amfree(inpline);
 
-    return tq;
+    /*@i@*/ return tq;
 }
 
 static void
-read_schedule(cookie)
-    void *cookie;
+read_schedule(
+    void *     cookie)
 {
     sched_t *sp;
     disk_t *dp;
-    disklist_t rq;
     int level, line, priority;
     char *dumpdate, *degr_dumpdate;
     int degr_level;
-    long time, degr_time;
-    unsigned long size, degr_size;
+    time_t time, degr_time;
+    time_t *time_p = &time;
+    time_t *degr_time_p = &degr_time;
+    off_t nsize, csize, degr_nsize, degr_csize;
+    unsigned long kps, degr_kps;
     char *hostname, *features, *diskname, *datestamp, *inpline = NULL;
     char *command;
     char *s;
     int ch;
-    long flush_size = 0;
+    off_t flush_size = (off_t)0;
+    char *qname = NULL;
 
-    rq.head = rq.tail = NULL;
+    (void)cookie;      /* Quiet unused parameter warning */
 
     event_release(schedule_ev_read);
 
     /* read schedule from stdin */
 
     for(line = 0; (inpline = agets(stdin)) != NULL; free(inpline)) {
+       if (inpline[0] == '\0')
+           continue;
        line++;
 
        s = inpline;
@@ -1734,7 +1967,7 @@ read_schedule(cookie)
        skip_whitespace(s, ch);                 /* find the command */
        if(ch == '\0') {
            error("schedule line %d: syntax error (no command)", line);
-           continue;
+           /*NOTREACHED*/
        }
        command = s - 1;
        skip_non_whitespace(s, ch);
@@ -1742,13 +1975,13 @@ read_schedule(cookie)
 
        if(strcmp(command,"DUMP") != 0) {
            error("schedule line %d: syntax error (%s != DUMP)", line, command);
-           continue;
+           /*NOTREACHED*/
        }
 
        skip_whitespace(s, ch);                 /* find the host name */
        if(ch == '\0') {
            error("schedule line %d: syntax error (no host name)", line);
-           continue;
+           /*NOTREACHED*/
        }
        hostname = s - 1;
        skip_non_whitespace(s, ch);
@@ -1757,7 +1990,7 @@ read_schedule(cookie)
        skip_whitespace(s, ch);                 /* find the feature list */
        if(ch == '\0') {
            error("schedule line %d: syntax error (no feature list)", line);
-           continue;
+           /*NOTREACHED*/
        }
        features = s - 1;
        skip_non_whitespace(s, ch);
@@ -1766,16 +1999,17 @@ read_schedule(cookie)
        skip_whitespace(s, ch);                 /* find the disk name */
        if(ch == '\0') {
            error("schedule line %d: syntax error (no disk name)", line);
-           continue;
+           /*NOTREACHED*/
        }
-       diskname = s - 1;
-       skip_non_whitespace(s, ch);
-       s[-1] = '\0';
+       qname = s - 1;
+       skip_quoted_string(s, ch);
+       s[-1] = '\0';                           /* terminate the disk name */
+       diskname = unquote_string(qname);
 
        skip_whitespace(s, ch);                 /* find the datestamp */
        if(ch == '\0') {
            error("schedule line %d: syntax error (no datestamp)", line);
-           continue;
+           /*NOTREACHED*/
        }
        datestamp = s - 1;
        skip_non_whitespace(s, ch);
@@ -1784,36 +2018,53 @@ read_schedule(cookie)
        skip_whitespace(s, ch);                 /* find the priority number */
        if(ch == '\0' || sscanf(s - 1, "%d", &priority) != 1) {
            error("schedule line %d: syntax error (bad priority)", line);
-           continue;
+           /*NOTREACHED*/
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);                 /* find the level number */
        if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
            error("schedule line %d: syntax error (bad level)", line);
-           continue;
+           /*NOTREACHED*/
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);                 /* find the dump date */
        if(ch == '\0') {
            error("schedule line %d: syntax error (bad dump date)", line);
-           continue;
+           /*NOTREACHED*/
        }
        dumpdate = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
 
-       skip_whitespace(s, ch);                 /* find the size number */
-       if(ch == '\0' || sscanf(s - 1, "%lu", &size) != 1) {
-           error("schedule line %d: syntax error (bad size)", line);
-           continue;
+       skip_whitespace(s, ch);                 /* find the native size */
+       if(ch == '\0' || sscanf(s - 1, OFF_T_FMT, 
+                               (OFF_T_FMT_TYPE *)&nsize) != 1) {
+           error("schedule line %d: syntax error (bad nsize)", line);
+           /*NOTREACHED*/
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);                 /* find the compressed size */
+       if(ch == '\0' || sscanf(s - 1, OFF_T_FMT, 
+                               (OFF_T_FMT_TYPE *)&csize) != 1) {
+           error("schedule line %d: syntax error (bad csize)", line);
+           /*NOTREACHED*/
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);                 /* find the time number */
-       if(ch == '\0' || sscanf(s - 1, "%ld", &time) != 1) {
+       if(ch == '\0' || sscanf(s - 1, TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)time_p) != 1) {
            error("schedule line %d: syntax error (bad estimated time)", line);
+           /*NOTREACHED*/
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);                 /* find the kps number */
+       if(ch == '\0' || sscanf(s - 1, "%lu", &kps) != 1) {
+           error("schedule line %d: syntax error (bad kps)", line);
            continue;
        }
        skip_integer(s, ch);
@@ -1823,30 +2074,47 @@ read_schedule(cookie)
        if(ch != '\0') {
            if(sscanf(s - 1, "%d", &degr_level) != 1) {
                error("schedule line %d: syntax error (bad degr level)", line);
-               continue;
+               /*NOTREACHED*/
            }
            skip_integer(s, ch);
 
            skip_whitespace(s, ch);             /* find the degr dump date */
            if(ch == '\0') {
                error("schedule line %d: syntax error (bad degr dump date)", line);
-               continue;
+               /*NOTREACHED*/
            }
            degr_dumpdate = s - 1;
            skip_non_whitespace(s, ch);
            s[-1] = '\0';
 
-           skip_whitespace(s, ch);             /* find the degr size number */
-           if(ch == '\0'  || sscanf(s - 1, "%lu", &degr_size) != 1) {
-               error("schedule line %d: syntax error (bad degr size)", line);
-               continue;
+           skip_whitespace(s, ch);             /* find the degr native size */
+           if(ch == '\0'  || sscanf(s - 1, OFF_T_FMT, 
+                       (OFF_T_FMT_TYPE *)&degr_nsize) != 1) {
+               error("schedule line %d: syntax error (bad degr nsize)", line);
+               /*NOTREACHED*/
+           }
+           skip_integer(s, ch);
+
+           skip_whitespace(s, ch);             /* find the degr compressed size */
+           if(ch == '\0'  || sscanf(s - 1, OFF_T_FMT, 
+                       (OFF_T_FMT_TYPE *)&degr_csize) != 1) {
+               error("schedule line %d: syntax error (bad degr csize)", line);
+               /*NOTREACHED*/
            }
            skip_integer(s, ch);
 
            skip_whitespace(s, ch);             /* find the degr time number */
-           if(ch == '\0' || sscanf(s - 1, "%lu", &degr_time) != 1) {
+           if(ch == '\0' || sscanf(s - 1, TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)degr_time_p) != 1) {
                error("schedule line %d: syntax error (bad degr estimated time)", line);
-               continue;
+               /*NOTREACHED*/
+           }
+           skip_integer(s, ch);
+
+           skip_whitespace(s, ch);             /* find the degr kps number */
+           if(ch == '\0' || sscanf(s - 1, "%lu", &degr_kps) != 1) {
+               error("schedule line %d: syntax error (bad degr kps)", line);
+               /*NOTREACHED*/
            }
            skip_integer(s, ch);
        }
@@ -1854,43 +2122,43 @@ read_schedule(cookie)
        dp = lookup_disk(hostname, diskname);
        if(dp == NULL) {
            log_add(L_WARNING,
-                   "schedule line %d: %s:%s not in disklist, ignored",
-                   line, hostname, diskname);
+                   "schedule line %d: %s:'%s' not in disklist, ignored",
+                   line, hostname, qname);
+           amfree(diskname);
            continue;
        }
 
-       sp = (sched_t *) alloc(sizeof(sched_t));
-       sp->level    = level;
+       sp = (sched_t *) alloc(SIZEOF(sched_t));
+       /*@ignore@*/
+       sp->level = level;
        sp->dumpdate = stralloc(dumpdate);
-       sp->est_size = DISK_BLOCK_KB + size; /* include header */
+       sp->est_nsize = DISK_BLOCK_KB + nsize; /* include header */
+       sp->est_csize = DISK_BLOCK_KB + csize; /* include header */
+       /* round estimate to next multiple of DISK_BLOCK_KB */
+       sp->est_csize = am_round(sp->est_csize, DISK_BLOCK_KB);
+       sp->est_size = sp->est_csize;
        sp->est_time = time;
+       sp->est_kps = kps;
        sp->priority = priority;
        sp->datestamp = stralloc(datestamp);
 
        if(degr_dumpdate) {
            sp->degr_level = degr_level;
            sp->degr_dumpdate = stralloc(degr_dumpdate);
-           sp->degr_size = DISK_BLOCK_KB + degr_size;
+           sp->degr_nsize = DISK_BLOCK_KB + degr_nsize;
+           sp->degr_csize = DISK_BLOCK_KB + degr_csize;
+           /* round estimate to next multiple of DISK_BLOCK_KB */
+           sp->degr_csize = am_round(sp->degr_csize, DISK_BLOCK_KB);
            sp->degr_time = degr_time;
+           sp->degr_kps = degr_kps;
        } else {
            sp->degr_level = -1;
            sp->degr_dumpdate = NULL;
        }
-
-       if(time <= 0)
-           sp->est_kps = 10;
-       else
-           sp->est_kps = size/time;
-
-       if(sp->degr_level != -1) {
-           if(degr_time <= 0)
-               sp->degr_kps = 10;
-           else
-               sp->degr_kps = degr_size/degr_time;
-       }
+       /*@end@*/
 
        sp->attempted = 0;
-       sp->act_size = 0;
+       sp->act_size = (off_t)0;
        sp->holdp = NULL;
        sp->activehd = -1;
        sp->dumper = NULL;
@@ -1905,8 +2173,9 @@ read_schedule(cookie)
        remove_disk(&waitq, dp);
        enqueue_disk(&runq, dp);
        flush_size += sp->act_size;
+       amfree(diskname);
     }
-    printf("driver: flush size %ld\n", flush_size);
+    printf("driver: flush size " OFF_T_FMT "\n", (OFF_T_FMT_TYPE)flush_size);
     amfree(inpline);
     if(line == 0)
        log_add(L_WARNING, "WARNING: got empty schedule from planner");
@@ -1914,83 +2183,80 @@ read_schedule(cookie)
     start_some_dumps(&runq);
 }
 
-static int
-free_kps(ip)
-    interface_t *ip;
+static unsigned long
+free_kps(
+    interface_t *ip)
 {
-    int res;
+    unsigned long res;
 
     if (ip == (interface_t *)0) {
        interface_t *p;
-       int maxusage=0;
-       int curusage=0;
+       unsigned long maxusage=0;
+       unsigned long curusage=0;
        for(p = lookup_interface(NULL); p != NULL; p = p->next) {
-           maxusage += p->maxusage;
+           maxusage += interface_get_maxusage(p);
            curusage += p->curusage;
        }
        res = maxusage - curusage;
-    }
-    else {
-       res = ip->maxusage - ip->curusage;
+#ifndef __lint
+    } else {
+       res = interface_get_maxusage(ip) - ip->curusage;
+#endif
     }
 
     return res;
 }
 
 static void
-interface_state(time_str)
-    char *time_str;
+interface_state(
+    char *time_str)
 {
     interface_t *ip;
 
     printf("driver: interface-state time %s", time_str);
 
     for(ip = lookup_interface(NULL); ip != NULL; ip = ip->next) {
-       printf(" if %s: free %d", ip->name, free_kps(ip));
+       printf(" if %s: free %lu", ip->name, free_kps(ip));
     }
     printf("\n");
 }
 
 static void
-allocate_bandwidth(ip, kps)
-    interface_t *ip;
-    int kps;
+allocate_bandwidth(
+    interface_t *      ip,
+    unsigned long      kps)
 {
     ip->curusage += kps;
 }
 
 static void
-deallocate_bandwidth(ip, kps)
-    interface_t *ip;
-    int kps;
+deallocate_bandwidth(
+    interface_t *      ip,
+    unsigned long      kps)
 {
     assert(kps <= ip->curusage);
     ip->curusage -= kps;
 }
 
 /* ------------ */
-static unsigned long
-free_space()
+static off_t
+free_space(void)
 {
     holdingdisk_t *hdp;
-    unsigned long total_free;
-    long diff;
+    off_t total_free;
+    off_t diff;
 
-    total_free = 0L;
+    total_free = (off_t)0;
     for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
        diff = hdp->disksize - holdalloc(hdp)->allocated_space;
-       if(diff > 0)
+       if(diff > (off_t)0)
            total_free += diff;
     }
     return total_free;
 }
 
-static assignedhd_t **
-find_diskspace(size, cur_idle, pref)
-    unsigned long size;
-    int *cur_idle;
-    assignedhd_t *pref;
-/* We return an array of pointers to assignedhd_t. The array contains at
+/*
+ * We return an array of pointers to assignedhd_t. The array contains at
  * most one entry per holding disk. The list of pointers is terminated by
  * a NULL pointer. Each entry contains a pointer to a holdingdisk and
  * how much diskspace to use on that disk. Later on, assign_holdingdisk
@@ -1998,18 +2264,28 @@ find_diskspace(size, cur_idle, pref)
  * If there is not enough room on the holdingdisks, NULL is returned.
  */
 
+static assignedhd_t **
+find_diskspace(
+    off_t              size,
+    int *              cur_idle,
+    assignedhd_t *     pref)
 {
     assignedhd_t **result = NULL;
     holdingdisk_t *minp, *hdp;
     int i=0, num_holdingdisks=0; /* are we allowed to use the global thing? */
     int j, minj;
     char *used;
-    long halloc, dalloc, hfree, dfree;
+    off_t halloc, dalloc, hfree, dfree;
 
-    size = am_round(size, DISK_BLOCK_KB);
+    (void)cur_idle;    /* Quiet unused parameter warning */
+
+    if (size < 2*DISK_BLOCK_KB)
+       size = 2*DISK_BLOCK_KB;
+    size = am_round(size, (off_t)DISK_BLOCK_KB);
 
 #ifdef HOLD_DEBUG
-    printf("%s: want %lu K\n", debug_prefix_time(": find_diskspace"), size);
+    printf("%s: want " OFF_T_FMT " K\n", debug_prefix_time(": find_diskspace"),
+          (OFF_T_FMT_TYPE)size);
     fflush(stdout);
 #endif
 
@@ -2017,24 +2293,24 @@ find_diskspace(size, cur_idle, pref)
        num_holdingdisks++;
     }
 
-    used = alloc(sizeof(char) * num_holdingdisks);/*disks used during this run*/
-    memset( used, 0, num_holdingdisks );
-    result = alloc( sizeof(assignedhd_t *) * (num_holdingdisks+1) );
+    used = alloc(SIZEOF(*used) * num_holdingdisks);/*disks used during this run*/
+    memset( used, 0, (size_t)num_holdingdisks );
+    result = alloc(SIZEOF(assignedhd_t *) * (num_holdingdisks + 1));
     result[0] = NULL;
 
-    while( i < num_holdingdisks && size > 0 ) {
+    while( i < num_holdingdisks && size > (off_t)0 ) {
        /* find the holdingdisk with the fewest active dumpers and among
         * those the one with the biggest free space
         */
        minp = NULL; minj = -1;
        for(j = 0, hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next, j++ ) {
            if( pref && pref->disk == hdp && !used[j] &&
-               holdalloc(hdp)->allocated_space <= hdp->disksize - DISK_BLOCK_KB) {
+               holdalloc(hdp)->allocated_space <= hdp->disksize - (off_t)DISK_BLOCK_KB) {
                minp = hdp;
                minj = j;
                break;
            }
-           else if( holdalloc(hdp)->allocated_space <= hdp->disksize - 2*DISK_BLOCK_KB &&
+           else if( holdalloc(hdp)->allocated_space <= hdp->disksize - (off_t)(2*DISK_BLOCK_KB) &&
                !used[j] &&
                (!minp ||
                 holdalloc(hdp)->allocated_dumpers < holdalloc(minp)->allocated_dumpers ||
@@ -2053,33 +2329,39 @@ find_diskspace(size, cur_idle, pref)
        hfree = minp->disksize - holdalloc(minp)->allocated_space;
 
        /* dfree = free space for data, remove 1 header for each chunksize */
-       dfree = hfree - (((hfree-1)/minp->chunksize)+1) * DISK_BLOCK_KB;
+       dfree = hfree - (((hfree-(off_t)1)/holdingdisk_get_chunksize(minp))+(off_t)1) * (off_t)DISK_BLOCK_KB;
 
        /* dalloc = space I can allocate for data */
        dalloc = ( dfree < size ) ? dfree : size;
 
        /* halloc = space to allocate, including 1 header for each chunksize */
-       halloc = dalloc + (((dalloc-1)/minp->chunksize)+1) * DISK_BLOCK_KB;
+       halloc = dalloc + (((dalloc-(off_t)1)/holdingdisk_get_chunksize(minp))+(off_t)1) * (off_t)DISK_BLOCK_KB;
 
 #ifdef HOLD_DEBUG
-       printf("%s: find diskspace: size %ld hf %ld df %ld da %ld ha %ld\n",
+       printf("%s: find diskspace: size " OFF_T_FMT " hf " OFF_T_FMT
+              " df " OFF_T_FMT " da " OFF_T_FMT " ha " OFF_T_FMT "\n",
               debug_prefix_time(": find_diskspace"),
-              size, hfree, dfree, dalloc, halloc);
+              (OFF_T_FMT_TYPE)size,
+              (OFF_T_FMT_TYPE)hfree,
+              (OFF_T_FMT_TYPE)dfree,
+              (OFF_T_FMT_TYPE)dalloc,
+              (OFF_T_FMT_TYPE)halloc);
        fflush(stdout);
 #endif
        size -= dalloc;
-       result[i] = alloc(sizeof(assignedhd_t));
+       result[i] = alloc(SIZEOF(assignedhd_t));
        result[i]->disk = minp;
        result[i]->reserved = halloc;
-       result[i]->used = 0;
+       result[i]->used = (off_t)0;
        result[i]->destname = NULL;
        result[i+1] = NULL;
        i++;
     } /* while i < num_holdingdisks && size > 0 */
     amfree(used);
 
-    if( size ) { /* not enough space available */
-       printf("find diskspace: not enough diskspace. Left with %lu K\n", size);
+    if(size != (off_t)0) { /* not enough space available */
+       printf("find diskspace: not enough diskspace. Left with "
+              OFF_T_FMT " K\n", (OFF_T_FMT_TYPE)size);
        fflush(stdout);
        free_assignedhd(result);
        result = NULL;
@@ -2087,11 +2369,12 @@ find_diskspace(size, cur_idle, pref)
 
 #ifdef HOLD_DEBUG
     for( i = 0; result && result[i]; i++ ) {
-       printf("%s: find diskspace: selected %s free %ld reserved %ld dumpers %d\n",
+       printf("%s: find diskspace: selected %s free " OFF_T_FMT " reserved " OFF_T_FMT " dumpers %d\n",
                debug_prefix_time(": find_diskspace"),
-               result[i]->disk->diskdir,
-               result[i]->disk->disksize - holdalloc(result[i]->disk)->allocated_space,
-               result[i]->reserved,
+               holdingdisk_get_diskdir(result[i]->disk),
+               (OFF_T_FMT_TYPE)(result[i]->disk->disksize -
+                 holdalloc(result[i]->disk)->allocated_space),
+               (OFF_T_FMT_TYPE)result[i]->reserved,
                holdalloc(result[i]->disk)->allocated_dumpers);
     }
     fflush(stdout);
@@ -2101,28 +2384,31 @@ find_diskspace(size, cur_idle, pref)
 }
 
 static int
-assign_holdingdisk(holdp, diskp)
-    assignedhd_t **holdp;
-    disk_t *diskp;
+assign_holdingdisk(
+    assignedhd_t **    holdp,
+    disk_t *           diskp)
 {
     int i, j, c, l=0;
-    unsigned long size;
+    off_t size;
     char *sfn = sanitise_filename(diskp->name);
     char lvl[64];
     assignedhd_t **new_holdp;
+    char *qname;
 
-    snprintf( lvl, sizeof(lvl), "%d", sched(diskp)->level );
+    snprintf( lvl, SIZEOF(lvl), "%d", sched(diskp)->level );
 
     size = am_round(sched(diskp)->est_size - sched(diskp)->act_size,
-                   DISK_BLOCK_KB);
+                   (off_t)DISK_BLOCK_KB);
 
-    for( c = 0; holdp[c]; c++ ); /* count number of disks */
+    for( c = 0; holdp[c]; c++ )
+       (void)c; /* count number of disks */
 
     /* allocate memory for sched(diskp)->holdp */
-    for(j = 0; sched(diskp)->holdp && sched(diskp)->holdp[j]; j++) {}
-    new_holdp = (assignedhd_t **)alloc(sizeof(assignedhd_t*)*(j+c+1));
+    for(j = 0; sched(diskp)->holdp && sched(diskp)->holdp[j]; j++)
+       (void)j;        /* Quiet lint */
+    new_holdp = (assignedhd_t **)alloc(SIZEOF(assignedhd_t*)*(j+c+1));
     if (sched(diskp)->holdp) {
-       memcpy(new_holdp, sched(diskp)->holdp, j * sizeof(*new_holdp));
+       memcpy(new_holdp, sched(diskp)->holdp, j * SIZEOF(*new_holdp));
        amfree(sched(diskp)->holdp);
     }
     sched(diskp)->holdp = new_holdp;
@@ -2135,17 +2421,20 @@ assign_holdingdisk(holdp, diskp)
        if( sched(diskp)->holdp[j-1]->disk == holdp[0]->disk ) { /* Yes! */
            sched(diskp)->holdp[j-1]->reserved += holdp[0]->reserved;
            holdalloc(holdp[0]->disk)->allocated_space += holdp[0]->reserved;
-           size = (holdp[0]->reserved>size) ? 0 : size-holdp[0]->reserved;
+           size = (holdp[0]->reserved>size) ? (off_t)0 : size-holdp[0]->reserved;
+           qname = quote_string(diskp->name);
 #ifdef HOLD_DEBUG
-           printf("%s: merging holding disk %s to disk %s:%s, add %lu for reserved %lu, left %lu\n",
+           printf("%s: merging holding disk %s to disk %s:%s, add " OFF_T_FMT " for reserved " OFF_T_FMT ", left " OFF_T_FMT "\n",
                   debug_prefix_time(": assign_holdingdisk"),
-                  sched(diskp)->holdp[j-1]->disk->diskdir,
-                  diskp->host->hostname, diskp->name,
-                  holdp[0]->reserved, sched(diskp)->holdp[j-1]->reserved,
-                  size );
+                  holdingdisk_get_diskdir(sched(diskp)->holdp[j-1]->disk),
+                  diskp->host->hostname, qname,
+                  (OFF_T_FMT_TYPE)holdp[0]->reserved,
+                  (OFF_T_FMT_TYPE)sched(diskp)->holdp[j-1]->reserved,
+                  (OFF_T_FMT_TYPE)size);
            fflush(stdout);
 #endif
            i++;
+           amfree(qname);
            amfree(holdp[0]);
            l=j-1;
        }
@@ -2154,21 +2443,25 @@ assign_holdingdisk(holdp, diskp)
     /* copy assignedhd_s to sched(diskp), adjust allocated_space */
     for( ; holdp[i]; i++ ) {
        holdp[i]->destname = newvstralloc( holdp[i]->destname,
-                                          holdp[i]->disk->diskdir, "/",
-                                          timestamp, "/",
+                                          holdingdisk_get_diskdir(holdp[i]->disk), "/",
+                                          hd_driver_timestamp, "/",
                                           diskp->host->hostname, ".",
                                           sfn, ".",
                                           lvl, NULL );
        sched(diskp)->holdp[j++] = holdp[i];
        holdalloc(holdp[i]->disk)->allocated_space += holdp[i]->reserved;
-       size = (holdp[i]->reserved>size) ? 0 : size-holdp[i]->reserved;
+       size = (holdp[i]->reserved > size) ? (off_t)0 :
+                 (size - holdp[i]->reserved);
+       qname = quote_string(diskp->name);
 #ifdef HOLD_DEBUG
-       printf("%s: %d assigning holding disk %s to disk %s:%s, reserved %lu, left %lu\n",
+       printf("%s: %d assigning holding disk %s to disk %s:%s, reserved " OFF_T_FMT ", left " OFF_T_FMT "\n",
                debug_prefix_time(": assign_holdingdisk"),
-               i, holdp[i]->disk->diskdir, diskp->host->hostname, diskp->name,
-               holdp[i]->reserved, size );
+               i, holdingdisk_get_diskdir(holdp[i]->disk), diskp->host->hostname, qname,
+               (OFF_T_FMT_TYPE)holdp[i]->reserved,
+               (OFF_T_FMT_TYPE)size);
        fflush(stdout);
 #endif
+       amfree(qname);
        holdp[i] = NULL; /* so it doesn't get free()d... */
     }
     sched(diskp)->holdp[j] = NULL;
@@ -2178,63 +2471,74 @@ assign_holdingdisk(holdp, diskp)
 }
 
 static void
-adjust_diskspace(diskp, cmd)
-    disk_t *diskp;
-    cmd_t cmd;
+adjust_diskspace(
+    disk_t *   diskp,
+    cmd_t      cmd)
 {
     assignedhd_t **holdp;
-    unsigned long total=0;
-    long diff;
+    off_t total = (off_t)0;
+    off_t diff;
     int i;
+    char *qname, *hqname, *qdest;
+
+    (void)cmd; /* Quiet unused parameter warning */
 
+    qname = quote_string(diskp->name);
+    qdest = quote_string(sched(diskp)->destname);
 #ifdef HOLD_DEBUG
     printf("%s: %s:%s %s\n",
           debug_prefix_time(": adjust_diskspace"),
-          diskp->host->hostname, diskp->name, sched(diskp)->destname);
+          diskp->host->hostname, qname, qdest);
     fflush(stdout);
 #endif
 
     holdp = sched(diskp)->holdp;
 
-    assert(holdp);
+    assert(holdp != NULL);
 
     for( i = 0; holdp[i]; i++ ) { /* for each allocated disk */
        diff = holdp[i]->used - holdp[i]->reserved;
        total += holdp[i]->used;
        holdalloc(holdp[i]->disk)->allocated_space += diff;
-
+       hqname = quote_string(holdp[i]->disk->name);
 #ifdef HOLD_DEBUG
-       printf("%s: hdisk %s done, reserved %ld used %ld diff %ld alloc %ld dumpers %d\n",
+       printf("%s: hdisk %s done, reserved " OFF_T_FMT " used " OFF_T_FMT " diff " OFF_T_FMT " alloc " OFF_T_FMT " dumpers %d\n",
                debug_prefix_time(": adjust_diskspace"),
-               holdp[i]->disk->name, holdp[i]->reserved, holdp[i]->used, diff,
-               holdalloc(holdp[i]->disk)->allocated_space,
+               holdp[i]->disk->name,
+               (OFF_T_FMT_TYPE)holdp[i]->reserved,
+               (OFF_T_FMT_TYPE)holdp[i]->used,
+               (OFF_T_FMT_TYPE)diff,
+               (OFF_T_FMT_TYPE)holdalloc(holdp[i]->disk)->allocated_space,
                holdalloc(holdp[i]->disk)->allocated_dumpers );
        fflush(stdout);
 #endif
        holdp[i]->reserved += diff;
+       amfree(hqname);
     }
 
     sched(diskp)->act_size = total;
 
 #ifdef HOLD_DEBUG
-    printf("%s: after: disk %s:%s used %ld\n",
+    printf("%s: after: disk %s:%s used " OFF_T_FMT "\n",
           debug_prefix_time(": adjust_diskspace"),
-          diskp->host->hostname, diskp->name, sched(diskp)->act_size );
+          diskp->host->hostname, qname,
+          (OFF_T_FMT_TYPE)sched(diskp)->act_size);
     fflush(stdout);
 #endif
-
+    amfree(qdest);
+    amfree(qname);
 }
 
 static void
-delete_diskspace(diskp)
-    disk_t *diskp;
+delete_diskspace(
+    disk_t *diskp)
 {
     assignedhd_t **holdp;
     int i;
 
     holdp = sched(diskp)->holdp;
 
-    assert(holdp);
+    assert(holdp != NULL);
 
     for( i = 0; holdp[i]; i++ ) { /* for each disk */
        /* find all files of this dump on that disk, and subtract their
@@ -2249,32 +2553,34 @@ delete_diskspace(diskp)
                                                 * using cont_filename */
     free_assignedhd(sched(diskp)->holdp);
     sched(diskp)->holdp = NULL;
-    sched(diskp)->act_size = 0;
+    sched(diskp)->act_size = (off_t)0;
 }
 
-static assignedhd_t **build_diskspace(destname)
-char *destname;
+static assignedhd_t **
+build_diskspace(
+    char *     destname)
 {
     int i, j;
     int fd;
-    int buflen;
+    ssize_t buflen;
     char buffer[DISK_BLOCK_BYTES];
     dumpfile_t file;
     assignedhd_t **result;
     holdingdisk_t *hdp;
-    int *used;
+    off_t *used;
     int num_holdingdisks=0;
     char dirname[1000], *ch;
     struct stat finfo;
     char *filename = destname;
 
+    memset(buffer, 0, sizeof(buffer));
     for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
         num_holdingdisks++;
     }
-    used = alloc(sizeof(int) * num_holdingdisks);
+    used = alloc(SIZEOF(off_t) * num_holdingdisks);
     for(i=0;i<num_holdingdisks;i++)
-       used[i] = 0;
-    result = alloc( sizeof(assignedhd_t *) * (num_holdingdisks+1) );
+       used[i] = (off_t)0;
+    result = alloc(SIZEOF(assignedhd_t *) * (num_holdingdisks + 1));
     result[0] = NULL;
     while(filename != NULL && filename[0] != '\0') {
        strncpy(dirname, filename, 999);
@@ -2286,23 +2592,23 @@ char *destname;
 
        for(j = 0, hdp = getconf_holdingdisks(); hdp != NULL;
                                                 hdp = hdp->next, j++ ) {
-           if(strcmp(dirname,hdp->diskdir)==0) {
+           if(strcmp(dirname, holdingdisk_get_diskdir(hdp))==0) {
                break;
            }
        }
 
        if(stat(filename, &finfo) == -1) {
            fprintf(stderr, "stat %s: %s\n", filename, strerror(errno));
-           finfo.st_size = 0;
+           finfo.st_size = (off_t)0;
        }
-       used[j] += (finfo.st_size+1023)/1024;
+       used[j] += ((off_t)finfo.st_size+(off_t)1023)/(off_t)1024;
        if((fd = open(filename,O_RDONLY)) == -1) {
            fprintf(stderr,"build_diskspace: open of %s failed: %s\n",
                    filename, strerror(errno));
            return NULL;
        }
-       if ((buflen = fullread(fd, buffer, sizeof(buffer))) > 0) {;
-               parse_file_header(buffer, &file, buflen);
+       if ((buflen = fullread(fd, buffer, SIZEOF(buffer))) > 0) {;
+               parse_file_header(buffer, &file, (size_t)buflen);
        }
        close(fd);
        filename = file.cont_filename;
@@ -2310,8 +2616,8 @@ char *destname;
 
     for(j = 0, i=0, hdp = getconf_holdingdisks(); hdp != NULL;
                                                  hdp = hdp->next, j++ ) {
-       if(used[j]) {
-           result[i] = alloc(sizeof(assignedhd_t));
+       if(used[j] != (off_t)0) {
+           result[i] = alloc(SIZEOF(assignedhd_t));
            result[i]->disk = hdp;
            result[i]->reserved = used[j];
            result[i]->used = used[j];
@@ -2326,26 +2632,26 @@ char *destname;
 }
 
 static void
-holdingdisk_state(time_str)
-    char *time_str;
+holdingdisk_state(
+    char *     time_str)
 {
     holdingdisk_t *hdp;
     int dsk;
-    long diff;
+    off_t diff;
 
     printf("driver: hdisk-state time %s", time_str);
 
     for(hdp = getconf_holdingdisks(), dsk = 0; hdp != NULL; hdp = hdp->next, dsk++) {
        diff = hdp->disksize - holdalloc(hdp)->allocated_space;
-       printf(" hdisk %d: free %ld dumpers %d", dsk, diff,
-              holdalloc(hdp)->allocated_dumpers);
+       printf(" hdisk %d: free " OFF_T_FMT " dumpers %d", dsk,
+              (OFF_T_FMT_TYPE)diff, holdalloc(hdp)->allocated_dumpers);
     }
     printf("\n");
 }
 
 static void
-update_failed_dump_to_tape(dp)
-    disk_t *dp;
+update_failed_dump_to_tape(
+    disk_t *   dp)
 {
 /* JLM
  * should simply set no_bump
@@ -2358,29 +2664,31 @@ update_failed_dump_to_tape(dp)
      * gnutar-lists might have been updated already, and a bumped
      * incremental might be created.  */
     sched(dp)->timestamp = 0;
-    update_info_dumper(dp, -1, -1, -1);
+    update_info_dumper(dp, (off_t)-1, (off_t)-1, (time_t)-1);
     sched(dp)->timestamp = save_timestamp;
 }
 
 /* ------------------- */
 static int
-dump_to_tape(dp)
-    disk_t *dp;
+dump_to_tape(
+    disk_t *   dp)
 {
     dumper_t *dumper;
     int failed = 0;
-    int filenum;
-    long origsize = 0;
-    long dumpsize = 0;
-    long dumptime = 0;
-    float tapetime = 0;
+    off_t filenum;
+    off_t origsize = (off_t)0;
+    off_t dumpsize = (off_t)0;
+    time_t dumptime = (time_t)0;
+    double tapetime = 0.0;
     cmd_t cmd;
-    int result_argc;
+    int result_argc, rc;
     char *result_argv[MAX_ARGS+1];
     int dumper_tryagain = 0;
+    char *qname;
 
+    qname = quote_string(dp->name);
     printf("driver: dumping %s:%s directly to tape\n",
-          dp->host->hostname, dp->name);
+          dp->host->hostname, qname);
     fflush(stdout);
 
     /* pick a dumper and fail if there are no idle dumpers */
@@ -2388,10 +2696,11 @@ dump_to_tape(dp)
     dumper = idle_dumper();
     if (!dumper) {
        printf("driver: no idle dumpers for %s:%s.\n", 
-               dp->host->hostname, dp->name);
+               dp->host->hostname, qname);
        fflush(stdout);
        log_add(L_WARNING, "no idle dumpers for %s:%s.\n",
-               dp->host->hostname, dp->name);
+               dp->host->hostname, qname);
+        amfree(qname);
        return 2;       /* fatal problem */
     }
 
@@ -2401,8 +2710,9 @@ dump_to_tape(dp)
     cmd = getresult(taper, 1, &result_argc, result_argv, MAX_ARGS+1);
     if(cmd != PORT) {
        printf("driver: did not get PORT from taper for %s:%s\n",
-               dp->host->hostname, dp->name);
+               dp->host->hostname, qname);
        fflush(stdout);
+        amfree(qname);
        return 2;       /* fatal problem */
     }
     /* copy port number */
@@ -2428,9 +2738,6 @@ dump_to_tape(dp)
 
     cmd = getresult(dumper->fd, 1, &result_argc, result_argv, MAX_ARGS+1);
 
-    if(cmd != BOGUS)
-       free_serial(result_argv[2]);
-
     switch(cmd) {
     case BOGUS:
        /* either eof or garbage from dumper */
@@ -2442,16 +2749,14 @@ dump_to_tape(dp)
 
     case DONE: /* DONE <handle> <origsize> <dumpsize> <dumptime> <errstr> */
        /* everything went fine */
-       origsize = (long)atof(result_argv[3]);
-       /*dumpsize = (long)atof(result_argv[4]);*/
-       dumptime = (long)atof(result_argv[5]);
+       origsize = (off_t)atof(result_argv[3]);
+       /*dumpsize = (off_t)atof(result_argv[4]);*/
+       dumptime = (time_t)atof(result_argv[5]);
        break;
 
     case NO_ROOM: /* NO-ROOM <handle> */
        dumper_cmd(dumper, ABORT, dp);
        cmd = getresult(dumper->fd, 1, &result_argc, result_argv, MAX_ARGS+1);
-       if(cmd != BOGUS)
-           free_serial(result_argv[2]);
        assert(cmd == ABORT_FINISHED);
 
     case TRYAGAIN: /* TRY-AGAIN <handle> <errstr> */
@@ -2486,6 +2791,7 @@ dump_to_tape(dp)
     case DONE: /* DONE <handle> <label> <tape file> <err mess> */
        if(result_argc != 5) {
            error("error [dump to tape DONE result_argc != 5: %d]", result_argc);
+           /*NOTREACHED*/
        }
 
        if(failed == 1) goto tryagain;  /* dump didn't work */
@@ -2493,12 +2799,25 @@ dump_to_tape(dp)
 
        free_serial(result_argv[2]);
 
-       sscanf(result_argv[5],"[sec %f kb %ld ", &tapetime, &dumpsize);
+       if (*result_argv[5] == '"') {
+           /* String was quoted */
+           rc = sscanf(result_argv[5],"\"[sec %lf kb " OFF_T_FMT " ",
+                       &tapetime, (OFF_T_FMT_TYPE *)&dumpsize);
+       } else {
+           /* String was not quoted */
+           rc = sscanf(result_argv[5],"[sec %lf kb " OFF_T_FMT " ",
+                       &tapetime, (OFF_T_FMT_TYPE *)&dumpsize);
+       }
+       if (rc < 2) {
+           error("error [malformed result: %d items matched in '%s']",
+                 rc, result_argv[5]);
+           /*NOTREACHED*/
+       }
 
        if(cmd == DONE) {
            /* every thing went fine */
            update_info_dumper(dp, origsize, dumpsize, dumptime);
-           filenum = atoi(result_argv[4]);
+           filenum = OFF_T_ATOI(result_argv[4]);
            update_info_taper(dp, result_argv[3], filenum, sched(dp)->level);
            /* note that update_info_dumper() must be run before
               update_info_taper(), since update_info_dumper overwrites
@@ -2526,16 +2845,17 @@ dump_to_tape(dp)
     case SPLIT_CONTINUE:  /* SPLIT_CONTINUE <handle> <new_label> */
         if (result_argc != 3) {
             error("error [taper SPLIT_CONTINUE result_argc != 3: %d]", result_argc);
+           /*NOTREACHED*/
         }
-        fprintf(stderr, "driver: Got SPLIT_CONTINUE %s %s\n", result_argv[2], result_argv[3]);
+        fprintf(stderr, "driver: Got SPLIT_CONTINUE %s %s\n",
+               result_argv[2], result_argv[3]);
         goto continue_port_dump;
-        break;
+
     case SPLIT_NEEDNEXT:
         fprintf(stderr, "driver: Got SPLIT_NEEDNEXT %s %s\n", result_argv[2], result_argv[3]);
 
         goto continue_port_dump;
-        break;
+
     case TAPE_ERROR: /* TAPE-ERROR <handle> <err mess> */
     case BOGUS:
     default:
@@ -2543,6 +2863,7 @@ dump_to_tape(dp)
        free_serial(result_argv[2]);
        failed = 2;     /* fatal problem */
        start_degraded_mode(&runq);
+       break;
     }
 
     /* reset statistics & return */
@@ -2551,23 +2872,25 @@ dump_to_tape(dp)
     dp->host->inprogress -= 1;
     dp->inprogress = 0;
     deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+    amfree(qname);
 
     return failed;
 }
 
 static int
-queue_length(q)
-    disklist_t q;
+queue_length(
+    disklist_t q)
 {
     disk_t *p;
     int len;
 
-    for(len = 0, p = q.head; p != NULL; len++, p = p->next);
+    for(len = 0, p = q.head; p != NULL; len++, p = p->next)
+       (void)len;      /* Quiet lint */
     return len;
 }
 
 static void
-short_dump_state()
+short_dump_state(void)
 {
     int i, nidle;
     char *wall_time;
@@ -2575,8 +2898,9 @@ short_dump_state()
     wall_time = walltime_str(curclock());
 
     printf("driver: state time %s ", wall_time);
-    printf("free kps: %d space: %lu taper: ",
-          free_kps((interface_t *)0), free_space());
+    printf("free kps: %lu space: " OFF_T_FMT " taper: ",
+          free_kps((interface_t *)0),
+          (OFF_T_FMT_TYPE)free_space());
     if(degraded_mode) printf("DOWN");
     else if(!taper_busy) printf("idle");
     else printf("writing");
@@ -2595,18 +2919,21 @@ short_dump_state()
 
 #if 0
 static void
-dump_state(str)
-    const char *str;
+dump_state(
+    const char *str)
 {
     int i;
     disk_t *dp;
+    char *qname;
 
     printf("================\n");
     printf("driver state at time %s: %s\n", walltime_str(curclock()), str);
-    printf("free kps: %d, space: %lu\n", free_kps((interface_t *)0), free_space());
+    printf("free kps: %lu, space: " OFF_T_FMT "\n",
+          free_kps((interface_t *)0),
+          (OFF_T_FMT_TYPE)free_space());
     if(degraded_mode) printf("taper: DOWN\n");
     else if(!taper_busy) printf("taper: idle\n");
-    else printf("taper: writing %s:%s.%d est size %lu\n",
+    else printf("taper: writing %s:%s.%d est size " OFF_T_FMT "\n",
                taper_disk->host->hostname, taper_disk->name,
                sched(taper_disk)->level,
                sched(taper_disk)->est_size);
@@ -2615,9 +2942,11 @@ dump_state(str)
        if(!dmptable[i].busy)
          printf("%s: idle\n", dmptable[i].name);
        else
-         printf("%s: dumping %s:%s.%d est kps %d size %lu time %ld\n",
-               dmptable[i].name, dp->host->hostname, dp->name, sched(dp)->level,
+         qname = quote_string(dp->name);
+         printf("%s: dumping %s:%s.%d est kps %d size " OFF_T_FMT " time %lu\n",
+               dmptable[i].name, dp->host->hostname, qname, sched(dp)->level,
                sched(dp)->est_kps, sched(dp)->est_size, sched(dp)->est_time);
+          amfree(qname);
     }
     dump_queue("TAPE", tapeq, 5, stdout);
     dump_queue("ROOM", roomq, 5, stdout);
index 252349327ad9241eea44f09383aadc70c1aaf5c8..acf850edbe840030afbdffe16d07a53b822f3e58 100644 (file)
  *                        University of Maryland at College Park
  */
 /*
- * $Id: driverio.c,v 1.81.2.1 2006/04/23 18:52:04 martinea Exp $
+ * $Id: driverio.c,v 1.92 2006/08/24 01:57:16 paddy_s Exp $
  *
  * I/O-related functions for driver program
  */
 #include "amanda.h"
 #include "util.h"
 #include "clock.h"
+#include "server_util.h"
 #include "conffile.h"
 #include "diskfile.h"
 #include "infofile.h"
 #include "logfile.h"
 #include "token.h"
-#include "server_util.h"
 
 #define GLOBAL         /* the global variables defined here */
 #include "driverio.h"
 
 int nb_chunker = 0;
 
-static const char *childstr P((int));
+static const char *childstr(int);
 
-void init_driverio()
+void
+init_driverio(void)
 {
     dumper_t *dumper;
 
@@ -59,8 +60,8 @@ void init_driverio()
 
 
 static const char *
-childstr(fd)
-    int fd;
+childstr(
+    int fd)
 {
     static char buf[NUM_STR_SIZE + 32];
     dumper_t *dumper;
@@ -74,36 +75,45 @@ childstr(fd)
        if (dumper->chunker->fd == fd)
            return (dumper->chunker->name);
     }
-    snprintf(buf, sizeof(buf), "unknown child (fd %d)", fd);
+    snprintf(buf, SIZEOF(buf), "unknown child (fd %d)", fd);
     return (buf);
 }
 
 
-void startup_tape_process(taper_program)
-char *taper_program;
+void
+startup_tape_process(
+    char *taper_program)
 {
     int fd[2];
 
-    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1)
+    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
        error("taper pipe: %s", strerror(errno));
-    if(fd[0] < 0 || fd[0] >= FD_SETSIZE) {
+       /*NOTREACHED*/
+    }
+    if(fd[0] < 0 || fd[0] >= (int)FD_SETSIZE) {
        error("taper socketpair 0: descriptor %d out of range (0 .. %d)\n",
              fd[0], FD_SETSIZE-1);
+        /*NOTREACHED*/
     }
-    if(fd[1] < 0 || fd[1] >= FD_SETSIZE) {
+    if(fd[1] < 0 || fd[1] >= (int)FD_SETSIZE) {
        error("taper socketpair 1: descriptor %d out of range (0 .. %d)\n",
              fd[1], FD_SETSIZE-1);
+        /*NOTREACHED*/
     }
 
     switch(taper_pid = fork()) {
     case -1:
        error("fork taper: %s", strerror(errno));
+       /*NOTREACHED*/
+
     case 0:    /* child process */
        aclose(fd[0]);
        if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1)
            error("taper dup2: %s", strerror(errno));
        execle(taper_program, "taper", config_name, (char *)0, safe_env());
        error("exec %s: %s", taper_program, strerror(errno));
+       /*NOTREACHED*/
+
     default:   /* parent process */
        aclose(fd[1]);
        taper = fd[0];
@@ -111,18 +121,23 @@ char *taper_program;
     }
 }
 
-void startup_dump_process(dumper, dumper_program)
-dumper_t *dumper;
-char *dumper_program;
+void
+startup_dump_process(
+    dumper_t *dumper,
+    char *dumper_program)
 {
     int fd[2];
 
-    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1)
+    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
        error("%s pipe: %s", dumper->name, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     switch(dumper->pid = fork()) {
     case -1:
        error("fork %s: %s", dumper->name, strerror(errno));
+       /*NOTREACHED*/
+
     case 0:            /* child process */
        aclose(fd[0]);
        if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1)
@@ -134,28 +149,32 @@ char *dumper_program;
               safe_env());
        error("exec %s (%s): %s", dumper_program,
              dumper->name, strerror(errno));
+        /*NOTREACHED*/
+
     default:   /* parent process */
        aclose(fd[1]);
        dumper->fd = fd[0];
        dumper->ev_read = NULL;
        dumper->busy = dumper->down = 0;
        dumper->dp = NULL;
-       fprintf(stderr,"driver: started %s pid %d\n",
-               dumper->name, dumper->pid);
+       fprintf(stderr,"driver: started %s pid %u\n",
+               dumper->name, (unsigned)dumper->pid);
        fflush(stderr);
     }
 }
 
-void startup_dump_processes(dumper_program, inparallel)
-char *dumper_program;
-int inparallel;
+void
+startup_dump_processes(
+    char *dumper_program,
+    int inparallel,
+    char *timestamp)
 {
     int i;
     dumper_t *dumper;
     char number[NUM_STR_SIZE];
 
     for(dumper = dmptable, i = 0; i < inparallel; dumper++, i++) {
-       snprintf(number, sizeof(number), "%d", i);
+       snprintf(number, SIZEOF(number), "%d", i);
        dumper->name = stralloc2("dumper", number);
        dumper->chunker = &chktable[i];
        chktable[i].name = stralloc2("chunker", number);
@@ -163,25 +182,33 @@ int inparallel;
        chktable[i].fd = -1;
 
        startup_dump_process(dumper, dumper_program);
+       dumper_cmd(dumper, START, (void *)timestamp);
     }
 }
 
-void startup_chunk_process(chunker, chunker_program)
-chunker_t *chunker;
-char *chunker_program;
+void
+startup_chunk_process(
+    chunker_t *chunker,
+    char *chunker_program)
 {
     int fd[2];
 
-    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1)
+    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
        error("%s pipe: %s", chunker->name, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     switch(chunker->pid = fork()) {
     case -1:
        error("fork %s: %s", chunker->name, strerror(errno));
+       /*NOTREACHED*/
+
     case 0:            /* child process */
        aclose(fd[0]);
-       if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1)
+       if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1) {
            error("%s dup2: %s", chunker->name, strerror(errno));
+           /*NOTREACHED*/
+       }
        execle(chunker_program,
               chunker->name ? chunker->name : "chunker",
               config_name,
@@ -189,23 +216,26 @@ char *chunker_program;
               safe_env());
        error("exec %s (%s): %s", chunker_program,
              chunker->name, strerror(errno));
+        /*NOTREACHED*/
+
     default:   /* parent process */
        aclose(fd[1]);
        chunker->down = 0;
        chunker->fd = fd[0];
        chunker->ev_read = NULL;
-       fprintf(stderr,"driver: started %s pid %d\n",
-               chunker->name, chunker->pid);
+       fprintf(stderr,"driver: started %s pid %u\n",
+               chunker->name, (unsigned)chunker->pid);
        fflush(stderr);
     }
 }
 
-cmd_t getresult(fd, show, result_argc, result_argv, max_arg)
-int fd;
-int show;
-int *result_argc;
-char **result_argv;
-int max_arg;
+cmd_t
+getresult(
+    int fd,
+    int show,
+    int *result_argc,
+    char **result_argv,
+    int max_arg)
 {
     int arg;
     cmd_t t;
@@ -214,6 +244,7 @@ int max_arg;
     if((line = areads(fd)) == NULL) {
        if(errno) {
            error("reading result from %s: %s", childstr(fd), strerror(errno));
+           /*NOTREACHED*/
        }
        *result_argc = 0;                               /* EOF */
     } else {
@@ -251,12 +282,13 @@ int max_arg;
 }
 
 
-int taper_cmd(cmd, /* optional */ ptr, destname, level, datestamp)
-cmd_t cmd;
-void *ptr;
-char *destname;
-int level;
-char *datestamp;
+int
+taper_cmd(
+    cmd_t cmd,
+    void *ptr,
+    char *destname,
+    int level,
+    char *datestamp)
 {
     char *cmdline = NULL;
     char number[NUM_STR_SIZE];
@@ -265,6 +297,8 @@ char *datestamp;
     char *diskbuffer = NULL;
     disk_t *dp;
     char *features;
+    char *qname;
+    char *qdest;
 
     switch(cmd) {
     case START_TAPER:
@@ -272,24 +306,30 @@ char *datestamp;
        break;
     case FILE_WRITE:
        dp = (disk_t *) ptr;
-       snprintf(number, sizeof(number), "%d", level);
-       snprintf(splitsize, sizeof(splitsize), "%ld", dp->tape_splitsize);
+        qname = quote_string(dp->name);
+       qdest = quote_string(destname);
+       snprintf(number, SIZEOF(number), "%d", level);
+       snprintf(splitsize, SIZEOF(splitsize), OFF_T_FMT,
+                (OFF_T_FMT_TYPE)dp->tape_splitsize);
        features = am_feature_to_string(dp->host->features);
        cmdline = vstralloc(cmdstr[cmd],
                            " ", disk2serial(dp),
-                           " ", destname,
+                           " ", qdest,
                            " ", dp->host->hostname,
                            " ", features,
-                           " ", dp->name,
+                           " ", qname,
                            " ", number,
                            " ", datestamp,
                            " ", splitsize,
                            "\n", NULL);
        amfree(features);
+       amfree(qdest);
+       amfree(qname);
        break;
     case PORT_WRITE:
        dp = (disk_t *) ptr;
-       snprintf(number, sizeof(number), "%d", level);
+        qname = quote_string(dp->name);
+       snprintf(number, SIZEOF(number), "%d", level);
 
        /*
           If we haven't been given a place to buffer split dumps to disk,
@@ -301,15 +341,16 @@ char *datestamp;
        } else {
            diskbuffer = dp->split_diskbuffer;
        }
-       snprintf(splitsize, sizeof(splitsize), "%ld", dp->tape_splitsize);
-       snprintf(fallback_splitsize, sizeof(fallback_splitsize),
-                   "%ld", dp->fallback_splitsize);
+       snprintf(splitsize, SIZEOF(splitsize), OFF_T_FMT,
+                (OFF_T_FMT_TYPE)dp->tape_splitsize);
+       snprintf(fallback_splitsize, SIZEOF(fallback_splitsize), OFF_T_FMT,
+                (OFF_T_FMT_TYPE)dp->fallback_splitsize);
        features = am_feature_to_string(dp->host->features);
        cmdline = vstralloc(cmdstr[cmd],
                            " ", disk2serial(dp),
                            " ", dp->host->hostname,
                            " ", features,
-                           " ", dp->name,
+                           " ", qname,
                            " ", number,
                            " ", datestamp,
                            " ", splitsize,
@@ -317,76 +358,91 @@ char *datestamp;
                            " ", fallback_splitsize,
                            "\n", NULL);
        amfree(features);
+       amfree(qname);
        break;
     case QUIT:
        cmdline = stralloc2(cmdstr[cmd], "\n");
        break;
     default:
        error("Don't know how to send %s command to taper", cmdstr[cmd]);
+       /*NOTREACHED*/
     }
+
     /*
      * Note: cmdline already has a '\n'.
      */
     printf("driver: send-cmd time %s to taper: %s",
           walltime_str(curclock()), cmdline);
     fflush(stdout);
-    if (fullwrite(taper, cmdline, strlen(cmdline)) < 0) {
-       printf("writing taper command: %s\n", strerror(errno));
+    if ((fullwrite(taper, cmdline, strlen(cmdline))) < 0) {
+       printf("writing taper command '%s' failed: %s\n",
+               cmdline, strerror(errno));
        fflush(stdout);
        amfree(cmdline);
        return 0;
     }
+    if(cmd == QUIT) aclose(taper);
     amfree(cmdline);
     return 1;
 }
 
-int dumper_cmd(dumper, cmd, /* optional */ dp)
-dumper_t *dumper;
-cmd_t cmd;
-disk_t *dp;
+int
+dumper_cmd(
+    dumper_t *dumper,
+    cmd_t cmd,
+    disk_t *dp)
 {
     char *cmdline = NULL;
     char number[NUM_STR_SIZE];
     char numberport[NUM_STR_SIZE];
     char *o;
-    int activehd=0;
-    assignedhd_t **h=NULL;
     char *device;
     char *features;
-
-    if(dp && sched(dp) && sched(dp)->holdp) {
-       h = sched(dp)->holdp;
-       activehd = sched(dp)->activehd;
-    }
-
-    if(dp && dp->device) {
-       device = dp->device;
-    }
-    else {
-       device = "NODEVICE";
-    }
+    char *qname;
+    char *qdest;
 
     switch(cmd) {
+    case START:
+       cmdline = vstralloc(cmdstr[cmd], " ", (char *)dp, "\n", NULL);
+       break;
     case PORT_DUMP:
+       if(dp && dp->device) {
+           device = dp->device;
+       }
+       else {
+           device = "NODEVICE";
+       }
+
        if (dp != NULL) {
-           snprintf(number, sizeof(number), "%d", sched(dp)->level);
-           snprintf(numberport, sizeof(numberport), "%d", dumper->output_port);
+           device = quote_string((dp->device) ? dp->device : "NODEVICE");
+           qname = quote_string(dp->name);
+           snprintf(number, SIZEOF(number), "%d", sched(dp)->level);
+           snprintf(numberport, SIZEOF(numberport), "%d", dumper->output_port);
            features = am_feature_to_string(dp->host->features);
            o = optionstr(dp, dp->host->features, NULL);
+           if ( o == NULL ) {
+             error("problem with option string, check the dumptype definition.\n");
+           }
+             
            cmdline = vstralloc(cmdstr[cmd],
                            " ", disk2serial(dp),
                            " ", numberport,
                            " ", dp->host->hostname,
                            " ", features,
-                           " ", dp->name,
+                           " ", qname,
                            " ", device,
                            " ", number,
                            " ", sched(dp)->dumpdate,
                            " ", dp->program,
+                           " ", dp->amandad_path,
+                           " ", dp->client_username,
+                           " ", dp->ssh_keys,
                            " |", o,
                            "\n", NULL);
            amfree(features);
            amfree(o);
+           amfree(qname);
+           amfree(device);
        } else {
                error("PORT-DUMP without disk pointer\n");
                /*NOTREACHED*/
@@ -395,16 +451,20 @@ disk_t *dp;
     case QUIT:
     case ABORT:
        if( dp ) {
+           qdest = quote_string(sched(dp)->destname);
            cmdline = vstralloc(cmdstr[cmd],
-                               " ", sched(dp)->destname,
+                               " ", qdest,
                                "\n", NULL );
+           amfree(qdest);
        } else {
            cmdline = stralloc2(cmdstr[cmd], "\n");
        }
        break;
     default:
        error("Don't know how to send %s command to dumper", cmdstr[cmd]);
+       /*NOTREACHED*/
     }
+
     /*
      * Note: cmdline already has a '\n'.
      */
@@ -421,15 +481,17 @@ disk_t *dp;
            amfree(cmdline);
            return 0;
        }
+       if (cmd == QUIT) aclose(dumper->fd);
     }
     amfree(cmdline);
     return 1;
 }
 
-int chunker_cmd(chunker, cmd, dp)
-chunker_t *chunker;
-cmd_t cmd;
-disk_t *dp;
+int
+chunker_cmd(
+    chunker_t *chunker,
+    cmd_t cmd,
+    disk_t *dp)
 {
     char *cmdline = NULL;
     char number[NUM_STR_SIZE];
@@ -439,30 +501,39 @@ disk_t *dp;
     int activehd=0;
     assignedhd_t **h=NULL;
     char *features;
-
-    if(cmd != START && dp && sched(dp) && sched(dp)->holdp) {
-       h = sched(dp)->holdp;
-       activehd = sched(dp)->activehd;
-    }
+    char *qname;
+    char *qdest;
 
     switch(cmd) {
     case START:
        cmdline = vstralloc(cmdstr[cmd], " ", (char *)dp, "\n", NULL);
        break;
     case PORT_WRITE:
+       if(dp && sched(dp) && sched(dp)->holdp) {
+           h = sched(dp)->holdp;
+           activehd = sched(dp)->activehd;
+       }
+
        if (dp && h) {
+           qname = quote_string(dp->name);
+           qdest = quote_string(sched(dp)->destname);
            holdalloc(h[activehd]->disk)->allocated_dumpers++;
-           snprintf(number, sizeof(number), "%d", sched(dp)->level);
-           snprintf(chunksize, sizeof(chunksize), "%ld", h[0]->disk->chunksize);
-           snprintf(use, sizeof(use), "%ld", h[0]->reserved );
+           snprintf(number, SIZEOF(number), "%d", sched(dp)->level);
+           snprintf(chunksize, SIZEOF(chunksize), OFF_T_FMT,
+                   (OFF_T_FMT_TYPE)holdingdisk_get_chunksize(h[0]->disk));
+           snprintf(use, SIZEOF(use), OFF_T_FMT,
+                   (OFF_T_FMT_TYPE)h[0]->reserved);
            features = am_feature_to_string(dp->host->features);
            o = optionstr(dp, dp->host->features, NULL);
+           if ( o == NULL ) {
+             error("problem with option string, check the dumptype definition.\n");
+           }
            cmdline = vstralloc(cmdstr[cmd],
                            " ", disk2serial(dp),
-                           " ", sched(dp)->destname,
+                           " ", qdest,
                            " ", dp->host->hostname,
                            " ", features,
-                           " ", dp->name,
+                           " ", qname,
                            " ", number,
                            " ", sched(dp)->dumpdate,
                            " ", chunksize,
@@ -472,6 +543,8 @@ disk_t *dp;
                            "\n", NULL);
            amfree(features);
            amfree(o);
+           amfree(qdest);
+           amfree(qname);
        } else {
                error("Write command without disk and holding disk.\n",
                      cmdstr[cmd]);
@@ -479,28 +552,38 @@ disk_t *dp;
        }
        break;
     case CONTINUE:
-       if( dp && h) {
+       if(dp && sched(dp) && sched(dp)->holdp) {
+           h = sched(dp)->holdp;
+           activehd = sched(dp)->activehd;
+       }
+
+       if(dp && h) {
+           qname = quote_string(dp->name);
+           qdest = quote_string(h[activehd]->destname);
            holdalloc(h[activehd]->disk)->allocated_dumpers++;
-           snprintf(chunksize, sizeof(chunksize), "%ld"
-                    h[activehd]->disk->chunksize );
-           snprintf(use, sizeof(use), "%ld"
-                    h[activehd]->reserved - h[activehd]->used );
+           snprintf(chunksize, SIZEOF(chunksize), OFF_T_FMT
+                    (OFF_T_FMT_TYPE)holdingdisk_get_chunksize(h[activehd]->disk));
+           snprintf(use, SIZEOF(use), OFF_T_FMT
+                    (OFF_T_FMT_TYPE)(h[activehd]->reserved - h[activehd]->used));
            cmdline = vstralloc(cmdstr[cmd],
                                " ", disk2serial(dp),
-                               " ", h[activehd]->destname,
+                               " ", qdest,
                                " ", chunksize,
                                " ", use,
                                "\n", NULL );
+           amfree(qdest);
+           amfree(qname);
        } else {
            cmdline = stralloc2(cmdstr[cmd], "\n");
        }
        break;
     case QUIT:
+    case ABORT:
        cmdline = stralloc2(cmdstr[cmd], "\n");
        break;
     case DONE:
     case FAILED:
-       if( dp) {
+       if( dp ) {
            cmdline = vstralloc(cmdstr[cmd],
                                " ", disk2serial(dp),
                                "\n",  NULL);
@@ -510,7 +593,9 @@ disk_t *dp;
        break;
     default:
        error("Don't know how to send %s command to chunker", cmdstr[cmd]);
+       /*NOTREACHED*/
     }
+
     /*
      * Note: cmdline already has a '\n'.
      */
@@ -523,6 +608,7 @@ disk_t *dp;
        amfree(cmdline);
        return 0;
     }
+    if (cmd == QUIT) aclose(chunker->fd);
     amfree(cmdline);
     return 1;
 }
@@ -536,8 +622,9 @@ struct serial_s {
     disk_t *dp;
 } stable[MAX_SERIAL];
 
-disk_t *serial2disk(str)
-char *str;
+disk_t *
+serial2disk(
+    char *str)
 {
     int rc, s;
     long gen;
@@ -545,17 +632,20 @@ char *str;
     rc = sscanf(str, "%d-%ld", &s, &gen);
     if(rc != 2) {
        error("error [serial2disk \"%s\" parse error]", str);
+       /*NOTREACHED*/
     } else if (s < 0 || s >= MAX_SERIAL) {
        error("error [serial out of range 0..%d: %d]", MAX_SERIAL, s);
+       /*NOTREACHED*/
     }
     if(gen != stable[s].gen)
-       printf("driver: error time %s serial gen mismatch %s\n",
+       printf("driver: serial2disk error time %s serial gen mismatch %s\n",
               walltime_str(curclock()), str);
     return stable[s].dp;
 }
 
-void free_serial(str)
-char *str;
+void
+free_serial(
+    char *str)
 {
     int rc, s;
     long gen;
@@ -570,15 +660,16 @@ char *str;
     }
 
     if(gen != stable[s].gen)
-       printf("driver: error time %s serial gen mismatch\n",
-              walltime_str(curclock()));
+       printf("driver: free_serial error time %s serial gen mismatch %s\n",
+              walltime_str(curclock()),str);
     stable[s].gen = 0;
     stable[s].dp = NULL;
 }
 
 
-void free_serial_dp(dp)
-disk_t *dp;
+void
+free_serial_dp(
+    disk_t *dp)
 {
     int s;
 
@@ -595,7 +686,8 @@ disk_t *dp;
 }
 
 
-void check_unfree_serial()
+void
+check_unfree_serial(void)
 {
     int s;
 
@@ -608,15 +700,15 @@ void check_unfree_serial()
     }
 }
 
-char *disk2serial(dp)
-disk_t *dp;
+char *disk2serial(
+    disk_t *dp)
 {
     int s;
     static char str[NUM_STR_SIZE];
 
     for(s = 0; s < MAX_SERIAL; s++) {
        if(stable[s].dp == dp) {
-           snprintf(str, sizeof(str), "%02d-%05ld", s, stable[s].gen);
+           snprintf(str, SIZEOF(str), "%02d-%05ld", s, stable[s].gen);
            return str;
        }
     }
@@ -634,15 +726,16 @@ disk_t *dp;
     stable[s].gen = generation++;
     stable[s].dp = dp;
 
-    snprintf(str, sizeof(str), "%02d-%05ld", s, stable[s].gen);
+    snprintf(str, SIZEOF(str), "%02d-%05ld", s, stable[s].gen);
     return str;
 }
 
-void update_info_dumper(dp, origsize, dumpsize, dumptime)
-     disk_t *dp;
-     long origsize;
-     long dumpsize;
-     long dumptime;
+void
+update_info_dumper(
+     disk_t *dp,
+     off_t origsize,
+     off_t dumpsize,
+     time_t dumptime)
 {
     int level, i;
     info_t info;
@@ -660,6 +753,7 @@ void update_info_dumper(dp, origsize, dumpsize, dumptime)
     }
     if (open_infofile(conf_infofile)) {
        error("could not open info db \"%s\"", conf_infofile);
+       /*NOTREACHED*/
     }
     amfree(conf_infofile);
 
@@ -670,9 +764,9 @@ void update_info_dumper(dp, origsize, dumpsize, dumptime)
        update_info_taper(). */
     for (i = level; i < DUMP_LEVELS; ++i) {
       infp = &info.inf[i];
-      infp->size = -1;
-      infp->csize = -1;
-      infp->secs = -1;
+      infp->size = (off_t)-1;
+      infp->csize = (off_t)-1;
+      infp->secs = (time_t)-1;
       infp->date = (time_t)-1;
       infp->label[0] = '\0';
       infp->filenum = 0;
@@ -689,14 +783,14 @@ void update_info_dumper(dp, origsize, dumpsize, dumptime)
     else perfp = &info.incr;
 
     /* Update the stats, but only if the new values are meaningful */
-    if(dp->compress != COMP_NONE && origsize > 0L) {
-       newperf(perfp->comp, dumpsize/(float)origsize);
+    if(dp->compress != COMP_NONE && origsize > (off_t)0) {
+       newperf(perfp->comp, (double)dumpsize/(double)origsize);
     }
-    if(dumptime > 0L) {
-       if(dumptime >= dumpsize)
+    if(dumptime > (time_t)0) {
+       if((off_t)dumptime >= dumpsize)
            newperf(perfp->rate, 1);
        else
-           newperf(perfp->rate, dumpsize/dumptime);
+           newperf(perfp->rate, (double)dumpsize/(double)dumptime);
     }
 
     if(getconf_int(CNF_RESERVE)<100) {
@@ -710,7 +804,7 @@ void update_info_dumper(dp, origsize, dumpsize, dumptime)
        info.consecutive_runs = 1;
     }
 
-    if(origsize >=0 && dumpsize >=0) {
+    if(origsize >= (off_t)0 && dumpsize >= (off_t)0) {
        for(i=NB_HISTORY-1;i>0;i--) {
            info.history[i] = info.history[i-1];
        }
@@ -722,48 +816,54 @@ void update_info_dumper(dp, origsize, dumpsize, dumptime)
        info.history[0].secs  = dumptime;
     }
 
-    if(put_info(dp->host->hostname, dp->name, &info))
-       error("infofile update failed (%s,%s)\n", dp->host->hostname, dp->name);
+    if(put_info(dp->host->hostname, dp->name, &info)) {
+       error("infofile update failed (%s,'%s')\n", dp->host->hostname, dp->name);
+       /*NOTREACHED*/
+    }
 
     close_infofile();
 }
 
-void update_info_taper(dp, label, filenum, level)
-disk_t *dp;
-char *label;
-int filenum;
-int level;
+void
+update_info_taper(
+    disk_t *dp,
+    char *label,
+    off_t filenum,
+    int level)
 {
     info_t info;
     stats_t *infp;
     int rc;
 
     rc = open_infofile(getconf_str(CNF_INFOFILE));
-    if(rc)
+    if(rc) {
        error("could not open infofile %s: %s (%d)", getconf_str(CNF_INFOFILE),
              strerror(errno), rc);
+       /*NOTREACHED*/
+    }
 
     get_info(dp->host->hostname, dp->name, &info);
 
     infp = &info.inf[level];
     /* XXX - should we record these two if no-record? */
-    strncpy(infp->label, label, sizeof(infp->label)-1);
-    infp->label[sizeof(infp->label)-1] = '\0';
+    strncpy(infp->label, label, SIZEOF(infp->label)-1);
+    infp->label[SIZEOF(infp->label)-1] = '\0';
     infp->filenum = filenum;
 
     info.command = NO_COMMAND;
 
-    if(put_info(dp->host->hostname, dp->name, &info))
-       error("infofile update failed (%s,%s)\n", dp->host->hostname, dp->name);
-
+    if(put_info(dp->host->hostname, dp->name, &info)) {
+       error("infofile update failed (%s,'%s')\n", dp->host->hostname, dp->name);
+       /*NOTREACHED*/
+    }
     close_infofile();
 }
 
 /* Free an array of pointers to assignedhd_t after freeing the
  * assignedhd_t themselves. The array must be NULL-terminated.
  */
-void free_assignedhd( ahd )
-assignedhd_t **ahd;
+void free_assignedhd(
+    assignedhd_t **ahd)
 {
     int i;
 
index 0d53c94c4cbd3052ef078a8bc06b6d9a19d9ae41..796a53f66639f8cb5135dd9ad0619247ec6ab00d 100644 (file)
  *                        University of Maryland at College Park
  */
 /*
- * $Id: driverio.h,v 1.32 2005/12/03 13:27:43 martinea Exp $
+ * $Id: driverio.h,v 1.35 2006/05/25 01:47:19 johnfranks Exp $
  *
  * driver-related helper functions
  */
+#ifndef DRIVERIO_H
+#define DRIVERIO_H
 
 #include "event.h"
 
@@ -45,7 +47,7 @@
 
 typedef struct chunker_s {
     char *name;                        /* name of this chunker */
-    int pid;                   /* its pid */
+    pid_t pid;                 /* its pid */
     int down;                  /* state */
     int fd;                    /* read/write */
     int result;
@@ -57,7 +59,7 @@ typedef struct chunker_s {
 
 typedef struct dumper_s {
     char *name;                        /* name of this dumper */
-    int pid;                   /* its pid */
+    pid_t pid;                 /* its pid */
     int busy, down;            /* state */
     int fd;                    /* read/write */
     int result;
@@ -69,8 +71,8 @@ typedef struct dumper_s {
 
 typedef struct assignedhd_s {
     holdingdisk_t      *disk;
-    long               used;
-    long               reserved;
+    off_t              used;
+    off_t              reserved;
     char               *destname;
 } assignedhd_t;
 
@@ -79,12 +81,13 @@ typedef struct assignedhd_s {
 typedef struct sched_s {
     int attempted, priority;
     int level, degr_level;
-    long est_time, degr_time;
-    unsigned long est_size, degr_size, act_size;
-    unsigned long origsize, dumpsize;
-    unsigned long dumptime, tapetime;
+    unsigned long est_time, degr_time;
+    off_t est_nsize, est_csize, est_size;
+    off_t degr_nsize, degr_csize, act_size;
+    off_t origsize, dumpsize;
+    time_t dumptime, tapetime;
     char *dumpdate, *degr_dumpdate;
-    int est_kps, degr_kps;
+    unsigned long est_kps, degr_kps;
     char *destname;                            /* file/port name */
     dumper_t *dumper;
     assignedhd_t **holdp;
@@ -101,7 +104,7 @@ typedef struct sched_s {
 
 typedef struct holdalloc_s {
     int allocated_dumpers;
-    long allocated_space;
+    off_t allocated_space;
 } holdalloc_t;
 
 #define holdalloc(hp)  ((holdalloc_t *) (hp)->up)
@@ -111,24 +114,22 @@ GLOBAL chunker_t chktable[MAX_DUMPERS];
 
 /* command/result tokens */
 
-GLOBAL int taper, taper_busy, taper_pid;
+GLOBAL int taper, taper_busy;
+GLOBAL pid_t taper_pid;
 GLOBAL event_handle_t *taper_ev_read;
 
-void init_driverio P((void));
-void startup_tape_process P((char *taper_program));
-void startup_dump_process P((dumper_t *dumper, char *dumper_program));
-void startup_dump_processes P((char *dumper_program, int inparallel));
-void startup_chunk_process P((chunker_t *chunker, char *chunker_program));
-
-cmd_t getresult P((int fd, int show, int *result_argc, char **result_argv, int max_arg));
-int taper_cmd P((cmd_t cmd, void *ptr, char *destname, int level, char *datestamp));
-int dumper_cmd P((dumper_t *dumper, cmd_t cmd, disk_t *dp));
-int chunker_cmd P((chunker_t *chunker, cmd_t cmd, disk_t *dp));
-disk_t *serial2disk P((char *str));
-void free_serial P((char *str));
-void free_serial_dp P((disk_t *dp));
-void check_unfree_serial P(());
-char *disk2serial P((disk_t *dp));
-void update_info_dumper P((disk_t *dp, long origsize, long dumpsize, long dumptime));
-void update_info_taper P((disk_t *dp, char *label, int filenum, int level));
-void free_assignedhd P((assignedhd_t **holdp));
+void init_driverio(void);
+void startup_tape_process(char *taper_program);
+void startup_dump_process(dumper_t *dumper, char *dumper_program);
+void startup_dump_processes(char *dumper_program, int inparallel, char *timestamp);
+void startup_chunk_process(chunker_t *chunker, char *chunker_program);
+
+disk_t *serial2disk(char *str);
+void free_serial(char *str);
+void free_serial_dp(disk_t *dp);
+void check_unfree_serial(void);
+char *disk2serial(disk_t *dp);
+void update_info_dumper(disk_t *dp, off_t origsize, off_t dumpsize, time_t dumptime);
+void update_info_taper(disk_t *dp, char *label, off_t filenum, int level);
+void free_assignedhd(assignedhd_t **holdp);
+#endif /* !DRIVERIO_H */
index 1e008601cf65cfa5fc137bc1baa6741087f29ccf..e8aff88e05f5930b942d0f29724c455df853eba5 100644 (file)
@@ -23,7 +23,7 @@
  * Authors: the Amanda Development Team.  Its members are listed in a
  * file named AUTHORS, in the root directory of this distribution.
  */
-/* $Id: dumper.c,v 1.170 2006/03/22 15:10:52 martinea Exp $
+/* $Id: dumper.c,v 1.190 2006/08/30 19:53:57 martinea Exp $
  *
  * requests remote amandad processes to dump filesystems
  */
@@ -70,8 +70,8 @@ struct databuf {
 static char *handle = NULL;
 
 static char *errstr = NULL;
-static long dumpbytes;
-static long dumpsize, headersize, origsize;
+static off_t dumpbytes;
+static off_t dumpsize, headersize, origsize;
 
 static comp_t srvcompress = COMP_NONE;
 char *srvcompprog = NULL;
@@ -87,14 +87,19 @@ static FILE *errf = NULL;
 static char *hostname = NULL;
 am_feature_t *their_features = NULL;
 static char *diskname = NULL;
+static char *qdiskname = NULL;
 static char *device = NULL;
 static char *options = NULL;
 static char *progname = NULL;
+static char *amandad_path=NULL;
+static char *client_username=NULL;
+static char *ssh_keys=NULL;
 static int level;
 static char *dumpdate = NULL;
-static char *datestamp;
-static int conf_dtimeout;
+static char *dumper_timestamp = NULL;
+static time_t conf_dtimeout;
 static int indexfderror;
+static int set_datafd;
 
 static dumpfile_t file;
 
@@ -109,44 +114,46 @@ static struct {
 #define        INDEXFD 2
     { "INDEX", NULL },
 };
-#define        NSTREAMS        (sizeof(streams) / sizeof(streams[0]))
+#define        NSTREAMS        (int)(sizeof(streams) / sizeof(streams[0]))
 
 static am_feature_t *our_features = NULL;
 static char *our_feature_string = NULL;
 
 /* local functions */
-int main P((int, char **));
-static int do_dump P((struct databuf *));
-static void check_options P((char *));
-static void finish_tapeheader P((dumpfile_t *));
-static int write_tapeheader P((int, dumpfile_t *));
-static void databuf_init P((struct databuf *, int));
-static int databuf_write P((struct databuf *, const void *, int));
-static int databuf_flush P((struct databuf *));
-static void process_dumpeof P((void));
-static void process_dumpline P((const char *));
-static void add_msg_data P((const char *, size_t));
-static void parse_info_line P((char *));
-static void log_msgout P((logtype_t));
-
-static int runcompress P((int, pid_t *, comp_t));
-static int runencrypt P((int, pid_t *,  encrypt_t));
-
-static void sendbackup_response P((void *, pkt_t *, security_handle_t *));
-static int startup_dump P((const char *, const char *, const char *, int,
-                          const char *, const char *, const char *));
-static void stop_dump P((void));
-
-static void read_indexfd P((void *, void *, ssize_t));
-static void read_datafd P((void *, void *, ssize_t));
-static void read_mesgfd P((void *, void *, ssize_t));
-static void timeout P((int));
-static void timeout_callback P((void *));
+int            main(int, char **);
+static int     do_dump(struct databuf *);
+static void    check_options(char *);
+static void    finish_tapeheader(dumpfile_t *);
+static ssize_t write_tapeheader(int, dumpfile_t *);
+static void    databuf_init(struct databuf *, int);
+static int     databuf_write(struct databuf *, const void *, size_t);
+static int     databuf_flush(struct databuf *);
+static void    process_dumpeof(void);
+static void    process_dumpline(const char *);
+static void    add_msg_data(const char *, size_t);
+static void    parse_info_line(char *);
+static void    log_msgout(logtype_t);
+static char *  dumper_get_security_conf (char *, void *);
+
+static int     runcompress(int, pid_t *, comp_t);
+static int     runencrypt(int, pid_t *,  encrypt_t);
+
+static void    sendbackup_response(void *, pkt_t *, security_handle_t *);
+static int     startup_dump(const char *, const char *, const char *, int,
+                       const char *, const char *, const char *,
+                       const char *, const char *, const char *);
+static void    stop_dump(void);
+
+static void    read_indexfd(void *, void *, ssize_t);
+static void    read_datafd(void *, void *, ssize_t);
+static void    read_mesgfd(void *, void *, ssize_t);
+static void    timeout(time_t);
+static void    timeout_callback(void *);
 
 static void
-check_options(options)
-    char *options;
-{      
+check_options(
+    char *options)
+{
   char *compmode = NULL;
   char *compend  = NULL;
   char *encryptmode = NULL;
@@ -221,25 +228,31 @@ check_options(options)
 
 
 int
-main(main_argc, main_argv)
-    int main_argc;
-    char **main_argv;
+main(
+    int                main_argc,
+    char **    main_argv)
 {
     static struct databuf db;
     struct cmdargs cmdargs;
     cmd_t cmd;
     int outfd = -1;
-    int taper_port, rc;
+    int rc;
+    in_port_t taper_port;
     unsigned long malloc_hist_1, malloc_size_1;
     unsigned long malloc_hist_2, malloc_size_2;
     char *conffile;
     char *q = NULL;
     int a;
+    uid_t ruid;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
 
     set_pname("dumper");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -248,14 +261,19 @@ main(main_argc, main_argv)
     erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
     set_logerror(logerror);
 
-    if (main_argc > 1) {
-       config_name = stralloc(main_argv[1]);
+    parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if (my_argc > 1) {
+       config_name = stralloc(my_argv[1]);
        config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     } else {
        char my_cwd[STR_SIZE];
 
-       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
            error("cannot determine current working directory");
+           /*NOTREACHED*/
        }
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
@@ -271,38 +289,45 @@ main(main_argc, main_argv)
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if(read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
     /*
-     * Make our effective uid nonprivlidged, but keep our real uid as root
+     * Make our effective uid nonprivlidged, keeping save uid as root
      * in case we need to get back (to bind privlidged ports, etc).
      */
+    ruid = getuid();
     if(geteuid() == 0) {
-       uid_t ruid = getuid();
-       setuid(0);
        seteuid(ruid);
        setgid(getgid());
     }
 #if defined BSD_SECURITY && !defined SSH_SECURITY
-    else error("must be run setuid root to communicate correctly");
+    else {
+       error("must be run setuid root to communicate correctly");
+       /*NOTREACHED*/
+    }
 #endif
 
     fprintf(stderr,
            "%s: pid %ld executable %s version %s\n",
            get_pname(), (long) getpid(),
-           main_argv[0], version());
+           my_argv[0], version());
     fflush(stderr);
 
     /* now, make sure we are a valid user */
 
-    if (getpwuid(getuid()) == NULL)
+    if (getpwuid(getuid()) == NULL) {
        error("can't get login name for my uid %ld", (long)getuid());
+       /*NOTREACHED*/
+    }
 
     signal(SIGPIPE, SIG_IGN);
 
-    datestamp = construct_datestamp(NULL);
-    conf_dtimeout = getconf_int(CNF_DTIMEOUT);
+    conf_dtimeout = getconf_time(CNF_DTIMEOUT);
 
     protocol_init();
 
@@ -310,6 +335,15 @@ main(main_argc, main_argv)
        cmd = getcmd(&cmdargs);
 
        switch(cmd) {
+       case START:
+           if(cmdargs.argc <  2)
+               error("error [dumper START: not enough args: timestamp]");
+           dumper_timestamp = newstralloc(dumper_timestamp, cmdargs.argv[2]);
+           break;
+
+       case ABORT:
+           break;
+
        case QUIT:
            break;
 
@@ -325,6 +359,9 @@ main(main_argc, main_argv)
             *   level
             *   dumpdate
             *   progname
+            *   amandad_path
+            *   client_username
+            *   ssh_keys
             *   options
             */
            cmdargs.argc++;                     /* true count of args */
@@ -332,68 +369,113 @@ main(main_argc, main_argv)
 
            if(a >= cmdargs.argc) {
                error("error [dumper PORT-DUMP: not enough args: handle]");
+               /*NOTREACHED*/
            }
            handle = newstralloc(handle, cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
-               error("error [dumper PORT-DUMP: not enough args: handle]");
+               error("error [dumper PORT-DUMP: not enough args: port]");
+               /*NOTREACHED*/
            }
-           taper_port = atoi(cmdargs.argv[a++]);
+           taper_port = (in_port_t)atoi(cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
-               error("error [dumper PORT-DUMP: not enough args: handle]");
+               error("error [dumper PORT-DUMP: not enough args: hostname]");
+               /*NOTREACHED*/
            }
            hostname = newstralloc(hostname, cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
                error("error [dumper PORT-DUMP: not enough args: features]");
+               /*NOTREACHED*/
            }
            am_release_feature_set(their_features);
            their_features = am_string_to_feature(cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
-               error("error [dumper PORT-DUMP: not enough args: handle]");
+               error("error [dumper PORT-DUMP: not enough args: diskname]");
+               /*NOTREACHED*/
            }
-           diskname = newstralloc(diskname, cmdargs.argv[a++]);
+           qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]);
+           if (diskname != NULL)
+               amfree(diskname);
+           diskname = unquote_string(qdiskname);
 
            if(a >= cmdargs.argc) {
-               error("error [dumper PORT-DUMP: not enough args: handle]");
+               error("error [dumper PORT-DUMP: not enough args: device]");
+               /*NOTREACHED*/
            }
            device = newstralloc(device, cmdargs.argv[a++]);
-           if(strcmp(device,"NODEVICE") == 0) amfree(device);
+           if(strcmp(device,"NODEVICE") == 0)
+               amfree(device);
 
            if(a >= cmdargs.argc) {
-               error("error [dumper PORT-DUMP: not enough args: handle]");
+               error("error [dumper PORT-DUMP: not enough args: level]");
+               /*NOTREACHED*/
            }
            level = atoi(cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
-               error("error [dumper PORT-DUMP: not enough args: handle]");
+               error("error [dumper PORT-DUMP: not enough args: dumpdate]");
+               /*NOTREACHED*/
            }
            dumpdate = newstralloc(dumpdate, cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
-               error("error [dumper PORT-DUMP: not enough args: handle]");
+               error("error [dumper PORT-DUMP: not enough args: program]");
+               /*NOTREACHED*/
            }
            progname = newstralloc(progname, cmdargs.argv[a++]);
 
            if(a >= cmdargs.argc) {
-               error("error [dumper PORT-DUMP: not enough args: handle]");
+               error("error [dumper PORT-DUMP: not enough args: amandad_path]");
+               /*NOTREACHED*/
+           }
+           amandad_path = newstralloc(amandad_path, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: client_username]");
+           }
+           client_username = newstralloc(client_username, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: ssh_keys]");
+           }
+           ssh_keys = newstralloc(ssh_keys, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: options]");
            }
            options = newstralloc(options, cmdargs.argv[a++]);
 
            if(a != cmdargs.argc) {
                error("error [dumper PORT-DUMP: too many args: %d != %d]",
                      cmdargs.argc, a);
+               /*NOTREACHED*/
            }
 
-           /* connect outf to taper port */
+           if ((gethostbyname("localhost")) == NULL) {
+               errstr = newstralloc(errstr,
+                                    "could not resolve localhost");
+               q = squotef(errstr);
+               putresult(FAILED, "%s %s\n", handle, q);
+               log_add(L_FAIL, "%s %s %s %d [%s]", hostname, qdiskname,
+                       dumper_timestamp, level, errstr);
+               amfree(q);
+               break;
+           }
+           /* connect outf to chunker/taper port */
 
            outfd = stream_client("localhost", taper_port,
-                                 STREAM_BUFSIZE, -1, NULL, 0);
+                                 STREAM_BUFSIZE, 0, NULL, 0);
            if (outfd == -1) {
-               q = squotef("[taper port open: %s]", strerror(errno));
+               
+               errstr = newvstralloc(errstr, "port open: ",
+                                     strerror(errno), NULL);
+               q = squotef(errstr);
                putresult(FAILED, "%s %s\n", handle, q);
+               log_add(L_FAIL, "%s %s %s %d [%s]", hostname, qdiskname,
+                       dumper_timestamp, level, errstr);
                amfree(q);
                break;
            }
@@ -407,19 +489,25 @@ main(main_argc, main_argv)
                              level,
                              dumpdate,
                              progname,
+                             amandad_path,
+                             client_username,
+                             ssh_keys,
                              options);
            if (rc != 0) {
                q = squote(errstr);
                putresult(rc == 2? FAILED : TRYAGAIN, "%s %s\n",
                    handle, q);
                if (rc == 2)
-                   log_add(L_FAIL, "%s %s %s %d [%s]", hostname, diskname,
-                       datestamp, level, errstr);
+                   log_add(L_FAIL, "%s %s %s %d [%s]", hostname, qdiskname,
+                       dumper_timestamp, level, errstr);
                amfree(q);
            } else {
-               if (do_dump(&db)) {
-               }
+               do_dump(&db);
            }
+
+           amfree(amandad_path);
+           amfree(client_username);
+
            break;
 
        default:
@@ -439,10 +527,21 @@ main(main_argc, main_argv)
            aclose(outfd);
     } while(cmd != QUIT);
 
+    /* make sure root privilege is dropped */
+    if ( geteuid() == 0 ) {
+      setuid(ruid);
+      seteuid(ruid);
+    }
+
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
+    am_release_feature_set(our_features);
+    amfree(our_feature_string);
     amfree(errstr);
-    amfree(datestamp);
+    amfree(dumper_timestamp);
     amfree(handle);
     amfree(hostname);
+    amfree(qdiskname);
     amfree(diskname);
     amfree(device);
     amfree(dumpdate);
@@ -459,10 +558,12 @@ main(main_argc, main_argv)
 
     malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
-    if (malloc_size_1 != malloc_size_2)
+    if (malloc_size_1 != malloc_size_2) {
        malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
+    }
 
-    exit(0);
+    dbclose();
+    return (0); /* exit */
 }
 
 
@@ -470,9 +571,9 @@ main(main_argc, main_argv)
  * Initialize a databuf.  Takes a writeable file descriptor.
  */
 static void
-databuf_init(db, fd)
-    struct databuf *db;
-    int fd;
+databuf_init(
+    struct databuf *   db,
+    int                        fd)
 {
 
     db->fd = fd;
@@ -489,10 +590,10 @@ databuf_init(db, fd)
  * any boundaries.
  */
 static int
-databuf_write(db, buf, size)
-    struct databuf *db;
-    const void *buf;
-    int size;
+databuf_write(
+    struct databuf *   db,
+    const void *       buf,
+    size_t             size)
 {
     db->buf = (char *)buf;
     db->datain = db->datalimit = db->buf + size;
@@ -504,10 +605,10 @@ databuf_write(db, buf, size)
  * Write out the buffer to chunker.
  */
 static int
-databuf_flush(db)
-    struct databuf *db;
+databuf_flush(
+    struct databuf *   db)
 {
-    int written;
+    ssize_t written;
 
     /*
      * If there's no data, do nothing.
@@ -519,14 +620,15 @@ databuf_flush(db)
     /*
      * Write out the buffer
      */
-    written = fullwrite(db->fd, db->dataout, db->datain - db->dataout);
+    written = fullwrite(db->fd, db->dataout,
+                       (size_t)(db->datain - db->dataout));
     if (written > 0) {
        db->dataout += written;
-        dumpbytes += written;
+        dumpbytes += (off_t)written;
     }
-    if (dumpbytes >= 1024) {
-       dumpsize += (dumpbytes / 1024);
-       dumpbytes %= 1024;
+    if (dumpbytes >= (off_t)1024) {
+       dumpsize += (dumpbytes / (off_t)1024);
+       dumpbytes %= (off_t)1024;
     }
     if (written < 0) {
        errstr = squotef("data write: %s", strerror(errno));
@@ -545,7 +647,7 @@ static int status;
 
 
 static void
-process_dumpeof()
+process_dumpeof(void)
 {
     /* process any partial line in msgbuf? !!! */
     add_msg_data(NULL, 0);
@@ -577,26 +679,26 @@ process_dumpeof()
  * of any duplicates.
  */
 static void
-parse_info_line(str)
-    char *str;
+parse_info_line(
+    char *str)
 {
     static const struct {
        const char *name;
        char *value;
        size_t len;
     } fields[] = {
-       { "BACKUP", file.program, sizeof(file.program) },
-       { "RECOVER_CMD", file.recover_cmd, sizeof(file.recover_cmd) },
-       { "COMPRESS_SUFFIX", file.comp_suffix, sizeof(file.comp_suffix) },
-       { "SERVER_CUSTOM_COMPRESS", file.srvcompprog, sizeof(file.srvcompprog) },
-       { "CLIENT_CUSTOM_COMPRESS", file.clntcompprog, sizeof(file.clntcompprog) },
-       { "SERVER_ENCRYPT", file.srv_encrypt, sizeof(file.srv_encrypt) },
-       { "CLIENT_ENCRYPT", file.clnt_encrypt, sizeof(file.clnt_encrypt) },
-       { "SERVER_DECRYPT_OPTION", file.srv_decrypt_opt, sizeof(file.srv_decrypt_opt) },
-       { "CLIENT_DECRYPT_OPTION", file.clnt_decrypt_opt, sizeof(file.clnt_decrypt_opt) }
+       { "BACKUP", file.program, SIZEOF(file.program) },
+       { "RECOVER_CMD", file.recover_cmd, SIZEOF(file.recover_cmd) },
+       { "COMPRESS_SUFFIX", file.comp_suffix, SIZEOF(file.comp_suffix) },
+       { "SERVER_CUSTOM_COMPRESS", file.srvcompprog, SIZEOF(file.srvcompprog) },
+       { "CLIENT_CUSTOM_COMPRESS", file.clntcompprog, SIZEOF(file.clntcompprog) },
+       { "SERVER_ENCRYPT", file.srv_encrypt, SIZEOF(file.srv_encrypt) },
+       { "CLIENT_ENCRYPT", file.clnt_encrypt, SIZEOF(file.clnt_encrypt) },
+       { "SERVER_DECRYPT_OPTION", file.srv_decrypt_opt, SIZEOF(file.srv_decrypt_opt) },
+       { "CLIENT_DECRYPT_OPTION", file.clnt_decrypt_opt, SIZEOF(file.clnt_decrypt_opt) }
     };
     char *name, *value;
-    int i;
+    size_t i;
 
     if (strcmp(str, "end") == 0) {
        SET(status, GOT_INFO_ENDLINE);
@@ -610,7 +712,7 @@ parse_info_line(str)
     if (value == NULL)
        return;
 
-    for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++) {
+    for (i = 0; i < SIZEOF(fields) / SIZEOF(fields[0]); i++) {
        if (strcmp(name, fields[i].name) == 0) {
            strncpy(fields[i].value, value, fields[i].len - 1);
            fields[i].value[fields[i].len - 1] = '\0';
@@ -620,8 +722,8 @@ parse_info_line(str)
 }
 
 static void
-process_dumpline(str)
-    const char *str;
+process_dumpline(
+    const char *       str)
 {
     char *buf, *tok;
 
@@ -645,13 +747,14 @@ process_dumpline(str)
        if (tok == NULL)
            goto bad_line;
 
-       if (strcmp(tok, "start") == 0)
+       if (strcmp(tok, "start") == 0) {
            break;
+       }
 
        if (strcmp(tok, "size") == 0) {
            tok = strtok(NULL, "");
            if (tok != NULL) {
-               origsize = (long)atof(tok);
+               origsize = OFF_T_ATOI(tok);
                SET(status, GOT_SIZELINE);
            }
            break;
@@ -704,16 +807,17 @@ bad_line:
 }
 
 static void
-add_msg_data(str, len)
-    const char *str;
-    size_t len;
+add_msg_data(
+    const char *       str,
+    size_t             len)
 {
     static struct {
        char *buf;      /* buffer holding msg data */
        size_t size;    /* size of alloced buffer */
     } msg = { NULL, 0 };
-    char *line, *nl;
+    char *line, *ch;
     size_t buflen;
+    int        in_quotes = 0;
 
     if (msg.buf != NULL)
        buflen = strlen(msg.buf);
@@ -727,8 +831,9 @@ add_msg_data(str, len)
     if (str == NULL) {
        if (buflen == 0)
            return;
-       fprintf(errf,"? %s: error [partial line in msgbuf: %ld bytes]\n",
-           get_pname(), (long)buflen);
+       fprintf(errf,"? %s: error [partial line in msgbuf: "
+                               SIZE_T_FMT " bytes]\n", get_pname(),
+                               (SIZE_T_FMT_TYPE)buflen);
        fprintf(errf,"? %s: error [partial line in msgbuf: \"%s\"]\n",
            get_pname(), msg.buf);
        msg.buf[0] = '\0';
@@ -738,18 +843,18 @@ add_msg_data(str, len)
     /*
      * Expand the buffer if it can't hold the new contents.
      */
-    if (buflen + len + 1 > msg.size) {
+    if ((buflen + len + 1) > msg.size) {
        char *newbuf;
        size_t newsize;
 
 /* round up to next y, where y is a power of 2 */
 #define        ROUND(x, y)     (((x) + (y) - 1) & ~((y) - 1))
 
-       newsize = ROUND(buflen + len + 1, 256);
+       newsize = ROUND(buflen + (ssize_t)len + 1, 256);
        newbuf = alloc(newsize);
 
        if (msg.buf != NULL) {
-           strcpy(newbuf, msg.buf);
+           strncpy(newbuf, msg.buf, newsize);
            amfree(msg.buf);
        } else
            newbuf[0] = '\0';
@@ -765,17 +870,21 @@ add_msg_data(str, len)
 
     /*
      * Process all lines in the buffer
+     * scanning line for unqouted newline.
      */
-    for (line = msg.buf;;) {
-       /*
-        * If there's no newline, then we've only got a partial line.
-        * We go back for more.
-        */
-       if ((nl = strchr(line, '\n')) == NULL)
-           break;
-       *nl = '\0';
-       process_dumpline(line);
-       line = nl + 1;
+    for (ch = line = msg.buf; *ch != '\0'; ch++) {
+       if (*ch == '"') {
+           in_quotes = !in_quotes;
+       } else if ((*ch == '\\') && (*(ch + 1) == '"')) {
+               ch++;
+       } else if (!in_quotes && (*ch == '\n')) {
+           /*
+            * Found an unqouted newline.  Terminate and process line.
+            */
+           *ch = '\0';
+           process_dumpline(line);
+           line = ch + 1;
+       }
     }
 
     /*
@@ -784,7 +893,7 @@ add_msg_data(str, len)
      */
     if (*line != '\0') {
        buflen = strlen(line);
-       memmove(msg.buf, line, buflen + 1);
+       memmove(msg.buf, line, (size_t)buflen + 1);
     } else {
        msg.buf[0] = '\0';
     }
@@ -792,15 +901,19 @@ add_msg_data(str, len)
 
 
 static void
-log_msgout(typ)
-    logtype_t typ;
+log_msgout(
+    logtype_t  typ)
 {
     char *line;
 
     fflush(errf);
-    (void) fseek(errf, 0L, SEEK_SET);
+    if (fseek(errf, 0L, SEEK_SET) < 0) {
+       dbprintf(("log_msgout: warning - seek failed: %s\n", strerror(errno)));
+    }
     while ((line = agets(errf)) != NULL) {
-       log_add(typ, "%s", line);
+       if (line[0] != '\0') {
+               log_add(typ, "%s", line);
+       }
        amfree(line);
     }
 
@@ -813,16 +926,16 @@ log_msgout(typ)
  * Fill in the rest of the tape header
  */
 static void
-finish_tapeheader(file)
-    dumpfile_t *file;
+finish_tapeheader(
+    dumpfile_t *file)
 {
 
     assert(ISSET(status, HEADER_DONE));
 
     file->type = F_DUMPFILE;
-    strncpy(file->datestamp, datestamp, sizeof(file->datestamp) - 1);
-    strncpy(file->name, hostname, sizeof(file->name) - 1);
-    strncpy(file->disk, diskname, sizeof(file->disk) - 1);
+    strncpy(file->datestamp, dumper_timestamp, sizeof(file->datestamp) - 1);
+    strncpy(file->name, hostname, SIZEOF(file->name) - 1);
+    strncpy(file->disk, diskname, SIZEOF(file->disk) - 1);
     file->dumplevel = level;
 
     /*
@@ -835,28 +948,31 @@ finish_tapeheader(file)
 #define        UNCOMPRESS_OPT  ""
 #endif
        if (srvcompress == COMP_SERV_CUST) {
-           snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+           snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd),
                     " %s %s |", srvcompprog, "-d");
-           strcpy(file->comp_suffix, "cust");
-           strncpy(file->srvcompprog, srvcompprog, sizeof(file->srvcompprog));
-           file->srvcompprog[sizeof(file->srvcompprog)-1] = '\0';
+           strncpy(file->comp_suffix, "cust", SIZEOF(file->comp_suffix) - 1);
+           file->comp_suffix[SIZEOF(file->comp_suffix) - 1] = '\0';
+           strncpy(file->srvcompprog, srvcompprog, SIZEOF(file->srvcompprog) - 1);
+           file->srvcompprog[SIZEOF(file->srvcompprog) - 1] = '\0';
        } else if ( srvcompress == COMP_CUST ) {
-           snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+           snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd),
                     " %s %s |", clntcompprog, "-d");
-           strcpy(file->comp_suffix, "cust");
-           strncpy(file->clntcompprog, clntcompprog, sizeof(file->clntcompprog));
-           file->clntcompprog[sizeof(file->clntcompprog)-1] = '\0';
+           strncpy(file->comp_suffix, "cust", SIZEOF(file->comp_suffix) - 1);
+           file->comp_suffix[SIZEOF(file->comp_suffix) - 1] = '\0';
+           strncpy(file->clntcompprog, clntcompprog, SIZEOF(file->clntcompprog));
+           file->clntcompprog[SIZEOF(file->clntcompprog) - 1] = '\0';
        } else {
-           snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+           snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd),
                " %s %s |", UNCOMPRESS_PATH, UNCOMPRESS_OPT);
-           strncpy(file->comp_suffix, COMPRESS_SUFFIX,sizeof(file->comp_suffix)-1);
-           file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+           strncpy(file->comp_suffix, COMPRESS_SUFFIX,SIZEOF(file->comp_suffix) - 1);
+           file->comp_suffix[SIZEOF(file->comp_suffix) - 1] = '\0';
        }
     } else {
        if (file->comp_suffix[0] == '\0') {
            file->compressed = 0;
-           assert(sizeof(file->comp_suffix) >= 2);
-           strcpy(file->comp_suffix, "N");
+           assert(SIZEOF(file->comp_suffix) >= 2);
+           strncpy(file->comp_suffix, "N", SIZEOF(file->comp_suffix) - 1);
+           file->comp_suffix[SIZEOF(file->comp_suffix) - 1] = '\0';
        } else {
            file->compressed = 1;
        }
@@ -865,27 +981,30 @@ finish_tapeheader(file)
     if (srvencrypt != ENCRYPT_NONE) {
       file->encrypted= 1;
       if (srvencrypt == ENCRYPT_SERV_CUST) {
-       snprintf(file->decrypt_cmd, sizeof(file->decrypt_cmd),
+       snprintf(file->decrypt_cmd, SIZEOF(file->decrypt_cmd),
                 " %s %s |", srv_encrypt, srv_decrypt_opt); 
-       strcpy(file->encrypt_suffix, "enc");
-       strncpy(file->srv_encrypt, srv_encrypt, sizeof(file->srv_encrypt));
-       file->srv_encrypt[sizeof(file->srv_encrypt)-1] = '\0';
-       strncpy(file->srv_decrypt_opt, srv_decrypt_opt, sizeof(file->srv_decrypt_opt));
-       file->srv_decrypt_opt[sizeof(file->srv_decrypt_opt)-1] = '\0';
+       strncpy(file->encrypt_suffix, "enc", SIZEOF(file->encrypt_suffix) - 1);
+       file->encrypt_suffix[SIZEOF(file->encrypt_suffix) - 1] = '\0';
+       strncpy(file->srv_encrypt, srv_encrypt, SIZEOF(file->srv_encrypt) - 1);
+       file->srv_encrypt[SIZEOF(file->srv_encrypt) - 1] = '\0';
+       strncpy(file->srv_decrypt_opt, srv_decrypt_opt, SIZEOF(file->srv_decrypt_opt) - 1);
+       file->srv_decrypt_opt[SIZEOF(file->srv_decrypt_opt) - 1] = '\0';
       } else if ( srvencrypt == ENCRYPT_CUST ) {
-       snprintf(file->decrypt_cmd, sizeof(file->decrypt_cmd),
+       snprintf(file->decrypt_cmd, SIZEOF(file->decrypt_cmd),
                 " %s %s |", clnt_encrypt, clnt_decrypt_opt);
-       strcpy(file->encrypt_suffix, "enc");
-       strncpy(file->clnt_encrypt, clnt_encrypt, sizeof(file->clnt_encrypt));
-       file->clnt_encrypt[sizeof(file->clnt_encrypt)-1] = '\0';
-       strncpy(file->clnt_decrypt_opt, clnt_decrypt_opt, sizeof(file->clnt_decrypt_opt));
-       file->clnt_decrypt_opt[sizeof(file->clnt_decrypt_opt)-1] = '\0';
+       strncpy(file->encrypt_suffix, "enc", SIZEOF(file->encrypt_suffix) - 1);
+       file->encrypt_suffix[SIZEOF(file->encrypt_suffix) - 1] = '\0';
+       strncpy(file->clnt_encrypt, clnt_encrypt, SIZEOF(file->clnt_encrypt) - 1);
+       file->clnt_encrypt[SIZEOF(file->clnt_encrypt) - 1] = '\0';
+       strncpy(file->clnt_decrypt_opt, clnt_decrypt_opt, SIZEOF(file->clnt_decrypt_opt));
+       file->clnt_decrypt_opt[SIZEOF(file->clnt_decrypt_opt) - 1] = '\0';
       }
     } else {
       if (file->encrypt_suffix[0] == '\0') {
        file->encrypted = 0;
-       assert(sizeof(file->encrypt_suffix) >= 2);
-       strcpy(file->encrypt_suffix, "N");
+       assert(SIZEOF(file->encrypt_suffix) >= 2);
+       strncpy(file->encrypt_suffix, "N", SIZEOF(file->encrypt_suffix) - 1);
+       file->encrypt_suffix[SIZEOF(file->encrypt_suffix) - 1] = '\0';
       } else {
        file->encrypted= 1;
       }
@@ -895,26 +1014,29 @@ finish_tapeheader(file)
 /*
  * Send an Amanda dump header to the output file.
  */
-static int
-write_tapeheader(outfd, file)
-    int outfd;
-    dumpfile_t *file;
+static ssize_t
+write_tapeheader(
+    int                outfd,
+    dumpfile_t *file)
 {
     char buffer[DISK_BLOCK_BYTES];
-    int written;
+    ssize_t written;
 
-    build_header(buffer, file, sizeof(buffer));
+    build_header(buffer, file, SIZEOF(buffer));
+
+    written = write(outfd, buffer, SIZEOF(buffer));
+    if(written == (ssize_t)sizeof(buffer))
+       return 0;
+    if(written < 0)
+       return written;
 
-    written = write(outfd, buffer, sizeof(buffer));
-    if(written == sizeof(buffer)) return 0;
-    if(written < 0) return written;
     errno = ENOSPC;
     return -1;
 }
 
 static int
-do_dump(db)
-    struct databuf *db;
+do_dump(
+    struct databuf *db)
 {
     char *indexfile_tmp = NULL;
     char *indexfile_real = NULL;
@@ -929,11 +1051,12 @@ do_dump(db)
 
     startclock();
 
-    dumpbytes = dumpsize = headersize = origsize = dump_result = 0;
     status = 0;
+    dump_result = 0;
+    dumpbytes = dumpsize = headersize = origsize = (off_t)0;
     fh_init(&file);
 
-    snprintf(level_str, sizeof(level_str), "%d", level);
+    snprintf(level_str, SIZEOF(level_str), "%d", level);
     fn = sanitise_filename(diskname);
     errfname = newvstralloc(errfname,
                            AMANDA_TMPDIR,
@@ -955,7 +1078,7 @@ do_dump(db)
     amfree(errfname);
 
     if (streams[INDEXFD].fd != NULL) {
-       indexfile_real = getindexfname(hostname, diskname, datestamp, level);
+       indexfile_real = getindexfname(hostname, diskname, dumper_timestamp, level);
        indexfile_tmp = stralloc2(indexfile_real, ".tmp");
 
        if (mkpdir(indexfile_tmp, 02755, (uid_t)-1, (gid_t)-1) == -1) {
@@ -992,6 +1115,7 @@ do_dump(db)
      * the header, we will start processing data too.
      */
     security_stream_read(streams[MESGFD].fd, read_mesgfd, db);
+    set_datafd = 0;
 
     /*
      * Setup a read timeout
@@ -1008,30 +1132,36 @@ do_dump(db)
        goto failed;
 
     runtime = stopclock();
-    dumptime = runtime.r.tv_sec + runtime.r.tv_usec/1000000.0;
+    dumptime = (double)(runtime.r.tv_sec) +
+              ((double)(runtime.r.tv_usec) / 1000000.0);
 
     dumpsize -= headersize;            /* don't count the header */
-    if (dumpsize < 0) dumpsize = 0;    /* XXX - maybe this should be fatal? */
+    if (dumpsize < (off_t)0)           /* XXX - maybe this should be fatal? */
+       dumpsize = (off_t)0;
 
     amfree(errstr);
     errstr = alloc(128);
-    snprintf(errstr, 128, "sec %s kb %ld kps %3.1f orig-kb %ld",
-       walltime_str(runtime), dumpsize,
-       dumptime ? dumpsize / dumptime : 0.0, origsize);
+    snprintf(errstr, 128, "sec %s kb " OFF_T_FMT " kps %3.1lf orig-kb " OFF_T_FMT "",
+       walltime_str(runtime),
+       (OFF_T_FMT_TYPE)dumpsize,
+       (isnormal(dumptime) ? ((double)dumpsize / (double)dumptime) : 0.0),
+       (OFF_T_FMT_TYPE)origsize);
     q = squotef("[%s]", errstr);
-    putresult(DONE, "%s %ld %ld %ld %s\n", handle, origsize, dumpsize,
-             (long)(dumptime+0.5), q);
+    putresult(DONE, "%s " OFF_T_FMT " " OFF_T_FMT " %lu %s\n", handle,
+               (OFF_T_FMT_TYPE)origsize,
+               (OFF_T_FMT_TYPE)dumpsize,
+               (unsigned long)((double)dumptime+0.5), q);
     amfree(q);
 
     switch(dump_result) {
     case 0:
-       log_add(L_SUCCESS, "%s %s %s %d [%s]", hostname, diskname, datestamp, level, errstr);
+       log_add(L_SUCCESS, "%s %s %s %d [%s]", hostname, qdiskname, dumper_timestamp, level, errstr);
 
        break;
 
     case 1:
        log_start_multiline();
-       log_add(L_STRANGE, "%s %s %d [%s]", hostname, diskname, level, errstr);
+       log_add(L_STRANGE, "%s %s %d [%s]", hostname, qdiskname, level, errstr);
        log_msgout(L_STRANGE);
        log_end_multiline();
 
@@ -1044,7 +1174,7 @@ do_dump(db)
     if (indexfile_tmp) {
        amwait_t index_status;
 
-       aclose(indexout);
+       /*@i@*/ aclose(indexout);
        waitpid(indexpid,&index_status,0);
        if (rename(indexfile_tmp, indexfile_real) != 0) {
            log_add(L_WARNING, "could not rename \"%s\" to \"%s\": %s",
@@ -1109,7 +1239,7 @@ failed:
     }
 
     log_start_multiline();
-    log_add(L_FAIL, "%s %s %s %d [%s]", hostname, diskname, datestamp,
+    log_add(L_FAIL, "%s %s %s %d [%s]", hostname, qdiskname, dumper_timestamp,
            level, errstr);
     if (errf) {
        log_msgout(L_FAIL);
@@ -1131,9 +1261,10 @@ failed:
  * Callback for reads on the mesgfd stream
  */
 static void
-read_mesgfd(cookie, buf, size)
-    void *cookie, *buf;
-    ssize_t size;
+read_mesgfd(
+    void *     cookie,
+    void *     buf,
+    ssize_t    size)
 {
     struct databuf *db = cookie;
 
@@ -1146,6 +1277,7 @@ read_mesgfd(cookie, buf, size)
        dump_result = 2;
        stop_dump();
        return;
+
     case 0:
        /*
         * EOF.  Just shut down the mesg stream.
@@ -1156,12 +1288,14 @@ read_mesgfd(cookie, buf, size)
        /*
         * If the data fd and index fd has also shut down, then we're done.
         */
-       if (streams[DATAFD].fd == NULL && streams[INDEXFD].fd == NULL)
+       if ((set_datafd == 0 || streams[DATAFD].fd == NULL) && 
+           streams[INDEXFD].fd == NULL)
            stop_dump();
        return;
+
     default:
        assert(buf != NULL);
-       add_msg_data(buf, size);
+       add_msg_data(buf, (size_t)size);
        security_stream_read(streams[MESGFD].fd, read_mesgfd, cookie);
        break;
     }
@@ -1182,8 +1316,8 @@ read_mesgfd(cookie, buf, size)
            stop_dump();
            return;
        }
-       dumpsize += DISK_BLOCK_KB;
-       headersize += DISK_BLOCK_KB;
+       dumpsize += (off_t)DISK_BLOCK_KB;
+       headersize += (off_t)DISK_BLOCK_KB;
 
        if (srvencrypt == ENCRYPT_SERV_CUST) {
            if (runencrypt(db->fd, &db->encryptpid, srvencrypt) < 0) {
@@ -1204,6 +1338,7 @@ read_mesgfd(cookie, buf, size)
            }
        }
        security_stream_read(streams[DATAFD].fd, read_datafd, db);
+       set_datafd = 1;
     }
 }
 
@@ -1211,9 +1346,10 @@ read_mesgfd(cookie, buf, size)
  * Callback for reads on the datafd stream
  */
 static void
-read_datafd(cookie, buf, size)
-    void *cookie, *buf;
-    ssize_t size;
+read_datafd(
+    void *     cookie,
+    void *     buf,
+    ssize_t    size)
 {
     struct databuf *db = cookie;
 
@@ -1243,8 +1379,8 @@ read_datafd(cookie, buf, size)
      */
     if (size == 0) {
        databuf_flush(db);
-       if (dumpbytes) {
-           dumpsize++;
+       if (dumpbytes != (off_t)0) {
+           dumpsize += (off_t)1;
        }
        security_stream_close(streams[DATAFD].fd);
        streams[DATAFD].fd = NULL;
@@ -1261,7 +1397,7 @@ read_datafd(cookie, buf, size)
      * more data.
      */
     assert(buf != NULL);
-    if (databuf_write(db, buf, size) < 0) {
+    if (databuf_write(db, buf, (size_t)size) < 0) {
        errstr = newstralloc2(errstr, "data write: ", strerror(errno));
        dump_result = 2;
        stop_dump();
@@ -1274,9 +1410,10 @@ read_datafd(cookie, buf, size)
  * Callback for reads on the index stream
  */
 static void
-read_indexfd(cookie, buf, size)
-    void *cookie, *buf;
-    ssize_t size;
+read_indexfd(
+    void *     cookie,
+    void *     buf,
+    ssize_t    size)
 {
     int fd;
 
@@ -1300,7 +1437,8 @@ read_indexfd(cookie, buf, size)
        /*
         * If the mesg fd has also shut down, then we're done.
         */
-       if (streams[DATAFD].fd == NULL && streams[MESGFD].fd == NULL)
+       if ((set_datafd == 0 || streams[DATAFD].fd == NULL) &&
+            streams[MESGFD].fd == NULL)
            stop_dump();
        return;
     }
@@ -1310,11 +1448,11 @@ read_indexfd(cookie, buf, size)
     /*
      * We ignore error while writing to the index file.
      */
-    if (fullwrite(fd, buf, size) < 0) {
+    if (fullwrite(fd, buf, (size_t)size) < 0) {
        /* Ignore error, but schedule another read. */
        if(indexfderror == 0) {
            indexfderror = 1;
-           log_add(L_INFO, "Index corrupted for %s:%s", hostname, diskname);
+           log_add(L_INFO, "Index corrupted for %s:%s", hostname, qdiskname);
        }
     }
     security_stream_read(streams[INDEXFD].fd, read_indexfd, cookie);
@@ -1325,8 +1463,8 @@ read_indexfd(cookie, buf, size)
  * then remove the timeout.
  */
 static void
-timeout(seconds)
-    int seconds;
+timeout(
+    time_t seconds)
 {
     static event_handle_t *ev_timeout = NULL;
 
@@ -1342,7 +1480,7 @@ timeout(seconds)
      * Now, schedule a new one if 'seconds' is greater than 0
      */
     if (seconds > 0)
-       ev_timeout = event_register(seconds, EV_TIME, timeout_callback, NULL);
+       ev_timeout = event_register((event_id_t)seconds, EV_TIME, timeout_callback, NULL);
 }
 
 /*
@@ -1350,9 +1488,11 @@ timeout(seconds)
  * have a data timeout.
  */
 static void
-timeout_callback(unused)
-    void *unused;
+timeout_callback(
+    void *     unused)
 {
+    (void)unused;      /* Quiet unused parameter warning */
+
     assert(unused == NULL);
     errstr = newstralloc(errstr, "data timeout");
     dump_result = 2;
@@ -1364,7 +1504,7 @@ timeout_callback(unused)
  * will exit.
  */
 static void
-stop_dump()
+stop_dump(void)
 {
     int i;
 
@@ -1385,10 +1525,10 @@ stop_dump()
  * process.
  */
 static int
-runcompress(outfd, pid, comptype)
-    int outfd;
-    pid_t *pid;
-    comp_t comptype;
+runcompress(
+    int                outfd,
+    pid_t *    pid,
+    comp_t     comptype)
 {
     int outpipe[2], rval;
 
@@ -1415,21 +1555,27 @@ runcompress(outfd, pid, comptype)
        aclose(outpipe[0]);
        return (rval);
     case 0:
-       if (dup2(outpipe[0], 0) < 0)
+       if (dup2(outpipe[0], 0) < 0) {
            error("err dup2 in: %s", strerror(errno));
-       if (dup2(outfd, 1) == -1)
+           /*NOTREACHED*/
+       }
+       if (dup2(outfd, 1) == -1) {
            error("err dup2 out: %s", strerror(errno));
+           /*NOTREACHED*/
+       }
        safe_fd(-1, 0);
        if (comptype != COMP_SERV_CUST) {
            execlp(COMPRESS_PATH, COMPRESS_PATH, (  comptype == COMP_BEST ?
-               COMPRESS_BEST_OPT : COMPRESS_FAST_OPT), NULL);
+               COMPRESS_BEST_OPT : COMPRESS_FAST_OPT), (char *)NULL);
            error("error: couldn't exec %s: %s", COMPRESS_PATH, strerror(errno));
+           /*NOTREACHED*/
        } else if (*srvcompprog) {
            execlp(srvcompprog, srvcompprog, (char *)0);
            error("error: couldn't exec server custom filter%s.\n", srvcompprog);
+           /*NOTREACHED*/
        }
     }
-    /* NOTREACHED */
+    /*NOTREACHED*/
     return (-1);
 }
 
@@ -1440,10 +1586,10 @@ runcompress(outfd, pid, comptype)
  * process.
  */
 static int
-runencrypt(outfd, pid, encrypttype)
-    int outfd;
-    pid_t *pid;
-    encrypt_t encrypttype;
+runencrypt(
+    int                outfd,
+    pid_t *    pid,
+    encrypt_t  encrypttype)
 {
     int outpipe[2], rval;
 
@@ -1470,17 +1616,22 @@ runencrypt(outfd, pid, encrypttype)
        aclose(outpipe[0]);
        return (rval);
     case 0:
-       if (dup2(outpipe[0], 0) < 0)
+       if (dup2(outpipe[0], 0) < 0) {
            error("err dup2 in: %s", strerror(errno));
-       if (dup2(outfd, 1) < 0 )
+           /*NOTREACHED*/
+       }
+       if (dup2(outfd, 1) < 0 ) {
            error("err dup2 out: %s", strerror(errno));
+           /*NOTREACHED*/
+       }
        safe_fd(-1, 0);
        if ((encrypttype == ENCRYPT_SERV_CUST) && *srv_encrypt) {
            execlp(srv_encrypt, srv_encrypt, (char *)0);
            error("error: couldn't exec server encryption%s.\n", srv_encrypt);
+           /*NOTREACHED*/
        }
     }
-    /* NOTREACHED */
+    /*NOTREACHED*/
     return (-1);
 }
 
@@ -1488,20 +1639,21 @@ runencrypt(outfd, pid, encrypttype)
 /* -------------------- */
 
 static void
-sendbackup_response(datap, pkt, sech)
-    void *datap;
-    pkt_t *pkt;
-    security_handle_t *sech;
+sendbackup_response(
+    void *             datap,
+    pkt_t *            pkt,
+    security_handle_t *        sech)
 {
     int ports[NSTREAMS], *response_error = datap, i;
     char *p;
     char *tok;
-    char *tok_end;
-    char *extra = NULL;
+    char *extra;
 
     assert(response_error != NULL);
     assert(sech != NULL);
 
+    security_close_connection(sech, hostname);
+
     if (pkt == NULL) {
        errstr = newvstralloc(errstr, "[request failed: ",
            security_geterror(sech), "]", NULL);
@@ -1509,6 +1661,8 @@ sendbackup_response(datap, pkt, sech)
        return;
     }
 
+    extra = NULL;
+    memset(ports, 0, SIZEOF(ports));
     if (pkt->type == P_NAK) {
 #if defined(PACKET_DEBUG)
        fprintf(stderr, "got nak response:\n----\n%s\n----\n\n", pkt->body);
@@ -1537,7 +1691,8 @@ bad_nak:
        return;
     }
 
-#if defined(PACKET_DEBUG)
+#if 1
+//#if defined(PACKET_DEBUG)
     fprintf(stderr, "got response:\n----\n%s\n----\n\n", pkt->body);
 #endif
 
@@ -1605,13 +1760,12 @@ bad_nak:
                extra = stralloc("OPTIONS token is missing");
                goto parse_error;
            }
-           tok_end = tok + strlen(tok);
 
            while((p = strchr(tok, ';')) != NULL) {
                *p++ = '\0';
 #define sc "features="
-               if(strncmp(tok, sc, sizeof(sc)-1) == 0) {
-                   tok += sizeof(sc) - 1;
+               if(strncmp(tok, sc, SIZEOF(sc) - 1) == 0) {
+                   tok += SIZEOF(sc) - 1;
 #undef sc
                    am_release_feature_set(their_features);
                    if((their_features = am_string_to_feature(tok)) == NULL) {
@@ -1684,6 +1838,7 @@ bad_nak:
 
     /* everything worked */
     *response_error = 0;
+    security_close_connection(sech, hostname);
     return;
 
 parse_error:
@@ -1694,28 +1849,72 @@ parse_error:
                          NULL);
     amfree(extra);
     *response_error = 2;
+    security_close_connection(sech, hostname);
     return;
 
 connect_error:
     stop_dump();
     *response_error = 1;
+    security_close_connection(sech, hostname);
+}
+
+static char *
+dumper_get_security_conf(
+    char *     string,
+    void *     arg)
+{
+        (void)arg;     /* Quiet unused parameter warning */
+
+        if(!string || !*string)
+                return(NULL);
+
+        if(strcmp(string, "krb5principal")==0) {
+                return(getconf_str(CNF_KRB5PRINCIPAL));
+        } else if(strcmp(string, "krb5keytab")==0) {
+                return(getconf_str(CNF_KRB5KEYTAB));
+        } else if(strcmp(string, "amandad_path")==0) {
+                return (amandad_path);
+        } else if(strcmp(string, "client_username")==0) {
+                return (client_username);
+        } else if(strcmp(string, "ssh_keys")==0) {
+                return (ssh_keys);
+        }
+        return(NULL);
 }
 
 static int
-startup_dump(hostname, disk, device, level, dumpdate, progname, options)
-    const char *hostname, *disk, *device, *dumpdate, *progname, *options;
-    int level;
+startup_dump(
+    const char *hostname,
+    const char *disk,
+    const char *device,
+    int                level,
+    const char *dumpdate,
+    const char *progname,
+    const char *amandad_path,
+    const char *client_username,
+    const char *ssh_keys,
+    const char *options)
 {
     char level_string[NUM_STR_SIZE];
     char *req = NULL;
-    char *authopt, *endauthopt, authoptbuf[64];
+    char *authopt, *endauthopt, authoptbuf[80];
     int response_error;
     const security_driver_t *secdrv;
     char *dumper_api;
+    int has_features;
+    int has_hostname;
+    int has_device;
+    int has_config;
+
+    (void)disk;                        /* Quiet unused parameter warning */
+    (void)amandad_path;                /* Quiet unused parameter warning */
+    (void)client_username;     /* Quiet unused parameter warning */
+    (void)ssh_keys;            /* Quiet unused parameter warning */
 
-    int has_features = am_has_feature(their_features, fe_req_options_features);
-    int has_hostname = am_has_feature(their_features, fe_req_options_hostname);
-    int has_device   = am_has_feature(their_features, fe_sendbackup_req_device);
+    has_features = am_has_feature(their_features, fe_req_options_features);
+    has_hostname = am_has_feature(their_features, fe_req_options_hostname);
+    has_config   = am_has_feature(their_features, fe_req_options_config);
+    has_device   = am_has_feature(their_features, fe_sendbackup_req_device);
 
     /*
      * Default to bsd authentication if none specified.  This is gross.
@@ -1723,18 +1922,23 @@ startup_dump(hostname, disk, device, level, dumpdate, progname, options)
      * Options really need to be pre-parsed into some sort of structure
      * much earlier, and then flattened out again before transmission.
      */
-    if ((authopt = strstr(options, "auth=")) == NULL
-       || (endauthopt = strchr(authopt, ';')) == NULL
-       || (sizeof(authoptbuf) - 1 < endauthopt - authopt)) {
+    authopt = strstr(options, "auth=");
+    if (authopt == NULL) {
        authopt = "BSD";
     } else {
-       authopt += strlen("auth=");
-       strncpy(authoptbuf, authopt, endauthopt - authopt);
-       authoptbuf[endauthopt - authopt] = '\0';
-       authopt = authoptbuf;
+       endauthopt = strchr(authopt, ';');
+       if ((endauthopt == NULL) ||
+         ((sizeof(authoptbuf) - 1) < (size_t)(endauthopt - authopt))) {
+           authopt = "BSD";
+       } else {
+           authopt += strlen("auth=");
+           strncpy(authoptbuf, authopt, (size_t)(endauthopt - authopt));
+           authoptbuf[endauthopt - authopt] = '\0';
+           authopt = authoptbuf;
+       }
     }
 
-    snprintf(level_string, sizeof(level_string), "%d", level);
+    snprintf(level_string, SIZEOF(level_string), "%d", level);
     if(strncmp(progname, "DUMP", 4) == 0
        || strncmp(progname, "GNUTAR", 6) == 0) {
        dumper_api = "";
@@ -1749,9 +1953,12 @@ startup_dump(hostname, disk, device, level, dumpdate, progname, options)
                    has_hostname ? "hostname=" : "",
                    has_hostname ? hostname : "",
                    has_hostname ? ";" : "",
+                   has_config   ? "config=" : "",
+                   has_config   ? config_name : "",
+                   has_config   ? ";" : "",
                    "\n",
                    dumper_api, progname,
-                   " ", disk,
+                   " ", qdiskname,
                    " ", device && has_device ? device : "",
                    " ", level_string,
                    " ", dumpdate,
@@ -1761,13 +1968,15 @@ startup_dump(hostname, disk, device, level, dumpdate, progname, options)
                    "\n",
                    NULL);
 
+fprintf(stderr, "send request:\n----\n%s\n----\n\n", req);
     secdrv = security_getdriver(authopt);
     if (secdrv == NULL) {
        error("no '%s' security driver available for host '%s'",
            authopt, hostname);
+       /*NOTREACHED*/
     }
 
-    protocol_sendreq(hostname, secdrv, generic_get_security_conf, req,
+    protocol_sendreq(hostname, secdrv, dumper_get_security_conf, req,
        STARTUP_TIMEOUT, sendbackup_response, &response_error);
 
     amfree(req);
index 2f8c950f062b68bdbd84069911f6ad0cb3087463..5a9310f6bb1211f8958f289ab1f1d84987d19a43 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: find.c,v 1.23 2006/01/15 21:01:00 martinea Exp $
+ * $Id: find.c,v 1.33 2006/07/06 13:13:15 martinea Exp $
  *
  * controlling process for the Amanda backup system
  */
 #include "holding.h"
 #include "find.h"
 
-void find P((int argc, char **argv));
-int find_match P((char *host, char *disk));
-int search_logfile P((find_result_t **output_find, char *label, int datestamp, int datestamp_aux, char *logfile));
-void search_holding_disk P((find_result_t **output_find));
-void strip_failed_chunks P((find_result_t *output_find));
-char *find_nicedate P((int datestamp));
-static int find_compare P((const void *, const void *));
-static int parse_taper_datestamp_log P((char *, int *, char **));
+int find_match(char *host, char *disk);
+int search_logfile(find_result_t **output_find, char *label, char *datestamp, char *logfile);
+void search_holding_disk(find_result_t **output_find);
+void strip_failed_chunks(find_result_t **output_find);
+char *find_nicedate(char *datestamp);
+static int find_compare(const void *, const void *);
+static int parse_taper_datestamp_log(char *logline, char **datestamp, char **level);
+static int seen_chunk_of(find_result_t *output_find, char *date, char *host, char *disk, int level);
 
 static char *find_sort_order = NULL;
 int dynamic_disklist = 0;
 disklist_t* find_diskqp = NULL;
 
-find_result_t *find_dump(dyna_disklist, diskqp)
-int dyna_disklist;
-disklist_t* diskqp;
+find_result_t *
+find_dump(
+    int dyna_disklist,
+    disklist_t* diskqp)
 {
     char *conf_logdir, *logfile = NULL;
-    int tape, maxtape, seq, logs;
+    int tape, maxtape, logs;
+    unsigned seq;
     tape_t *tp;
     find_result_t *output_find = NULL;
 
@@ -69,11 +71,9 @@ disklist_t* diskqp;
     maxtape = lookup_nb_tape();
 
     for(tape = 1; tape <= maxtape; tape++) {
-       char ds_str[NUM_STR_SIZE];
 
        tp = lookup_tapepos(tape);
        if(tp == NULL) continue;
-       snprintf(ds_str, sizeof(ds_str), "%d", tp->datestamp);
 
        /* search log files */
 
@@ -84,28 +84,28 @@ disklist_t* diskqp;
        for(seq = 0; 1; seq++) {
            char seq_str[NUM_STR_SIZE];
 
-           snprintf(seq_str, sizeof(seq_str), "%d", seq);
+           snprintf(seq_str, SIZEOF(seq_str), "%u", seq);
            logfile = newvstralloc(logfile,
-                       conf_logdir, "/log.", ds_str, ".", seq_str, NULL);
+                       conf_logdir, "/log.", tp->datestamp, ".", seq_str, NULL);
            if(access(logfile, R_OK) != 0) break;
-           logs += search_logfile(&output_find, tp->label, tp->datestamp, seq, logfile);
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
        }
 
        /* search old-style amflush log, if any */
 
        logfile = newvstralloc(logfile,
-                              conf_logdir, "/log.", ds_str, ".amflush", NULL);
+                              conf_logdir, "/log.", tp->datestamp, ".amflush", NULL);
        if(access(logfile,R_OK) == 0) {
-           logs += search_logfile(&output_find, tp->label, tp->datestamp, 1000, logfile);
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
        }
 
        /* search old-style main log, if any */
 
-       logfile = newvstralloc(logfile, conf_logdir, "/log.", ds_str, NULL);
+       logfile = newvstralloc(logfile, conf_logdir, "/log.", tp->datestamp, NULL);
        if(access(logfile,R_OK) == 0) {
-           logs += search_logfile(&output_find, tp->label, tp->datestamp, -1, logfile);
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
        }
-       if(logs == 0 && tp->datestamp != 0)
+       if(logs == 0 && strcmp(tp->datestamp,"0") != 0)
            printf("Warning: no log files found for tape %s written %s\n",
                   tp->label, find_nicedate(tp->datestamp));
     }
@@ -114,15 +114,17 @@ disklist_t* diskqp;
 
     search_holding_disk(&output_find);
 
-    strip_failed_chunks(output_find);
+    strip_failed_chunks(&output_find);
     
     return(output_find);
 }
 
-char **find_log()
+char **
+find_log(void)
 {
     char *conf_logdir, *logfile = NULL;
-    int tape, maxtape, seq, logs;
+    int tape, maxtape, logs;
+    unsigned seq;
     tape_t *tp;
     char **output_find_log = NULL;
     char **current_log;
@@ -135,15 +137,13 @@ char **find_log()
     }
     maxtape = lookup_nb_tape();
 
-    output_find_log = alloc((maxtape*5+10) * sizeof(char *));
+    output_find_log = alloc((maxtape*5+10) * SIZEOF(char *));
     current_log = output_find_log;
 
     for(tape = 1; tape <= maxtape; tape++) {
-       char ds_str[NUM_STR_SIZE];
 
        tp = lookup_tapepos(tape);
        if(tp == NULL) continue;
-       snprintf(ds_str, sizeof(ds_str), "%d", tp->datestamp);
 
        /* search log files */
 
@@ -154,12 +154,12 @@ char **find_log()
        for(seq = 0; 1; seq++) {
            char seq_str[NUM_STR_SIZE];
 
-           snprintf(seq_str, sizeof(seq_str), "%d", seq);
+           snprintf(seq_str, SIZEOF(seq_str), "%u", seq);
            logfile = newvstralloc(logfile,
-                       conf_logdir, "/log.", ds_str, ".", seq_str, NULL);
+                       conf_logdir, "/log.", tp->datestamp, ".", seq_str, NULL);
            if(access(logfile, R_OK) != 0) break;
-           if( search_logfile(NULL, tp->label, tp->datestamp, seq, logfile)) {
-               *current_log = vstralloc("log.", ds_str, ".", seq_str, NULL);
+           if( search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+               *current_log = vstralloc("log.", tp->datestamp, ".", seq_str, NULL);
                current_log++;
                logs++;
                break;
@@ -169,10 +169,10 @@ char **find_log()
        /* search old-style amflush log, if any */
 
        logfile = newvstralloc(logfile,
-                              conf_logdir, "/log.", ds_str, ".amflush", NULL);
+                              conf_logdir, "/log.", tp->datestamp, ".amflush", NULL);
        if(access(logfile,R_OK) == 0) {
-           if( search_logfile(NULL, tp->label, tp->datestamp, 1000, logfile)) {
-               *current_log = vstralloc("log.", ds_str, ".amflush", NULL);
+           if( search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+               *current_log = vstralloc("log.", tp->datestamp, ".amflush", NULL);
                current_log++;
                logs++;
            }
@@ -180,15 +180,15 @@ char **find_log()
 
        /* search old-style main log, if any */
 
-       logfile = newvstralloc(logfile, conf_logdir, "/log.", ds_str, NULL);
+       logfile = newvstralloc(logfile, conf_logdir, "/log.", tp->datestamp, NULL);
        if(access(logfile,R_OK) == 0) {
-           if(search_logfile(NULL, tp->label, tp->datestamp, -1, logfile)) {
-               *current_log = vstralloc("log.", ds_str, NULL);
+           if(search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+               *current_log = vstralloc("log.", tp->datestamp, NULL);
                current_log++;
                logs++;
            }
        }
-       if(logs == 0 && tp->datestamp != 0)
+       if(logs == 0 && strcmp(tp->datestamp,"0") != 0)
            printf("Warning: no log files found for tape %s written %s\n",
                   tp->label, find_nicedate(tp->datestamp));
     }
@@ -201,21 +201,21 @@ char **find_log()
 /*
  * Remove CHUNK entries from dumps that ultimately failed from our report.
  */
-void strip_failed_chunks(output_find)
-find_result_t *output_find;
+void strip_failed_chunks(
+    find_result_t **output_find)
 {
     find_result_t *cur, *prev = NULL, *failed = NULL, *failures = NULL;
 
     /* Generate a list of failures */
-    for(cur=output_find; cur; cur=cur->next) {
-       if(!cur->hostname || !cur->diskname) continue;
+    for(cur=*output_find; cur; cur=cur->next) {
+       if(!cur->hostname  || !cur->diskname ||
+          !cur->timestamp || !cur->label)
+           continue;
 
        if(strcmp(cur->status, "OK")){
-           failed = alloc(sizeof(find_result_t));
-           memcpy(failed, cur, sizeof(find_result_t));
+           failed = alloc(SIZEOF(find_result_t));
+           memcpy(failed, cur, SIZEOF(find_result_t));
            failed->next = failures;
-           failed->diskname = stralloc(cur->diskname);
-           failed->hostname = stralloc(cur->hostname);
            failures = failed;
        }
     }
@@ -223,45 +223,54 @@ find_result_t *output_find;
     /* Now if a CHUNK matches the parameters of a failed dump, remove it */
     for(failed=failures; failed; failed=failed->next) {
        prev = NULL;
-       for(cur=output_find; cur; cur=cur->next) {
-           if(!cur->hostname || !cur->diskname ||
-                 !strcmp(cur->partnum, "--") || strcmp(cur->status, "OK")){
+       cur = *output_find;
+       while (cur != NULL) {
+           find_result_t *next = cur->next;
+           if(!cur->hostname  || !cur->diskname || 
+              !cur->timestamp || !cur->label    || !cur->partnum ||
+              !strcmp(cur->partnum, "--") || strcmp(cur->status, "OK")) {
                prev = cur;
-               continue;
+               cur = next;
            }
-
-           if(!strcmp(cur->hostname, failed->hostname) &&
+           else if(!strcmp(cur->hostname, failed->hostname) &&
                 !strcmp(cur->diskname, failed->diskname) &&
-                cur->datestamp == failed->datestamp &&
-                cur->datestamp_aux == failed->datestamp_aux &&
+                !strcmp(cur->timestamp, failed->timestamp) &&
+                !strcmp(cur->label, failed->label) &&
                 cur->level == failed->level){
-               find_result_t *next = cur->next;
                amfree(cur->diskname);
                amfree(cur->hostname);
-               next = cur->next;
-               amfree(cur);
-               if(prev){
+               amfree(cur->label);
+               amfree(cur->timestamp);
+               amfree(cur->partnum);
+               amfree(cur->status);
+               cur = next;
+               if (prev) {
+                   amfree(prev->next);
                    prev->next = next;
-                   cur = prev;
+               } else {
+                   amfree(*output_find);
+                   *output_find = next;
                }
-               else output_find = next;
            }
-            else prev = cur;
+            else {
+               prev = cur;
+               cur = next;
+           }
+
        }
     }
 
     for(failed=failures; failed;) {
        find_result_t *fai = failed->next;
-       amfree(failed->diskname);
-       amfree(failed->hostname);
        fai = failed->next;
        amfree(failed);
        failed=fai;
     }
 }
 
-void search_holding_disk(output_find)
-find_result_t **output_find;
+void
+search_holding_disk(
+    find_result_t **output_find)
 {
     holdingdisk_t *hdisk;
     sl_t  *holding_list;
@@ -272,15 +281,19 @@ find_result_t **output_find;
     char *diskname = NULL;
     DIR *workdir;
     struct dirent *entry;
-    int level;
+    int level = 0;
     disk_t *dp;
+    int fd;
+    ssize_t result;
+    char buf[DISK_BLOCK_BYTES];
+    dumpfile_t file;
 
     holding_list = pick_all_datestamp(1);
 
     for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next) {
        for(dir = holding_list->first; dir != NULL; dir = dir->next) {
            sdirname = newvstralloc(sdirname,
-                                   hdisk->diskdir, "/", dir->name,
+                                   holdingdisk_get_diskdir(hdisk), "/", dir->name,
                                    NULL);
            if((workdir = opendir(sdirname)) == NULL) {
                continue;
@@ -303,6 +316,21 @@ find_result_t **output_find;
                }
                if(level < 0 || level > 9)
                    continue;
+               if ((fd = open(destname, O_RDONLY)) == -1) {
+                   continue;
+               }
+               if((result = read(fd, &buf, DISK_BLOCK_BYTES)) <= 0) {
+                   continue;
+               }
+               close(fd);
+
+               parse_file_header(buf, &file, (size_t)result);
+               if (strcmp(file.name, hostname) != 0 ||
+                   strcmp(file.disk, diskname) != 0 ||
+                   file.dumplevel != level ||
+                   !match_datestamp(file.datestamp, dir->name)) {
+                   continue;
+               }
 
                dp = NULL;
                for(;;) {
@@ -319,23 +347,9 @@ find_result_t **output_find;
 
                if(find_match(hostname,diskname)) {
                    find_result_t *new_output_find =
-                       alloc(sizeof(find_result_t));
+                       alloc(SIZEOF(find_result_t));
                    new_output_find->next=*output_find;
-                   if(strlen(dir->name) == 8) {
-                       new_output_find->datestamp=atoi(dir->name);
-                       new_output_find->timestamp=stralloc2(dir->name, "000000");
-                   }
-                   else if(strlen(dir->name) == 14) {
-                       char *name = stralloc(dir->name);
-                       name[8] = '\0';
-                       new_output_find->datestamp=atoi(name);
-                       new_output_find->timestamp=stralloc(dir->name);
-                       amfree(name);
-                   }
-                   else {
-                       error("Bad date\n");
-                   }
-                   new_output_find->datestamp_aux=1001;
+                   new_output_find->timestamp=stralloc(file.datestamp);
                    new_output_find->hostname=hostname;
                    hostname = NULL;
                    new_output_find->diskname=diskname;
@@ -359,16 +373,17 @@ find_result_t **output_find;
     amfree(diskname);
 }
 
-static int find_compare(i1, j1)
-const void *i1;
-const void *j1;
+static int
+find_compare(
+    const void *i1,
+    const void *j1)
 {
     int compare=0;
     find_result_t **i = (find_result_t **)i1;
     find_result_t **j = (find_result_t **)j1;
 
-    int nb_compare=strlen(find_sort_order);
-    int k;
+    size_t nb_compare=strlen(find_sort_order);
+    size_t k;
 
     for(k=0;k<nb_compare;k++) {
        switch (find_sort_order[k]) {
@@ -380,19 +395,17 @@ const void *j1;
                   break;
        case 'K' : compare=strcmp((*j)->diskname,(*i)->diskname);
                   break;
-       case 'd' : compare=(*i)->datestamp - (*j)->datestamp;
-                  if (compare == 0)
-                       compare = (*i)->datestamp_aux - (*j)->datestamp_aux;
+       case 'd' : compare=strcmp((*i)->timestamp,(*j)->timestamp);
                   break;
-       case 'D' : compare=(*j)->datestamp - (*i)->datestamp;
-                  if (compare == 0)
-                       compare = (*j)->datestamp_aux - (*i)->datestamp_aux;
+       case 'D' : compare=strcmp((*j)->timestamp,(*i)->timestamp);
                   break;
        case 'l' : compare=(*j)->level - (*i)->level;
                   break;
-       case 'f' : compare=(*i)->filenum - (*j)->filenum;
+       case 'f' : compare=((*i)->filenum == (*j)->filenum) ? 0 :
+                          (((*i)->filenum < (*j)->filenum) ? -1 : 1);
                   break;
-       case 'F' : compare=(*j)->filenum - (*i)->filenum;
+       case 'F' : compare=((*j)->filenum == (*i)->filenum) ? 0 :
+                          (((*j)->filenum < (*i)->filenum) ? -1 : 1);
                   break;
        case 'L' : compare=(*i)->level - (*j)->level;
                   break;
@@ -421,14 +434,15 @@ const void *j1;
     return 0;
 }
 
-void sort_find_result(sort_order, output_find)
-char *sort_order;
-find_result_t **output_find;
+void
+sort_find_result(
+    char *sort_order,
+    find_result_t **output_find)
 {
     find_result_t *output_find_result;
     find_result_t **array_find_result = NULL;
-    int nb_result=0;
-    int no_result;
+    size_t nb_result=0;
+    size_t no_result;
 
     find_sort_order = sort_order;
     /* qsort core dump if nothing to sort */
@@ -443,7 +457,7 @@ find_result_t **output_find;
     }
 
     /* put the list in an array */
-    array_find_result=alloc(nb_result * sizeof(find_result_t *));
+    array_find_result=alloc(nb_result * SIZEOF(find_result_t *));
     for(output_find_result=*output_find,no_result=0;
        output_find_result;
        output_find_result=output_find_result->next,no_result++) {
@@ -451,7 +465,7 @@ find_result_t **output_find;
     }
 
     /* sort the array */
-    qsort(array_find_result,nb_result,sizeof(find_result_t *),
+    qsort(array_find_result,nb_result,SIZEOF(find_result_t *),
          find_compare);
 
     /* put the sorted result in the list */
@@ -464,8 +478,9 @@ find_result_t **output_find;
     amfree(array_find_result);
 }
 
-void print_find_result(output_find)
-find_result_t *output_find;
+void
+print_find_result(
+    find_result_t *output_find)
 {
     find_result_t *output_find_result;
     int max_len_datestamp = 4;
@@ -476,29 +491,35 @@ find_result_t *output_find;
     int max_len_filenum   = 4;
     int max_len_part      = 4;
     int max_len_status    = 6;
-    int len;
+    size_t len;
 
     for(output_find_result=output_find;
        output_find_result;
        output_find_result=output_find_result->next) {
 
-       len=strlen(find_nicedate(output_find_result->datestamp));
-       if(len>max_len_datestamp) max_len_datestamp=len;
+       len=strlen(find_nicedate(output_find_result->timestamp));
+       if((int)len > max_len_datestamp)
+           max_len_datestamp=(int)len;
 
        len=strlen(output_find_result->hostname);
-       if(len>max_len_hostname) max_len_hostname=len;
+       if((int)len > max_len_hostname)
+           max_len_hostname = (int)len;
 
        len=strlen(output_find_result->diskname);
-       if(len>max_len_diskname) max_len_diskname=len;
+       if((int)len > max_len_diskname)
+           max_len_diskname = (int)len;
 
        len=strlen(output_find_result->label);
-       if(len>max_len_label) max_len_label=len;
+       if((int)len > max_len_label)
+           max_len_label = (int)len;
 
        len=strlen(output_find_result->status);
-       if(len>max_len_status) max_len_status=len;
+       if((int)len > max_len_status)
+           max_len_status = (int)len;
 
        len=strlen(output_find_result->partnum);
-       if(len>max_len_part) max_len_part=len;
+       if((int)len > max_len_part)
+           max_len_part = (int)len;
     }
 
     /*
@@ -523,24 +544,30 @@ find_result_t *output_find;
         for(output_find_result=output_find;
                output_find_result;
                output_find_result=output_find_result->next) {
+           char *qdiskname;
 
-           printf("%-*s %-*s %-*s %*d %-*s %*d %*s %-*s\n",
+           qdiskname = quote_string(output_find_result->diskname);
+           /*@ignore@*/
+           printf("%-*s %-*s %-*s %*d %-*s %*" OFF_T_RFMT " %*s %-*s\n",
                    max_len_datestamp, 
-                       find_nicedate(output_find_result->datestamp),
+                       find_nicedate(output_find_result->timestamp),
                    max_len_hostname,  output_find_result->hostname,
-                   max_len_diskname,  output_find_result->diskname,
+                   max_len_diskname,  qdiskname,
                    max_len_level,     output_find_result->level,
                    max_len_label,     output_find_result->label,
-                   max_len_filenum,   output_find_result->filenum,
+                   max_len_filenum,   (OFF_T_FMT_TYPE)output_find_result->filenum,
                    max_len_part,      output_find_result->partnum,
                    max_len_status,    output_find_result->status
                    );
+           /*@end@*/
+           amfree(qdiskname);
        }
     }
 }
 
-void free_find_result(output_find)
-find_result_t **output_find;
+void
+free_find_result(
+    find_result_t **output_find)
 {
     find_result_t *output_find_result, *prev;
 
@@ -548,7 +575,8 @@ find_result_t **output_find;
     for(output_find_result=*output_find;
            output_find_result;
            output_find_result=output_find_result->next) {
-       if(prev != NULL) amfree(prev);
+       amfree(prev);
+       amfree(output_find_result->timestamp);
        amfree(output_find_result->hostname);
        amfree(output_find_result->diskname);
        amfree(output_find_result->label);
@@ -557,36 +585,60 @@ find_result_t **output_find;
        amfree(output_find_result->timestamp);
        prev = output_find_result;
     }
-    if(prev != NULL) amfree(prev);
-    output_find = NULL;
+    amfree(prev);
+    *output_find = NULL;
 }
 
-int find_match(host, disk)
-char *host, *disk;
+int
+find_match(
+    char *host,
+    char *disk)
 {
     disk_t *dp = lookup_disk(host,disk);
     return (dp && dp->todo);
 }
 
-char *find_nicedate(datestamp)
-int datestamp;
+char *
+find_nicedate(
+    char *datestamp)
 {
     static char nice[20];
     int year, month, day;
-
-    year  = datestamp / 10000;
-    month = (datestamp / 100) % 100;
-    day   = datestamp % 100;
-
-    snprintf(nice, sizeof(nice), "%4d-%02d-%02d", year, month, day);
+    int hours, minutes, seconds;
+    char date[9], atime[7];
+    int  numdate, numtime;
+
+    strncpy(date, datestamp, 8);
+    date[8] = '\0';
+    numdate = atoi(date);
+    year  = numdate / 10000;
+    month = (numdate / 100) % 100;
+    day   = numdate % 100;
+
+    if(strlen(datestamp) <= 8) {
+       snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d",
+               year, month, day);
+    }
+    else {
+       strncpy(atime, &(datestamp[8]), 6);
+       atime[6] = '\0';
+       numtime = atoi(atime);
+       hours = numtime / 10000;
+       minutes = (numtime / 100) % 100;
+       seconds = numtime % 100;
+
+       snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d %02d:%02d:%02d",
+               year, month, day, hours, minutes, seconds);
+    }
 
     return nice;
 }
 
-static int parse_taper_datestamp_log(logline, datestamp, label)
-char *logline;
-int *datestamp;
-char **label;
+static int
+parse_taper_datestamp_log(
+    char *logline,
+    char **datestamp,
+    char **label)
 {
     char *s;
     int ch;
@@ -599,28 +651,30 @@ char **label;
        return 0;
     }
 #define sc "datestamp"
-    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+    if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
        return 0;
     }
-    s += sizeof(sc)-1;
+    s += SIZEOF(sc)-1;
     ch = s[-1];
 #undef sc
 
     skip_whitespace(s, ch);
-    if(ch == '\0' || sscanf(s - 1, "%d", datestamp) != 1) {
+    if(ch == '\0') {
        return 0;
     }
-    skip_integer(s, ch);
+    *datestamp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
        return 0;
     }
 #define sc "label"
-    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+    if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
        return 0;
     }
-    s += sizeof(sc)-1;
+    s += SIZEOF(sc)-1;
     ch = s[-1];
 #undef sc
 
@@ -640,10 +694,13 @@ char **label;
  * This is so we can interpret the final SUCCESS entry for a split dump as 
  * 'list its parts' instead.  Return 1 if we have, 0 if not.
  */
-int seen_chunk_of(output_find, date, host, disk, level)
-find_result_t *output_find;
-int date, level;
-char *host, *disk;
+int
+seen_chunk_of(
+    find_result_t *output_find,
+    char *date,
+    char *host,
+    char *disk,
+    int level)
 {
     find_result_t *cur;
 
@@ -652,7 +709,7 @@ char *host, *disk;
     for(cur=output_find; cur; cur=cur->next) {
        if(atoi(cur->partnum) < 1 || !cur->hostname || !cur->diskname) continue;
 
-       if(cur->datestamp == date && strcmp(cur->hostname, host) == 0 &&
+       if(strcmp(cur->timestamp, date) == 0 && strcmp(cur->hostname, host) == 0 &&
                strcmp(cur->diskname, disk) == 0 && cur->level == level){
            return(1);
        }
@@ -666,26 +723,33 @@ char *host, *disk;
 /* else                                                                */
 /*     add to output_find all the dump for this label          */
 /*     return the number of dump added.                        */
-int search_logfile(output_find, label, datestamp, datestamp_aux, logfile)
-find_result_t **output_find;
-char *label, *logfile;
-int datestamp, datestamp_aux;
+int
+search_logfile(
+    find_result_t **output_find,
+    char *label,
+    char *datestamp,
+    char *logfile)
 {
     FILE *logf;
     char *host, *host_undo;
-    char *disk, *disk_undo;
+    char *disk, *qdisk, *disk_undo;
+    char *date, *date_undo;
     char *partnum=NULL, *partnum_undo;
-    int   datestampI;
     char *rest;
-    char *ck_label;
-    int level, filenum, ck_datestamp, tapematch;
-    int passlabel, ck_datestamp2;
+    char *ck_label=NULL;
+    int level = 0; 
+    int tapematch;
+    off_t filenum;
+    int passlabel;
+    char *ck_datestamp, *ck_datestamp2;
     char *s;
     int ch;
     disk_t *dp;
 
-    if((logf = fopen(logfile, "r")) == NULL)
+    if((logf = fopen(logfile, "r")) == NULL) {
        error("could not open logfile %s: %s", logfile, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     /* check that this log file corresponds to the right tape */
     tapematch = 0;
@@ -693,8 +757,9 @@ int datestamp, datestamp_aux;
        if(curlog == L_START && curprog == P_TAPER) {
            if(parse_taper_datestamp_log(curstr,
                                         &ck_datestamp, &ck_label) == 0) {
-               printf("strange log line \"start taper %s\"\n", curstr);
-           } else if(ck_datestamp == datestamp
+               printf("strange log line \"start taper %s\" curstr='%s'\n",
+                   logfile, curstr);
+           } else if(strcmp(ck_datestamp, datestamp) == 0
                      && strcmp(ck_label, label) == 0) {
                tapematch = 1;
            }
@@ -714,7 +779,7 @@ int datestamp, datestamp_aux;
        return 0;
     }
 
-    filenum = 0;
+    filenum = (off_t)0;
     passlabel = 1;
     while(get_logline(logf) && passlabel) {
        if((curlog == L_SUCCESS || curlog == L_CHUNK) &&
@@ -724,7 +789,8 @@ int datestamp, datestamp_aux;
        if(curlog == L_START && curprog == P_TAPER) {
            if(parse_taper_datestamp_log(curstr,
                                         &ck_datestamp2, &ck_label) == 0) {
-               printf("strange log line \"start taper %s\"\n", curstr);
+               printf("strange log line in %s \"start taper %s\"\n",
+                   logfile, curstr);
            } else if (strcmp(ck_label, label)) {
                passlabel = !passlabel;
            }
@@ -736,7 +802,8 @@ int datestamp, datestamp_aux;
 
            skip_whitespace(s, ch);
            if(ch == '\0') {
-               printf("strange log line \"%s\"\n", curstr);
+               printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                continue;
            }
            host = s - 1;
@@ -746,24 +813,30 @@ int datestamp, datestamp_aux;
 
            skip_whitespace(s, ch);
            if(ch == '\0') {
-               printf("strange log line \"%s\"\n", curstr);
+               printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                continue;
            }
-           disk = s - 1;
-           skip_non_whitespace(s, ch);
+           qdisk = s - 1;
+           skip_quoted_string(s, ch);
            disk_undo = s - 1;
            *disk_undo = '\0';
+           disk = unquote_string(qdisk);
 
            skip_whitespace(s, ch);
-           if(ch == '\0' || sscanf(s - 1, "%d", &datestampI) != 1) {
-               printf("strange log line \"%s\"\n", curstr);
+           if(ch == '\0') {
+               printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                continue;
            }
-           skip_integer(s, ch);
+           date = s - 1;
+           skip_non_whitespace(s, ch);
+           date_undo = s - 1;
+           *date_undo = '\0';
 
-           if(datestampI < 100)  { /* old log didn't have datestamp */
-               level = datestampI;
-               datestampI = datestamp;
+           if(strlen(date) < 3) { /* old log didn't have datestamp */
+               level = atoi(date);
+               date = stralloc(datestamp);
            }
            else {
                if(curlog == L_CHUNK){
@@ -775,7 +848,8 @@ int datestamp, datestamp_aux;
                }
                skip_whitespace(s, ch);
                if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
-                   printf("strange log line \"%s\"\n", curstr);
+                   printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                    continue;
                }
                skip_integer(s, ch);
@@ -783,7 +857,8 @@ int datestamp, datestamp_aux;
 
            skip_whitespace(s, ch);
            if(ch == '\0') {
-               printf("strange log line \"%s\"\n", curstr);
+               printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                continue;
            }
            rest = s - 1;
@@ -800,15 +875,12 @@ int datestamp, datestamp_aux;
                enqueue_disk(find_diskqp, dp);
            }
             if(find_match(host, disk) && (curlog != L_SUCCESS ||
-               !seen_chunk_of(*output_find,datestampI,host,disk,level))){
+               !seen_chunk_of(*output_find, date, host, disk, level))) {
                if(curprog == P_TAPER) {
                    find_result_t *new_output_find =
-                       (find_result_t *)alloc(sizeof(find_result_t));
+                       (find_result_t *)alloc(SIZEOF(find_result_t));
                    new_output_find->next=*output_find;
-                   new_output_find->datestamp=datestampI;
-                   new_output_find->timestamp = alloc(15);
-                   snprintf(new_output_find->timestamp, 15, "%d000000", datestampI);
-                   new_output_find->datestamp_aux=datestamp_aux;
+                   new_output_find->timestamp = stralloc(date);
                    new_output_find->hostname=stralloc(host);
                    new_output_find->diskname=stralloc(disk);
                    new_output_find->level=level;
@@ -823,12 +895,9 @@ int datestamp, datestamp_aux;
                }
                else if(curlog == L_FAIL) {     /* print other failures too */
                    find_result_t *new_output_find =
-                       (find_result_t *)alloc(sizeof(find_result_t));
+                       (find_result_t *)alloc(SIZEOF(find_result_t));
                    new_output_find->next=*output_find;
-                   new_output_find->datestamp=datestamp;
-                   new_output_find->datestamp_aux=datestamp_aux;
-                   new_output_find->timestamp = alloc(15);
-                   snprintf(new_output_find->timestamp, 15, "%d000000", datestamp);
+                   new_output_find->timestamp = stralloc(date);
                    new_output_find->hostname=stralloc(host);
                    new_output_find->diskname=stralloc(disk);
                    new_output_find->level=level;
@@ -844,6 +913,7 @@ int datestamp, datestamp_aux;
                    *output_find=new_output_find;
                }
            }
+           amfree(disk);
        }
     }
     afclose(logf);
@@ -856,13 +926,14 @@ int datestamp, datestamp_aux;
  * an empty pattern to match .*, though).  If 'ok' is true, will only match
  * dumps with SUCCESS status.
  */
-find_result_t *dumps_match(output_find,hostname,diskname,datestamp,level,ok)
-find_result_t *output_find;
-char *hostname;
-char *diskname;
-char *datestamp;
-char *level;
-int ok;
+find_result_t *
+dumps_match(
+    find_result_t *output_find,
+    char *hostname,
+    char *diskname,
+    char *datestamp,
+    char *level,
+    int ok)
 {
     find_result_t *cur_result;
     find_result_t *matches = NULL;
@@ -870,18 +941,16 @@ int ok;
     for(cur_result=output_find;
        cur_result;
        cur_result=cur_result->next) {
-       char date_str[NUM_STR_SIZE];
        char level_str[NUM_STR_SIZE];
-       snprintf(date_str, sizeof(date_str), "%d", cur_result->datestamp);
-       snprintf(level_str, sizeof(level_str), "%d", cur_result->level);
+       snprintf(level_str, SIZEOF(level_str), "%d", cur_result->level);
        if((*hostname == '\0' || match_host(hostname, cur_result->hostname)) &&
           (*diskname == '\0' || match_disk(diskname, cur_result->diskname)) &&
-          (*datestamp== '\0' || match_datestamp(datestamp, date_str)) &&
+          (*datestamp== '\0' || match_datestamp(datestamp, cur_result->timestamp)) &&
           (*level== '\0' || match_level(level, level_str)) &&
           (!ok || !strcmp(cur_result->status, "OK"))){
 
-           find_result_t *curmatch = alloc(sizeof(find_result_t));
-           memcpy(curmatch, cur_result, sizeof(find_result_t));
+           find_result_t *curmatch = alloc(SIZEOF(find_result_t));
+           memcpy(curmatch, cur_result, SIZEOF(find_result_t));
 
 /*
            curmatch->hostname = stralloc(cur_result->hostname);
@@ -899,12 +968,13 @@ int ok;
     return(matches);
 }
 
-find_result_t *dump_exist(output_find, hostname, diskname, datestamp, level)
-find_result_t *output_find;
-char *hostname;
-char *diskname;
-int datestamp;
-int level;
+find_result_t *
+dump_exist(
+    find_result_t *output_find,
+    char *hostname,
+    char *diskname,
+    char *datestamp,
+    int level)
 {
     find_result_t *output_find_result;
 
@@ -913,7 +983,7 @@ int level;
        output_find_result=output_find_result->next) {
        if( !strcmp(output_find_result->hostname, hostname) &&
            !strcmp(output_find_result->diskname, diskname) &&
-           output_find_result->datestamp == datestamp &&
+           !strcmp(output_find_result->timestamp, datestamp) &&
            output_find_result->level == level) {
 
            return output_find_result;
index 5b9811db8e8c21e004cf631180d4a9268a1aa8b4..e3f76c1ad764dbb04bb9baf15111d3762bb2c330 100644 (file)
@@ -1,28 +1,28 @@
+#ifndef FIND_H
+#define FIND_H
+
 #include "diskfile.h"
 
 #define DEFAULT_SORT_ORDER      "hkdlpb"
 
 typedef struct find_result_s {
     struct find_result_s *next;
-    int datestamp;
-    int datestamp_aux;
-        /* aux is secondary key for intra-day comparisons -- could be timestamp,
-           just use seq# */
     char *timestamp;
     char *hostname;
     char *diskname;
     int level;
     char *label;
-    int  filenum;
+    off_t filenum;
     char *status;
     char *partnum;
     void *user_ptr;
 } find_result_t;
 
-find_result_t *find_dump P((int dyna_disklist, disklist_t* diskqp));
-char **find_log P((void));
-void sort_find_result P((char *sort_order, find_result_t **output_find));
-void print_find_result P((find_result_t *output_find));
-void free_find_result P((find_result_t **output_find));
-find_result_t *dump_exist P((find_result_t *output_find, char *hostname, char *diskname, int datestamp, int level));
-find_result_t *dumps_match P((find_result_t *output_find, char *hostname, char *diskname, char *datestamp, char *level, int ok));
+find_result_t *find_dump(int dyna_disklist, disklist_t* diskqp);
+char **find_log(void);
+void sort_find_result(char *sort_order, find_result_t **output_find);
+void print_find_result(find_result_t *output_find);
+void free_find_result(find_result_t **output_find);
+find_result_t *dump_exist(find_result_t *output_find, char *hostname, char *diskname, char *datestamp, int level);
+find_result_t *dumps_match(find_result_t *output_find, char *hostname, char *diskname, char *datestamp, char *level, int ok);
+#endif /* !FIND_H */
index c645ebdf3a812c42aad96f5c60fded247395a7c0..40dfc0cd8d86c2b029af0924afa143ca0842df93 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: getconf.c,v 1.18 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: getconf.c,v 1.26 2006/07/25 19:00:56 martinea Exp $
  *
  * a little wrapper to extract config variables for shell scripts
  */
 #include "genversion.h"
 #include "conffile.h"
 
-int main P((int argc, char **argv));
+int main(int argc, char **argv);
+
+/*
+ * HOSTNAME_INSTANCE may not be defined at this point.
+ * We define it locally if it is needed...
+ *
+ * If CLIENT_HOST_PRINCIPLE is defined as HOSTNAME_INSTANCE
+ * then local host is the client host principle.
+ */
+#ifndef HOSTNAME_INSTANCE
+#  define HOSTNAME_INSTANCE "localhost"
+#endif
+
+#ifndef KEYFILE
+#  define KEYFILE "id_rsa"
+#endif
 
 static struct build_info {
     char *symbol;
@@ -54,123 +69,172 @@ static struct build_info {
     { "DEFAULT_SERVER",                        DEFAULT_SERVER },
     { "DEFAULT_CONFIG",                        DEFAULT_CONFIG },
     { "DEFAULT_TAPE_SERVER",           DEFAULT_TAPE_SERVER },
-    { "DEFAULT_TAPE_DEVICE",           DEFAULT_TAPE_SERVER },
+#ifdef DEFAULT_TAPE_DEVICE
+    { "DEFAULT_TAPE_DEVICE",           DEFAULT_TAPE_DEVICE },
+#endif
     { "CLIENT_LOGIN",                  CLIENT_LOGIN },
 
     { "BUILT_DATE",
 #if defined(BUILT_DATE)
        BUILT_DATE
+#else
+       NULL
 #endif
     },
     { "BUILT_MACH",
 #if defined(BUILT_MACH)
        BUILT_MACH
+#else
+       NULL
 #endif
     },
     { "CC",
 #if defined(CC)
        CC
+#else
+       NULL
 #endif
     },
 
     { "AMANDA_DBGDIR",
 #if defined(AMANDA_DBGDIR)
        AMANDA_DBGDIR
+#else
+       NULL
 #endif
     },
     { "DEV_PREFIX",
 #if defined(DEV_PREFIX)
        DEV_PREFIX
+#else
+       NULL
 #endif
     },
     { "RDEV_PREFIX",
 #if defined(RDEV_PREFIX)
-       RDEV_PREFIX },
+       RDEV_PREFIX
+#else
+       NULL
 #endif
+    },
     { "DUMP",
 #if defined(DUMP)
        DUMP
+#else
+       NULL
 #endif
     },
     { "RESTORE",
 #if defined(DUMP)
        RESTORE
+#else
+       NULL
 #endif
     },
     { "VDUMP",
 #if defined(VDUMP)
        VDUMP
+#else
+       NULL
 #endif
     },
     { "VRESTORE",
 #if defined(VDUMP)
        VRESTORE
+#else
+       NULL
 #endif
     },
     { "XFSDUMP",
 #if defined(XFSDUMP)
        XFSDUMP
+#else
+       NULL
 #endif
     },
     { "XFSRESTORE",
 #if defined(XFSDUMP)
        XFSRESTORE
+#else
+       NULL
 #endif
     },
     { "VXDUMP",
 #if defined(VXDUMP)
        VXDUMP
+#else
+       NULL
 #endif
     },
     { "VXRESTORE",
 #if defined(VXDUMP)
        VXRESTORE
+#else
+       NULL
 #endif
     },
     { "SAMBA_CLIENT",
 #if defined(SAMBA_CLIENT)
        SAMBA_CLIENT
+#else
+       NULL
 #endif
     },
     { "GNUTAR",
 #if defined(GNUTAR)
        GNUTAR
+#else
+       NULL
 #endif
     },
     { "COMPRESS_PATH",
 #if defined(COMPRESS_PATH)
        COMPRESS_PATH
+#else
+       NULL
 #endif
     },
     { "UNCOMPRESS_PATH",
 #if defined(UNCOMPRESS_PATH)
        UNCOMPRESS_PATH
+#else
+       NULL
 #endif
     },
     { "listed_incr_dir",
 #if defined(GNUTAR_LISTED_INCREMENTAL_DIR)
        GNUTAR_LISTED_INCREMENTAL_DIR
+#else
+       NULL
 #endif
     },
     { "GNUTAR_LISTED_INCREMENTAL_DIR",
 #if defined(GNUTAR_LISTED_INCREMENTAL_DIR)
        GNUTAR_LISTED_INCREMENTAL_DIR
+#else
+       NULL
 #endif
     },
 
     { "AIX_BACKUP",
 #if defined(AIX_BACKUP)
        "1"
+#else
+       NULL
 #endif
     },
     { "AIX_TAPEIO",
 #if defined(AIX_TAPEIO)
        "1"
+#else
+       NULL
 #endif
     },
     { "DUMP_RETURNS_1",
 #if defined(DUMP_RETURNS_1)
        "1"
+#else
+       NULL
 #endif
     },
 
@@ -191,122 +255,167 @@ static struct build_info {
     { "STATFS_BSD",
 #if defined(STATFS_BSD)
        "1"
+#else
+       NULL
 #endif
     },
     { "STATFS_OSF1",
 #if defined(STATFS_OSF1)
        "1"
+#else
+       NULL
 #endif
     },
     { "STATFS_ULTRIX",
 #if defined(STATFS_ULTRIX)
        "1"
+#else
+       NULL
 #endif
     },
     { "ASSERTIONS",
 #if defined(ASSERTIONS)
        "1"
+#else
+       NULL
 #endif
     },
     { "DEBUG_CODE",
 #if defined(DEBUG_CODE)
        "1"
+#else
+       NULL
 #endif
     },
     { "BSD_SECURITY",
 #if defined(BSD_SECURITY)
        "1"
+#else
+       NULL
 #endif
     },
     { "USE_AMANDAHOSTS",
 #if defined(USE_AMANDAHOSTS)
        "1"
+#else
+       NULL
 #endif
     },
     { "USE_RUNDUMP",
 #if defined(USE_RUNDUMP)
        "1"
+#else
+       NULL
 #endif
     },
     { "FORCE_USERID",
 #if defined(FORCE_USERID)
        "1"
+#else
+       NULL
 #endif
     },
     { "USE_VERSION_SUFFIXES",
 #if defined(USE_VERSION_SUFFIXES)
        "1"
+#else
+       NULL
 #endif
     },
     { "HAVE_GZIP",
 #if defined(HAVE_GZIP)
        "1"
+#else
+       NULL
 #endif
     },
 
     { "KRB4_SECURITY",
 #if defined(KRB4_SECURITY)
        "1"
+#else
+       NULL
 #endif
     },
     { "SERVER_HOST_PRINCIPLE",
 #if defined(KRB4_SECURITY)
        SERVER_HOST_PRINCIPLE
+#else
+       NULL
 #endif
     },
     { "SERVER_HOST_INSTANCE",
 #if defined(KRB4_SECURITY)
        SERVER_HOST_INSTANCE
+#else
+       NULL
 #endif
     },
     { "SERVER_HOST_KEY_FILE",
 #if defined(KRB4_SECURITY)
        SERVER_HOST_KEY_FILE
+#else
+       NULL
 #endif
     },
     { "CLIENT_HOST_PRINCIPLE",
 #if defined(KRB4_SECURITY)
        CLIENT_HOST_PRINCIPLE
+#else
+       NULL
 #endif
     },
     { "CLIENT_HOST_INSTANCE",
 #if defined(KRB4_SECURITY)
        CLIENT_HOST_INSTANCE
+#else
+       NULL
 #endif
     },
     { "CLIENT_HOST_KEY_FILE",
 #if defined(KRB4_SECURITY)
        CLIENT_HOST_KEY_FILE
+#else
+       NULL
 #endif
     },
 
     { "COMPRESS_SUFFIX",
 #if defined(COMPRESS_SUFFIX)
        COMPRESS_SUFFIX
+#else
+       NULL
 #endif
     },
     { "COMPRESS_FAST_OPT",
 #if defined(COMPRESS_FAST_OPT)
        COMPRESS_FAST_OPT
+#else
+       NULL
 #endif
     },
     { "COMPRESS_BEST_OPT",
 #if defined(COMPRESS_BEST_OPT)
        COMPRESS_BEST_OPT
+#else
+       NULL
 #endif
     },
     { "UNCOMPRESS_OPT",
 #if defined(UNCOMPRESS_OPT)
        UNCOMPRESS_OPT
+#else
+       NULL
 #endif
     },
 
     { NULL,                    NULL }
 };
 
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
     char *result;
     unsigned long malloc_hist_1, malloc_size_1;
@@ -316,13 +425,19 @@ char **argv;
     char *parmname;
     int i;
     char number[NUM_STR_SIZE];
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
 
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
-    if((pgm = strrchr(argv[0], '/')) == NULL) {
-       pgm = argv[0];
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if((pgm = strrchr(my_argv[0], '/')) == NULL) {
+       pgm = my_argv[0];
     } else {
        pgm++;
     }
@@ -331,26 +446,27 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-    if(argc < 2) {
-       fprintf(stderr, "Usage: %s [config] <parmname>\n", pgm);
+    if(my_argc < 2) {
+       fprintf(stderr, "Usage: %s [config] <parmname> [-o configoption]*\n", pgm);
        exit(1);
     }
 
-    if (argc > 2) {
-       config_name = stralloc(argv[1]);
+    if (my_argc > 2) {
+       config_name = stralloc(my_argv[1]);
        config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
-       parmname = argv[2];
+       parmname = my_argv[2];
     } else {
        char my_cwd[STR_SIZE];
 
-       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
            error("cannot determine current working directory");
+           /*NOTREACHED*/
        }
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
            config_name = stralloc(config_name + 1);
        }
-       parmname = argv[1];
+       parmname = my_argv[1];
     }
 
     safe_cd();
@@ -364,24 +480,24 @@ char **argv;
 #else
     i = -1;
 #endif
-    snprintf(number, sizeof(number), "%ld", (long)i);
+    snprintf(number, SIZEOF(number), "%ld", (long)i);
     build_info[1].value = stralloc(number);
 #if defined(KRB4_SECURITY)
     i = TICKET_LIFETIME;
 #else
     i = -1;
 #endif
-    snprintf(number, sizeof(number), "%ld", (long)i);
+    snprintf(number, SIZEOF(number), "%ld", (long)i);
     build_info[2].value = stralloc(number);
 
 #undef p
 #define        p       "build."
 
-    if(strncmp(parmname, p, sizeof(p) - 1) == 0) {
+    if(strncmp(parmname, p, SIZEOF(p) - 1) == 0) {
        char *s;
        char *t;
 
-       t = stralloc(parmname + sizeof(p) - 1);
+       t = stralloc(parmname + SIZEOF(p) - 1);
        for(i = 0; (s = build_info[i].symbol) != NULL; i++) {
            if(strcasecmp(s, t) == 0) {
                break;
@@ -397,17 +513,17 @@ char **argv;
 #undef p
 #define        p       "dbopen."
 
-    } else if(strncmp(parmname, p, sizeof(p) - 1) == 0) {
+    } else if(strncmp(parmname, p, SIZEOF(p) - 1) == 0) {
        char *pname;
        char *dbname;
 
-       if((pname = strrchr(parmname + sizeof(p) - 1, '/')) == NULL) {
-           pname = parmname + sizeof(p) - 1;
+       if((pname = strrchr(parmname + SIZEOF(p) - 1, '/')) == NULL) {
+           pname = parmname + SIZEOF(p) - 1;
        } else {
            pname++;
        }
        set_pname(pname);
-       dbopen();
+       dbopen(DBG_SUBDIR_SERVER);
        if((dbname = dbfn()) == NULL) {
            result = stralloc("/dev/null");
        } else {
@@ -421,14 +537,15 @@ char **argv;
 #undef p
 #define        p       "dbclose."
 
-    } else if(strncmp(parmname, p, sizeof(p) - 1) == 0) {
+    } else if(strncmp(parmname, p, SIZEOF(p) - 1) == 0) {
        char *t;
        char *pname;
        char *dbname;
 
-       t = stralloc(parmname + sizeof(p) - 1);
+       t = stralloc(parmname + SIZEOF(p) - 1);
        if((dbname = strchr(t, ':')) == NULL) {
            error("cannot parse %s", parmname);
+           /*NOTREACHED*/
        }
        *dbname++ = '\0';
        if((pname = strrchr(t, '/')) == NULL) {
@@ -447,19 +564,24 @@ char **argv;
        conffile = stralloc2(config_dir, CONFFILE_NAME);
        if(read_conffile(conffile)) {
            error("errors processing config file \"%s\"", conffile);
+           /*NOTREACHED*/
        }
        amfree(conffile);
+       dbrename(config_name, DBG_SUBDIR_SERVER);
+       report_bad_conf_arg();
        result = getconf_byname(parmname);
     }
-    if(result == NULL) {
-       result = stralloc("BUGGY");
+
+    if (result == NULL) {
        fprintf(stderr, "%s: no such parameter \"%s\"\n",
                get_pname(), parmname);
        fflush(stderr);
+    } else {
+       puts(result);
     }
 
-    puts(result);
-
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
     amfree(result);
     amfree(config_dir);
     amfree(config_name);
index 9581e60550b3c5bdfaa7cd0333989ed110be0b27..bcc580ac3c9875c6b1ce0a996dab4813fbab8add 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: holding.c,v 1.52 2006/03/09 22:01:21 martinea Exp $
+ * $Id: holding.c,v 1.56 2006/06/09 23:07:26 martinea Exp $
  *
  * Functions to access holding disk
  */
 #include "fileheader.h"
 #include "logfile.h"
 
-static sl_t *scan_holdingdisk P((sl_t *holding_list, char *diskdir, int verbose));
+static sl_t *scan_holdingdisk(sl_t *holding_list, char *diskdir, int verbose);
+static sl_t *scan_holdingdir(sl_t *holding_list, holdingdisk_t *holdp, char *datestamp);
 
-int is_dir(fname)
-char *fname;
+int
+is_dir(
+    char *fname)
 {
     struct stat statbuf;
 
@@ -47,19 +49,26 @@ char *fname;
     return (statbuf.st_mode & S_IFDIR) == S_IFDIR;
 }
 
-int is_emptyfile(fname)
-char *fname;
+int
+is_emptyfile(
+    char *fname)
 {
     struct stat statbuf;
 
     if(stat(fname, &statbuf) == -1) return 0;
 
-    return (statbuf.st_mode & S_IFDIR) != S_IFDIR && statbuf.st_size == 0;
+    return ((statbuf.st_mode & S_IFDIR) != S_IFDIR) &&
+               (statbuf.st_size == (off_t)0);
 }
 
-int is_datestr(fname)
-char *fname;
-/* sanity check on datestamp of the form YYYYMMDD or YYYYMMDDhhmmss*/
+
+/*
+ * sanity check on datestamp of the form YYYYMMDD or YYYYMMDDhhmmss
+ */
+
+int
+is_datestr(
+    char *fname)
 {
     char *cp;
     int ch, num, date, year, month, hour, minute, second;
@@ -105,8 +114,9 @@ char *fname;
 }
 
 
-int non_empty(fname)
-char *fname;
+int
+non_empty(
+    char *     fname)
 {
     DIR *dir;
     struct dirent *entry;
@@ -125,10 +135,11 @@ char *fname;
 }
 
 
-static sl_t *scan_holdingdisk(holding_list, diskdir, verbose)
-sl_t *holding_list;
-char *diskdir;
-int verbose;
+static sl_t *
+scan_holdingdisk(
+    sl_t *     holding_list,
+    char *     diskdir,
+    int                verbose)
 {
     DIR *topdir;
     struct dirent *workdir;
@@ -175,10 +186,11 @@ int verbose;
 }
 
 
-sl_t *scan_holdingdir(holding_list, holdp, datestamp)
-sl_t *holding_list;
-holdingdisk_t *holdp;
-char *datestamp;
+static sl_t *
+scan_holdingdir(
+    sl_t *             holding_list,
+    holdingdisk_t *    holdp,
+    char *             datestamp)
 {
     DIR *workdir;
     struct dirent *entry;
@@ -187,7 +199,7 @@ char *datestamp;
     disk_t *dp;
     dumpfile_t file;
 
-    dirname = vstralloc(holdp->diskdir, "/", datestamp, NULL);
+    dirname = vstralloc(holdingdisk_get_diskdir(holdp), "/", datestamp, NULL);
     if((workdir = opendir(dirname)) == NULL) {
        if(errno != ENOENT)
            log_add(L_INFO, "%s: could not open dir: %s",
@@ -195,7 +207,13 @@ char *datestamp;
        amfree(dirname);
        return holding_list;
     }
-    chdir(dirname);
+    if ((chdir(dirname)) == -1) {
+       log_add(L_INFO, "%s: could not chdir: %s",
+                   dirname, strerror(errno));
+       amfree(dirname);
+       return holding_list;
+    }
+
     while((entry = readdir(workdir)) != NULL) {
        if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            continue;
@@ -237,22 +255,28 @@ char *datestamp;
 
 
 
-sl_t *get_flush(dateargs, datestamp, amflush, verbose)
-sl_t *dateargs;
-char *datestamp;  /* don't do this date */
-int amflush, verbose;
+sl_t *
+get_flush(
+    sl_t *dateargs,
+    char *datestamp,  /* don't do this date */
+    int amflush,
+    int verbose)
 {
     sl_t *holding_list;
     sl_t *date_list;
     sle_t *datearg;
     sle_t *date, *next_date;
     holdingdisk_t *hdisk;
-    char current_dir[1000];
-
-    getcwd(current_dir, 999);
+    char current_dir[PATH_MAX];
 
     holding_list = new_sl();
 
+    if (getcwd(current_dir, SIZEOF(current_dir)-1) == NULL) {
+       log_add(L_INFO, "get_flush: could get current working directory: %s",
+                   strerror(errno));
+       return holding_list;
+    }
+
     if(dateargs) {
        int ok;
 
@@ -288,27 +312,32 @@ int amflush, verbose;
 
     free_sl(date_list);
     date_list = NULL;
-    chdir(current_dir);
+    if (chdir(current_dir) == -1) {
+       log_add(L_INFO, "%s: could not chdir: %s",
+                   current_dir, strerror(errno));
+    }
     return(holding_list);
 }
 
 
-sl_t *pick_all_datestamp(verbose)
-int verbose;
+sl_t *
+pick_all_datestamp(
+    int                verbose)
 {
     sl_t *holding_list = NULL;
     holdingdisk_t *hdisk;
 
     holding_list = new_sl();
     for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
-       holding_list = scan_holdingdisk(holding_list, hdisk->diskdir, verbose);
+       holding_list = scan_holdingdisk(holding_list, holdingdisk_get_diskdir(hdisk), verbose);
 
     return holding_list;
 }
 
 
-sl_t *pick_datestamp(verbose)
-int verbose;
+sl_t *
+pick_datestamp(
+    int                verbose)
 {
     sl_t *holding_list;
     sl_t *r_holding_list = NULL;
@@ -316,8 +345,8 @@ int verbose;
     char **directories = NULL;
     int i;
     char *answer = NULL;
-    char *a;
-    int ch;
+    char *a = NULL;
+    int ch = 0;
     char max_char = '\0', chupper = '\0';
 
     holding_list = pick_all_datestamp(verbose);
@@ -329,7 +358,7 @@ int verbose;
        return holding_list;
     }
     else {
-       directories = alloc((holding_list->nb_element) * sizeof(char *));
+       directories = alloc((holding_list->nb_element) * SIZEOF(char *));
        for(dir = holding_list->first, i=0; dir != NULL; dir = dir->next,i++) {
            directories[i] = dir->name;
        }
@@ -349,16 +378,22 @@ int verbose;
                clearerr(stdin);
                continue;
            }
-           a = answer;
-           while ((ch = *a++) != '\0' && isspace(ch)) {}
-           if(ch == '\0' || strncasecmp(a, "ALL", 3) == 0) {
+
+           if (*answer == '\0' || strncasecmp(answer, "ALL", 3) == 0) {
                break;
            }
+
+           a = answer;
+           while ((ch = *a++) != '\0') {
+               if (!isspace(ch))
+                   break;
+           }
+
            do {
                if (isspace(ch) || ch == ',') {
                    continue;
                }
-               chupper = toupper(ch);
+               chupper = (char)toupper(ch);
                if (chupper < 'A' || chupper > max_char) {
                    free_sl(r_holding_list);
                    r_holding_list = NULL;
@@ -380,25 +415,28 @@ int verbose;
 }
 
 
-filetype_t get_amanda_names(fname, hostname, diskname, level)
-char *fname, **hostname, **diskname;
-int *level;
+filetype_t
+get_amanda_names( char *       fname,
+    char **    hostname,
+    char **    diskname,
+    int *      level)
 {
     dumpfile_t file;
     char buffer[DISK_BLOCK_BYTES];
     int fd;
     *hostname = *diskname = NULL;
 
+    memset(buffer, 0, sizeof(buffer));
     if((fd = open(fname, O_RDONLY)) == -1)
        return F_UNKNOWN;
 
-    if(fullread(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+    if(fullread(fd, buffer, SIZEOF(buffer)) != (ssize_t)sizeof(buffer)) {
        aclose(fd);
        return F_UNKNOWN;
     }
     aclose(fd);
 
-    parse_file_header(buffer,&file,sizeof(buffer));
+    parse_file_header(buffer, &file, SIZEOF(buffer));
     if(file.type != F_DUMPFILE && file.type != F_CONT_DUMPFILE) {
        return file.type;
     }
@@ -410,58 +448,64 @@ int *level;
 }
 
 
-void get_dumpfile(fname, file)
-char *fname;
-dumpfile_t *file;
+void
+get_dumpfile(
+    char *     fname,
+    dumpfile_t *file)
 {
     char buffer[DISK_BLOCK_BYTES];
     int fd;
 
+    memset(buffer, 0, sizeof(buffer));
+
     fh_init(file);
     file->type = F_UNKNOWN;
     if((fd = open(fname, O_RDONLY)) == -1)
        return;
 
-    if(fullread(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+    if(fullread(fd, buffer, SIZEOF(buffer)) != (ssize_t)sizeof(buffer)) {
        aclose(fd);
        return;
     }
     aclose(fd);
 
-    parse_file_header(buffer,file,sizeof(buffer));
+    parse_file_header(buffer, file, SIZEOF(buffer));
     return;
 }
 
 
-long size_holding_files(holding_file, strip_headers)
-char *holding_file;
-int strip_headers;
+off_t
+size_holding_files(
+    char *     holding_file,
+    int                strip_headers)
 {
     int fd;
-    int buflen;
+    ssize_t buflen;
     char buffer[DISK_BLOCK_BYTES];
     dumpfile_t file;
     char *filename;
-    long size=0;
+    off_t size = (off_t)0;
     struct stat finfo;
 
+    memset(buffer, 0, sizeof(buffer));
     filename = stralloc(holding_file);
     while(filename != NULL && filename[0] != '\0') {
        if((fd = open(filename,O_RDONLY)) == -1) {
            fprintf(stderr,"size_holding_files: open of %s failed: %s\n",filename,strerror(errno));
            amfree(filename);
-           return -1;
+           return (off_t)-1;
        }
-       if ((buflen = fullread(fd, buffer, sizeof(buffer))) > 0) {
-               parse_file_header(buffer, &file, buflen);
+       if ((buflen = fullread(fd, buffer, SIZEOF(buffer))) > 0) {
+               parse_file_header(buffer, &file, (size_t)buflen);
        }
        close(fd);
        if(stat(filename, &finfo) == -1) {
            printf("stat %s: %s\n", filename, strerror(errno));
-           finfo.st_size = 0;
+           finfo.st_size = (off_t)0;
        }
-       size += (finfo.st_size+1023)/1024;
-       if(strip_headers) size -= DISK_BLOCK_BYTES/1024;
+       size += (finfo.st_size+(off_t)1023)/(off_t)1024;
+       if(strip_headers)
+           size -= (off_t)(DISK_BLOCK_BYTES / 1024);
        if(buflen > 0) {
            filename = newstralloc(filename, file.cont_filename);
        }
@@ -474,15 +518,17 @@ int strip_headers;
 }
 
 
-int unlink_holding_files( holding_file )
-char *holding_file;
+int
+unlink_holding_files(
+    char *     holding_file)
 {
     int fd;
-    int buflen;
+    ssize_t buflen;
     char buffer[DISK_BLOCK_BYTES];
     dumpfile_t file;
     char *filename;
 
+    memset(buffer, 0, sizeof(buffer));
     filename = stralloc(holding_file);
     while(filename != NULL && filename[0] != '\0') {
        if((fd = open(filename,O_RDONLY)) == -1) {
@@ -490,8 +536,8 @@ char *holding_file;
            amfree(filename);
            return 0;
        }
-       if ((buflen = fullread(fd, buffer, sizeof(buffer))) > 0) {
-           parse_file_header(buffer, &file, buflen);
+       if ((buflen = fullread(fd, buffer, SIZEOF(buffer))) > 0) {
+           parse_file_header(buffer, &file, (size_t)buflen);
        }
        close(fd);
        unlink(filename);
@@ -507,17 +553,19 @@ char *holding_file;
 }
 
 
-int rename_tmp_holding( holding_file, complete )
-char *holding_file;
-int complete;
+int
+rename_tmp_holding(
+    char *     holding_file,
+    int                complete)
 {
     int fd;
-    int buflen;
+    ssize_t buflen;
     char buffer[DISK_BLOCK_BYTES];
     dumpfile_t file;
     char *filename;
     char *filename_tmp = NULL;
 
+    memset(buffer, 0, sizeof(buffer));
     filename = stralloc(holding_file);
     while(filename != NULL && filename[0] != '\0') {
        filename_tmp = newvstralloc(filename_tmp, filename, ".tmp", NULL);
@@ -527,7 +575,7 @@ int complete;
            amfree(filename_tmp);
            return 0;
        }
-       buflen = fullread(fd, buffer, sizeof(buffer));
+       buflen = fullread(fd, buffer, SIZEOF(buffer));
        close(fd);
 
        if(rename(filename_tmp, filename) != 0) {
@@ -542,7 +590,7 @@ int complete;
            amfree(filename_tmp);
            return 0;
        }
-       parse_file_header(buffer, &file, buflen);
+       parse_file_header(buffer, &file, (size_t)buflen);
        if(complete == 0 ) {
            if((fd = open(filename, O_RDWR)) == -1) {
                fprintf(stderr, "rename_tmp_holdingX: open of %s failed: %s\n",
@@ -553,8 +601,8 @@ int complete;
 
            }
            file.is_partial = 1;
-           build_header(buffer, &file, sizeof(buffer));
-           fullwrite(fd, buffer, sizeof(buffer));
+           build_header(buffer, &file, SIZEOF(buffer));
+           fullwrite(fd, buffer, SIZEOF(buffer));
            close(fd);
        }
        filename = newstralloc(filename, file.cont_filename);
@@ -565,9 +613,10 @@ int complete;
 }
 
 
-void cleanup_holdingdisk(diskdir, verbose)
-char *diskdir;
-int verbose;
+void
+cleanup_holdingdisk(
+    char *     diskdir,
+    int                verbose)
 {
     DIR *topdir;
     struct dirent *workdir;
@@ -583,7 +632,10 @@ int verbose;
 
     if(verbose)
        printf("Scanning %s...\n", diskdir);
-    chdir(diskdir);
+    if ((chdir(diskdir)) == -1) {
+       log_add(L_INFO, "%s: could not chdir: %s",
+                   diskdir, strerror(errno));
+    }
     while((workdir = readdir(topdir)) != NULL) {
        if(strcmp(workdir->d_name, ".") == 0
           || strcmp(workdir->d_name, "..") == 0
@@ -609,8 +661,9 @@ int verbose;
 }
 
 
-int mkholdingdir(diskdir)
-char *diskdir;
+int
+mkholdingdir(
+    char *     diskdir)
 {
     struct stat stat_hdp;
     int success = 1;
index 75284d5e39c74e8c521a8751c588dd5289de2757..063a2bfd4662ba81012b24a90c78b01916bac870 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: holding.h,v 1.22 2005/10/11 01:17:01 vectro Exp $
+ * $Id: holding.h,v 1.23 2006/05/25 01:47:20 johnfranks Exp $
  *
  */
 
 #include "sl.h"
 
 /* local functions */
-int is_dir P((char *fname));
-int is_emptyfile P((char *fname));
-int is_datestr P((char *fname));
-int non_empty P((char *fname));
-void free_holding_list P(( sl_t *holding_list));
+int is_dir(char *fname);
+int is_emptyfile(char *fname);
+int is_datestr(char *fname);
+int non_empty(char *fname);
+void free_holding_list( sl_t *holding_list);
 sl_t *get_flush(sl_t *dateargs, char *datestamp, int amflush, int verbose);
-sl_t *pick_datestamp P((int verbose));
-sl_t *pick_all_datestamp P((int verbose));
-filetype_t get_amanda_names P((char *fname,
+sl_t *pick_datestamp(int verbose);
+sl_t *pick_all_datestamp(int verbose);
+filetype_t get_amanda_names(char *fname,
                               char **hostname,
                               char **diskname,
-                              int *level));
-void get_dumpfile P((char *fname, dumpfile_t *file));
-long size_holding_files P((char *holding_file, int strip_headers));
-int unlink_holding_files P((char *holding_file));
-int rename_tmp_holding P((char *holding_file, int complete));
-void cleanup_holdingdisk P((char *diskdir, int verbose));
-int mkholdingdir P((char *diskdir));
+                              int *level);
+void get_dumpfile(char *fname, dumpfile_t *file);
+off_t size_holding_files(char *holding_file, int strip_headers);
+int unlink_holding_files(char *holding_file);
+int rename_tmp_holding(char *holding_file, int complete);
+void cleanup_holdingdisk(char *diskdir, int verbose);
+int mkholdingdir(char *diskdir);
 
 
 #endif /* HOLDING_H */
index ac331a7adb10e8f93743611f766dd1d948779436..32f86f4123c3dbd69087ee058b3de8a9f7d7d762 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: infofile.c,v 1.57 2006/03/10 11:56:06 martinea Exp $
+ * $Id: infofile.c,v 1.64 2006/07/25 18:18:48 martinea Exp $
  *
  * manage current info file
  */
@@ -34,7 +34,7 @@
 #include "infofile.h"
 #include "token.h"
 
-static void zero_info P((info_t *));
+static void zero_info(info_t *);
 
 #ifdef TEXTDB
   static char *infodir = (char *)0;
@@ -42,14 +42,14 @@ static void zero_info P((info_t *));
   static char *newinfofile;
   static int writing;
 
-  static FILE *open_txinfofile P((char *, char *, char *));
-  static int close_txinfofile P((FILE *));
-  static int read_txinfofile P((FILE *, info_t *));
-  static int write_txinfofile P((FILE *, info_t *));
-  static int delete_txinfofile P((char *, char *));
+  static FILE *open_txinfofile(char *, char *, char *);
+  static int close_txinfofile(FILE *);
+  static int read_txinfofile(FILE *, info_t *);
+  static int write_txinfofile(FILE *, info_t *);
+  static int delete_txinfofile(char *, char *);
 #else
 #  define MAX_KEY 256
-/*#  define HEADER     (sizeof(info_t)-DUMP_LEVELS*sizeof(stats_t))*/
+/*#  define HEADER     (SIZEOF(info_t)-DUMP_LEVELS*SIZEOF(stats_t))*/
 
   static DBM *infodb = NULL;
   static lockfd = -1;
@@ -57,28 +57,31 @@ static void zero_info P((info_t *));
 
 #ifdef TEXTDB
 
-static FILE *open_txinfofile(host, disk, mode)
-char *host;
-char *disk;
-char *mode;
+static FILE *
+open_txinfofile(
+    char *     host,
+    char *     disk,
+    char *     mode)
 {
     FILE *infof;
+    char *myhost;
+    char *mydisk;
 
     assert(infofile == (char *)0);
 
     writing = (*mode == 'w');
 
-    host = sanitise_filename(host);
-    disk = sanitise_filename(disk);
+    myhost = sanitise_filename(host);
+    mydisk = sanitise_filename(disk);
 
     infofile = vstralloc(infodir,
-                        "/", host,
-                        "/", disk,
+                        "/", myhost,
+                        "/", mydisk,
                         "/info",
                         NULL);
 
-    amfree(host);
-    amfree(disk);
+    amfree(myhost);
+    amfree(mydisk);
 
     /* create the directory structure if in write mode */
     if (writing) {
@@ -109,8 +112,9 @@ char *mode;
     return infof;
 }
 
-static int close_txinfofile(infof)
-FILE *infof;
+static int
+close_txinfofile(
+    FILE *infof)
 {
     int rc = 0;
 
@@ -132,9 +136,11 @@ FILE *infof;
     return rc;
 }
 
-static int read_txinfofile(infof, info) /* XXX - code assumes AVG_COUNT == 3 */
-FILE *infof;
-info_t *info;
+/* XXX - code assumes AVG_COUNT == 3 */
+static int
+read_txinfofile(
+    FILE *     infof,
+    info_t *   info)
 {
     char *line = NULL;
     int version;
@@ -147,13 +153,23 @@ info_t *info;
 
     /* get version: command: lines */
 
-    if((line = agets(infof)) == NULL) return -1;
+    while ((line = agets(infof)) != NULL) {
+       if (line[0] != '\0')
+           break;
+       amfree(line);
+    }
+    if (line == NULL) return -1;
     rc = sscanf(line, "version: %d", &version);
     amfree(line);
     if(rc != 1) return -2;
 
-    if((line = agets(infof)) == NULL) return -1;
-    rc = sscanf(line, "command: %d", &info->command);
+    while ((line = agets(infof)) != NULL) {
+       if (line[0] != '\0')
+           break;
+       amfree(line);
+    }
+    if (line == NULL) return -1;
+    rc = sscanf(line, "command: %u", &info->command);
     amfree(line);
     if(rc != 1) return -2;
 
@@ -161,14 +177,24 @@ info_t *info;
 
     pp = &info->full;
 
-    if((line = agets(infof)) == NULL) return -1;
-    rc = sscanf(line, "full-rate: %f %f %f",
+    while ((line = agets(infof)) != NULL) {
+       if (line[0] != '\0')
+           break;
+       amfree(line);
+    }
+    if (line == NULL) return -1;
+    rc = sscanf(line, "full-rate: %lf %lf %lf",
                &pp->rate[0], &pp->rate[1], &pp->rate[2]);
     amfree(line);
     if(rc > 3) return -2;
 
-    if((line = agets(infof)) == NULL) return -1;
-    rc = sscanf(line, "full-comp: %f %f %f",
+    while ((line = agets(infof)) != NULL) {
+       if (line[0] != '\0')
+           break;
+       amfree(line);
+    }
+    if (line == NULL) return -1;
+    rc = sscanf(line, "full-comp: %lf %lf %lf",
                &pp->comp[0], &pp->comp[1], &pp->comp[2]);
     amfree(line);
     if(rc > 3) return -2;
@@ -177,14 +203,24 @@ info_t *info;
 
     pp = &info->incr;
 
-    if((line = agets(infof)) == NULL) return -1;
-    rc = sscanf(line, "incr-rate: %f %f %f",
+    while ((line = agets(infof)) != NULL) {
+       if (line[0] != '\0')
+           break;
+       amfree(line);
+    }
+    if (line == NULL) return -1;
+    rc = sscanf(line, "incr-rate: %lf %lf %lf",
                &pp->rate[0], &pp->rate[1], &pp->rate[2]);
     amfree(line);
     if(rc > 3) return -2;
 
-    if((line = agets(infof)) == NULL) return -1;
-    rc = sscanf(line, "incr-comp: %f %f %f",
+    while ((line = agets(infof)) != NULL) {
+       if (line[0] != '\0')
+           break;
+       amfree(line);
+    }
+    if (line == NULL) return -1;
+    rc = sscanf(line, "incr-comp: %lf %lf %lf",
                &pp->comp[0], &pp->comp[1], &pp->comp[2]);
     amfree(line);
     if(rc > 3) return -2;
@@ -193,9 +229,13 @@ info_t *info;
 
     for(rc = -2; (line = agets(infof)) != NULL; free(line)) {
        stats_t onestat;        /* one stat record */
-       long date;
-       int level;
+       time_t date = 0;
+        time_t *date_p = &date;
+        time_t *secs_p;
+       int level = 0;
 
+       if (line[0] == '\0')
+           continue;
        if(line[0] == '/' && line[1] == '/') {
            rc = 0;
            amfree(line);
@@ -207,16 +247,16 @@ info_t *info;
        else if (strncmp(line,"history:",8) == 0) {
            break;                              /* normal */
        }
-       memset(&onestat, 0, sizeof(onestat));
+       memset(&onestat, 0, SIZEOF(onestat));
 
        s = line;
        ch = *s++;
 
 #define sc "stats:"
-       if(strncmp(line, sc, sizeof(sc)-1) != 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) != 0) {
            break;
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
 
@@ -227,32 +267,38 @@ info_t *info;
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.size) != 1) {
+       if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&onestat.size) != 1) {
            break;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.csize) != 1) {
+       if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&onestat.csize) != 1) {
            break;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.secs) != 1) {
+        secs_p = &onestat.secs;
+       if(ch == '\0' || sscanf((s - 1), TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)secs_p) != 1) {
            break;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &date) != 1) {
+       if(ch == '\0' || sscanf((s - 1), TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)date_p) != 1) {
            break;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
        if(ch != '\0') {
-           if(sscanf((s - 1), "%d", &onestat.filenum) != 1) {
+           if(sscanf((s - 1), OFF_T_FMT,
+                       (OFF_T_FMT_TYPE *)&onestat.filenum) != 1) {
                break;
            }
            skip_integer(s, ch);
@@ -261,8 +307,8 @@ info_t *info;
            if(ch == '\0') {
                break;
            }
-           strncpy(onestat.label, s-1, sizeof(onestat.label)-1);
-           onestat.label[sizeof(onestat.label)-1] = '\0';
+           strncpy(onestat.label, s-1, SIZEOF(onestat.label)-1);
+           onestat.label[SIZEOF(onestat.label)-1] = '\0';
        }
 
        onestat.date = date;    /* time_t not guarranteed to be long */
@@ -289,8 +335,13 @@ info_t *info;
 
     for(rc = -2; (line = agets(infof)) != NULL; free(line)) {
        history_t onehistory;   /* one history record */
-       long date;
+       time_t date;
+       time_t *date_p = &date;
+        time_t *secs_p;
 
+       if (line[0] == '\0')
+           continue;
+       date = 0L;
        if(line[0] == '/' && line[1] == '/') {
            info->history[nb_history].level = -2;
            rc = 0;
@@ -298,17 +349,17 @@ info_t *info;
            return 0;                           /* normal end of record */
        }
 
-       memset(&onehistory, 0, sizeof(onehistory));
+       memset(&onehistory, 0, SIZEOF(onehistory));
 
        s = line;
        ch = *s++;
 
 #define sc "history:"
-       if(strncmp(line, sc, sizeof(sc)-1) != 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) != 0) {
            amfree(line);
            break;
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
 
@@ -320,32 +371,37 @@ info_t *info;
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &onehistory.size) != 1) {
+       if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&onehistory.size) != 1) {
            amfree(line);
            break;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &onehistory.csize) != 1) {
+       if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+                               (OFF_T_FMT_TYPE *)&onehistory.csize) != 1) {
            amfree(line);
            break;
        }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf((s - 1), "%ld", &date) != 1) {
+       if(ch == '\0' || sscanf((s - 1), TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)date_p) != 1) {
            amfree(line);
            break;
        }
        skip_integer(s, ch);
 
-       onehistory.date = date; /* time_t not guarranteed to be long */
+       onehistory.date = date; /* time_t not guaranteed to be long */
 
-       onehistory.secs = -1;
+       onehistory.secs = (unsigned long)-1;
        skip_whitespace(s, ch);
+        secs_p = &onehistory.secs;
        if(ch != '\0') {
-           if(sscanf((s - 1), "%ld", &onehistory.secs) != 1) {
+           if(sscanf((s - 1), TIME_T_FMT,
+                               (TIME_T_FMT_TYPE *)secs_p) != 1) {
                amfree(line);
                break;
            }
@@ -356,15 +412,21 @@ info_t *info;
     }
     amfree(line);
 
-    if((line = agets(infof)) == NULL) return -1; /* // line */
+    while ((line = agets(infof)) != NULL) {
+       if (line[0] != '\0')
+           break;
+       amfree(line);
+    }
+    if (line == NULL) return -1;
     amfree(line);
 
     return rc;
 }
 
-static int write_txinfofile(infof, info)
-FILE *infof;
-info_t *info;
+static int
+write_txinfofile(
+    FILE *     infof,
+    info_t *   info)
 {
     int i;
     stats_t *sp;
@@ -373,20 +435,20 @@ info_t *info;
 
     fprintf(infof, "version: %d\n", 0);
 
-    fprintf(infof, "command: %d\n", info->command);
+    fprintf(infof, "command: %u\n", info->command);
 
     pp = &info->full;
 
     fprintf(infof, "full-rate:");
     for(i=0; i<AVG_COUNT; i++)
        if(pp->rate[i] >= 0.0)
-           fprintf(infof, " %f", pp->rate[i]);
+           fprintf(infof, " %lf", pp->rate[i]);
     fprintf(infof, "\n");
 
     fprintf(infof, "full-comp:");
     for(i=0; i<AVG_COUNT; i++)
        if(pp->comp[i] >= 0.0)
-           fprintf(infof, " %f", pp->comp[i]);
+           fprintf(infof, " %lf", pp->comp[i]);
     fprintf(infof, "\n");
 
     pp = &info->incr;
@@ -394,13 +456,13 @@ info_t *info;
     fprintf(infof, "incr-rate:");
     for(i=0; i<AVG_COUNT; i++)
        if(pp->rate[i] >= 0.0)
-           fprintf(infof, " %f", pp->rate[i]);
+           fprintf(infof, " %lf", pp->rate[i]);
     fprintf(infof, "\n");
 
     fprintf(infof, "incr-comp:");
     for(i=0; i<AVG_COUNT; i++)
        if(pp->comp[i] >= 0.0)
-           fprintf(infof, " %f", pp->comp[i]);
+           fprintf(infof, " %lf", pp->comp[i]);
     fprintf(infof, "\n");
 
     for(level=0; level<DUMP_LEVELS; level++) {
@@ -408,43 +470,53 @@ info_t *info;
 
        if(sp->date < (time_t)0 && sp->label[0] == '\0') continue;
 
-       fprintf(infof, "stats: %d %ld %ld %ld %ld", level,
-              sp->size, sp->csize, sp->secs, (long)sp->date);
+       fprintf(infof, "stats: %d " OFF_T_FMT " " OFF_T_FMT
+               " " TIME_T_FMT " " OFF_T_FMT,
+               level, (OFF_T_FMT_TYPE)sp->size, (OFF_T_FMT_TYPE)sp->csize,
+               (TIME_T_FMT_TYPE)sp->secs, (OFF_T_FMT_TYPE)sp->date);
        if(sp->label[0] != '\0')
-           fprintf(infof, " %d %s", sp->filenum, sp->label);
+           fprintf(infof, " " OFF_T_FMT " %s",
+               (OFF_T_FMT_TYPE)sp->filenum, sp->label);
        fprintf(infof, "\n");
     }
 
     fprintf(infof, "last_level: %d %d\n", info->last_level, info->consecutive_runs);
 
     for(i=0;info->history[i].level > -1;i++) {
-       fprintf(infof, "history: %d %ld %ld %ld %ld\n",info->history[i].level,
-               info->history[i].size, info->history[i].csize,
-               info->history[i].date, info->history[i].secs);
+       fprintf(infof, "history: %d " OFF_T_FMT " " OFF_T_FMT
+               " " TIME_T_FMT " " TIME_T_FMT "\n",
+               info->history[i].level,
+               (OFF_T_FMT_TYPE)info->history[i].size,
+               (OFF_T_FMT_TYPE)info->history[i].csize,
+               (TIME_T_FMT_TYPE)info->history[i].date,
+               (TIME_T_FMT_TYPE)info->history[i].secs);
     }
     fprintf(infof, "//\n");
 
     return 0;
 }
 
-static int delete_txinfofile(host, disk)
-char *host;
-char *disk;
+static int
+delete_txinfofile(
+    char *     host,
+    char *     disk)
 {
     char *fn = NULL, *fn_new = NULL;
     int rc;
+    char *myhost;
+    char *mydisk;
 
-    host = sanitise_filename(host);
-    disk = sanitise_filename(disk);
+    myhost = sanitise_filename(host);
+    mydisk = sanitise_filename(disk);
     fn = vstralloc(infodir,
-                  "/", host,
-                  "/", disk,
+                  "/", myhost,
+                  "/", mydisk,
                   "/info",
                   NULL);
     fn_new = stralloc2(fn, ".new");
 
-    amfree(host);
-    amfree(disk);
+    amfree(myhost);
+    amfree(mydisk);
 
     unlink(fn_new);
     amfree(fn_new);
@@ -460,8 +532,9 @@ char *disk;
 static char *lockname = NULL;
 #endif
 
-int open_infofile(filename)
-char *filename;
+int
+open_infofile(
+    char *     filename)
 {
 #ifdef TEXTDB
     assert(infodir == (char *)0);
@@ -493,7 +566,8 @@ char *filename;
 #endif
 }
 
-void close_infofile()
+void
+close_infofile(void)
 {
 #ifdef TEXTDB
     assert(infodir != (char *)0);
@@ -502,8 +576,10 @@ void close_infofile()
 #else
     dbm_close(infodb);
 
-    if(amfunlock(lockfd, "info") == -1)
+    if(amfunlock(lockfd, "info") == -1) {
        error("could not unlock infofile: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
     aclose(lockfd);
     lockfd = -1;
@@ -513,9 +589,10 @@ void close_infofile()
 }
 
 /* Convert a dump level to a GMT based time stamp */
-char *get_dumpdate(info, lev)
-info_t *info;
-int lev;
+char *
+get_dumpdate(
+    info_t *   info,
+    int                lev)
 {
     static char stamp[20]; /* YYYY:MM:DD:hh:mm:ss */
     int l;
@@ -530,17 +607,20 @@ int lev;
     }
 
     t = gmtime(&last);
-    snprintf(stamp, sizeof(stamp), "%d:%d:%d:%d:%d:%d",
+    snprintf(stamp, SIZEOF(stamp), "%d:%d:%d:%d:%d:%d",
                t->tm_year+1900, t->tm_mon+1, t->tm_mday,
                t->tm_hour, t->tm_min, t->tm_sec);
 
     return stamp;
 }
 
-double perf_average(a, d)
-/* Weighted average */
-float *a;      /* array of items to average */
-double d;      /* default value */
+/*
+ * Weighted average
+ */
+double
+perf_average(
+    double *   a,      /* array of items to average */
+    double     d)      /* default value */
 {
     double sum;        /* running total */
     int n;     /* number of items in sum */
@@ -562,12 +642,13 @@ double d; /* default value */
     return sum / n;
 }
 
-static void zero_info(info)
-info_t *info;
+static void
+zero_info(
+    info_t *info)
 {
     int i;
 
-    memset(info, '\0', sizeof(info_t));
+    memset(info, '\0', SIZEOF(info_t));
 
     for(i = 0; i < AVG_COUNT; i++) {
        info->full.comp[i] = info->incr.comp[i] = -1.0;
@@ -583,16 +664,18 @@ info_t *info;
 
     for(i=0;i<=NB_HISTORY;i++) {
        info->history[i].level = -2;
-       info->history[i].size = 0;
-       info->history[i].csize = 0;
-       info->history[i].date = 0;
+       info->history[i].size = (off_t)0;
+       info->history[i].csize = (off_t)0;
+       info->history[i].date = 0UL;
     }
     return;
 }
 
-int get_info(hostname, diskname, info)
-char *hostname, *diskname;
-info_t *info;
+int
+get_info(
+    char *     hostname,
+    char *     diskname,
+    info_t *   info)
 {
     int rc;
 
@@ -638,11 +721,19 @@ info_t *info;
 }
 
 
-int get_firstkey(hostname, hostname_size, diskname, diskname_size)
-char *hostname, *diskname;
-int hostname_size, diskname_size;
+int
+get_firstkey(
+    char *     hostname,
+    int                hostname_size,
+    char *     diskname,
+    int                diskname_size)
 {
 #ifdef TEXTDB
+    (void)hostname;            /* Quiet unused parameter warning */
+    (void)hostname_size;       /* Quiet unused parameter warning */
+    (void)diskname;            /* Quiet unused parameter warning */
+    (void)diskname_size;       /* Quiet unused parameter warning */
+
     assert(0);
     return 0;
 #else
@@ -681,11 +772,19 @@ int hostname_size, diskname_size;
 }
 
 
-int get_nextkey(hostname, hostname_size, diskname, diskname_size)
-char *hostname, *diskname;
-int hostname_size, diskname_size;
+int
+get_nextkey(
+    char *     hostname,
+    int                hostname_size,
+    char *     diskname,
+    int                diskname_size)
 {
 #ifdef TEXTDB
+    (void)hostname;            /* Quiet unused parameter warning */
+    (void)hostname_size;       /* Quiet unused parameter warning */
+    (void)diskname;            /* Quiet unused parameter warning */
+    (void)diskname_size;       /* Quiet unused parameter warning */
+
     assert(0);
     return 0;
 #else
@@ -724,9 +823,11 @@ int hostname_size, diskname_size;
 }
 
 
-int put_info(hostname, diskname, info)
-     char *hostname, *diskname;
-     info_t *info;
+int
+put_info(
+     char *    hostname,
+     char *    diskname,
+     info_t *  info)
 {
 #ifdef TEXTDB
     FILE *infof;
@@ -751,7 +852,7 @@ int put_info(hostname, diskname, info)
     k.dsize = strlen(k.dptr)+1;
 
     d.dptr = (char *)info;
-    d.dsize = sizeof(info_t);
+    d.dsize = SIZEOF(info_t);
 
     /* store record */
 
@@ -766,8 +867,10 @@ int put_info(hostname, diskname, info)
 }
 
 
-int del_info(hostname, diskname)
-char *hostname, *diskname;
+int
+del_info(
+    char *     hostname,
+    char *     diskname)
 {
 #ifdef TEXTDB
     return delete_txinfofile(hostname, diskname);
@@ -794,26 +897,29 @@ char *hostname, *diskname;
 
 #ifdef TEST
 
-void dump_rec(info)
-info_t *info;
+void dump_rec(info_t *info);
+
+void
+dump_rec(
+    info_t *   info)
 {
     int i;
     stats_t *sp;
 
     printf("command word: %d\n", info->command);
-    printf("full dump rate (K/s) %5.1f, %5.1f, %5.1f\n",
+    printf("full dump rate (K/s) %5.1lf, %5.1lf, %5.1lf\n",
           info->full.rate[0],info->full.rate[1],info->full.rate[2]);
-    printf("full comp rate %5.1f, %5.1f, %5.1f\n",
+    printf("full comp rate %5.1lf, %5.1lf, %5.1lf\n",
           info->full.comp[0]*100,info->full.comp[1]*100,info->full.comp[2]*100);
-    printf("incr dump rate (K/s) %5.1f, %5.1f, %5.1f\n",
+    printf("incr dump rate (K/s) %5.1lf, %5.1lf, %5.1lf\n",
           info->incr.rate[0],info->incr.rate[1],info->incr.rate[2]);
-    printf("incr comp rate %5.1f, %5.1f, %5.1f\n",
+    printf("incr comp rate %5.1lf, %5.1lf, %5.1lf\n",
           info->incr.comp[0]*100,info->incr.comp[1]*100,info->incr.comp[2]*100);
     for(i = 0; i < DUMP_LEVELS; i++) {
        sp = &info->inf[i];
        if( sp->size != -1) {
 
-           printf("lev %d date %ld tape %s filenum %d size %ld csize %ld secs %ld\n",
+           printf("lev %d date %ld tape %s filenum " OFF_T_FMT " size %ld csize %ld secs %ld\n",
                   i, (long)sp->date, sp->label, sp->filenum,
                   sp->size, sp->csize, sp->secs);
        }
@@ -823,8 +929,12 @@ info_t *info;
 }
 
 #ifdef TEXTDB
-void dump_db(host, disk)
-char *host, *disk;
+void dump_db( char *host, char *disk);
+
+void
+dump_db(
+    char *     host,
+    char *     disk)
 {
     info_t info;
     int rc;
@@ -836,8 +946,9 @@ char *host, *disk;
     }
 }
 #else
-void dump_db(str)
-char *str;
+void
+dump_db(
+    char *     str)
 {
     datum k,d;
     int rec,r,num;
@@ -852,10 +963,10 @@ char *str;
        printf("%3d: KEY %s =\n", rec, k.dptr);
 
        d = dbm_fetch(infodb, k);
-       memset(&info, '\0', sizeof(info));
+       memset(&info, '\0', SIZEOF(info));
        memcpy(&info, d.dptr, d.dsize);
 
-       num = (d.dsize-HEADER)/sizeof(stats_t);
+       num = (d.dsize-HEADER)/SIZEOF(stats_t);
        dump_rec(&info);
 
        k = dbm_nextkey(infodb);
@@ -866,9 +977,9 @@ char *str;
 #endif
 
 int
-main(argc, argv)
-int argc;
-char *argv[];
+main(
+    int                argc,
+    char **    argv)
 {
   int i;
   unsigned long malloc_hist_1, malloc_size_1;
@@ -878,6 +989,8 @@ char *argv[];
 
   set_pname("infofile");
 
+  dbopen(DBG_SUBDIR_SERVER);
+
   malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
   for(i = 1; i < argc; ++i) {
index 3aa2ef2cb8eb5b0fcebb1f0e8e55c7aa847f9830..f8139f7ff8f9e8a2694c70b7a353a4d378a4c504 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: infofile.h,v 1.13 2005/03/16 18:15:05 martinea Exp $
+ * $Id: infofile.h,v 1.14 2006/05/25 01:47:20 johnfranks Exp $
  *
  * interface for current info file reading code
  */
 
 typedef struct stats_s {
     /* fields updated by dumper */
-    long size;                 /* original size of dump in kbytes */
-    long csize;                        /* compressed size of dump in kbytes */
-    long secs;                 /* time of dump in secs */
+    off_t size;                        /* original size of dump in kbytes */
+    off_t csize;               /* compressed size of dump in kbytes */
+    time_t secs;               /* time of dump in secs */
     time_t date;               /* end time of dump */
     /* fields updated by taper */
-    int filenum;               /* file number on tape */
+    off_t filenum;             /* file number on tape */
     char label[MAX_LABEL];     /* tape label */
 } stats_t;
 
 typedef struct history_s {
     int level;                 /* level of dump */
-    long size;                 /* original size of dump in kbytes */
-    long csize;                        /* compressed size of dump in kbytes */
+    off_t size;                        /* original size of dump in kbytes */
+    off_t csize;               /* compressed size of dump in kbytes */
     time_t date;               /* time of dump */
-    long secs;                 /* time of dump in secs */
+    time_t secs;               /* time of dump in secs */
 } history_t;
 
 typedef struct perf_s {
-    float rate[AVG_COUNT];
-    float comp[AVG_COUNT];
+    double rate[AVG_COUNT];
+    double comp[AVG_COUNT];
 } perf_t;
 
 typedef struct info_s {
@@ -80,17 +80,17 @@ typedef struct info_s {
 } info_t;
 
 
-int open_infofile P((char *infofile));
-void close_infofile P((void));
+int open_infofile(char *infofile);
+void close_infofile(void);
 
-char *get_dumpdate P((info_t *info, int level));
-double perf_average P((float *array, double def));
-int get_info P((char *hostname, char *diskname, info_t *info));
-int get_firstkey P((char *hostname, int hostname_size,
-                   char *diskname, int diskname_size));
-int get_nextkey  P((char *hostname, int hostname_size,
-                   char *diskname, int diskname_size));
-int put_info P((char *hostname, char *diskname, info_t *info));
-int del_info P((char *hostname, char *diskname));
+char *get_dumpdate(info_t *info, int level);
+double perf_average(double *array, double def);
+int get_info(char *hostname, char *diskname, info_t *info);
+int get_firstkey(char *hostname, int hostname_size,
+                   char *diskname, int diskname_size);
+int get_nextkey(char *hostname, int hostname_size,
+                   char *diskname, int diskname_size);
+int put_info(char *hostname, char *diskname, info_t *info);
+int del_info(char *hostname, char *diskname);
 
 #endif /* ! INFOFILE_H */
index c38a30639b6d84876d7c59075ff33d4df2b47eeb..060f07f8e44dd2eccbf1033be75c101f4863f90c 100644 (file)
@@ -23,7 +23,7 @@
  * Authors: the Amanda Development Team.  Its members are listed in a
  * file named AUTHORS, in the root directory of this distribution.
  */
-/* $Id: list_dir.c,v 1.17 2002/03/24 19:25:51 jrjackson Exp $
+/* $Id: list_dir.c,v 1.19 2006/07/05 11:22:49 martinea Exp $
  *
  * manage directory listings from index files
  */
@@ -36,13 +36,15 @@ DIR_ITEM *dir_list = NULL; /* first dir entry */
 DIR_ITEM *dir_last = NULL; /* last dir entry  */
 DIR_ITEM *cur_list = NULL; /* current dir entry,for speeding up search */
 
-DIR_ITEM *get_dir_list()
+DIR_ITEM *
+get_dir_list(void)
 {
     return dir_list;
 }
 
 
-void clear_dir_list P((void))
+void
+clear_dir_list(void)
 {
     DIR_ITEM *this;
 
@@ -68,15 +70,17 @@ void clear_dir_list P((void))
 /* It's true because the output of the index file is sorted         */
 /* Maybe it could be more efficient if the index was sorted when    */
 /* it is generated                                                  */
-int add_dir_list_item(dump, path)
-DUMP_ITEM *dump;
-char *path;
+
+int
+add_dir_list_item(
+    DUMP_ITEM *        dump,
+    const char *path)
 {
     DIR_ITEM *cur;
 
     if (dir_list == NULL)
     {
-       dir_list = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+       dir_list = (DIR_ITEM *)alloc(SIZEOF(DIR_ITEM));
        dir_list->next = NULL;
        dir_list->dump = dump;
        dir_list->path = stralloc(path);
@@ -91,7 +95,7 @@ char *path;
     /* add at head of list */
     if(strcmp(path,dir_list->path) < 0)
     {
-       cur_list = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+       cur_list = (DIR_ITEM *)alloc(SIZEOF(DIR_ITEM));
        cur_list->next = dir_list;
        cur_list->dump = dump;
        cur_list->path = stralloc(path);
@@ -117,14 +121,14 @@ char *path;
            cur_list=cur_list->next;
        }
 
-       if(strcmp(path,cur_list->next->path) == 0)
+       if (cur_list->next && strcmp(path, cur_list->next->path) == 0)
        {
            cur_list=cur_list->next;
            return 0; /* found */
        }
 
        /* add at cur_list */
-       cur = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+       cur = (DIR_ITEM *)alloc(SIZEOF(DIR_ITEM));
        cur->next = cur_list->next;
        cur->dump = dump;
        cur->path = stralloc(path);
@@ -134,7 +138,7 @@ char *path;
     }
     else /* add at end of list */
     {
-       dir_last->next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+       dir_last->next = (DIR_ITEM *)alloc(SIZEOF(DIR_ITEM));
        dir_last=dir_last->next;
        dir_last->next = NULL;
        dir_last->dump = dump;
index fec34747f1008b44475facdf57a0bfc3a227c055..109559ffa02a857c334a8e80af689a4ca691a256 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: list_dir.h,v 1.3 1999/02/15 02:30:26 martinea Exp $
+ * $Id: list_dir.h,v 1.4 2006/05/25 01:47:20 johnfranks Exp $
  *
  */
+#ifndef LISTDIR_H
+#define LISTDIR_H
+
 
 typedef struct DIR_ITEM {
     DUMP_ITEM *dump;
@@ -34,7 +37,7 @@ typedef struct DIR_ITEM {
     struct DIR_ITEM *next;
 } DIR_ITEM;
 
-
-extern DIR_ITEM *get_dir_list P((void));
-extern void clear_dir_list P((void));
-extern int add_dir_list_item P((DUMP_ITEM *dump, char *path));
+extern struct DIR_ITEM *get_dir_list(void);
+extern void clear_dir_list(void);
+extern int add_dir_list_item(DUMP_ITEM *dump, const char *path);
+#endif /* !LISTDIR_H */
index de063dcfd1782f023f03e8b51f55a98cf169c5a7..c1d3e26b35ac1609dfc408b5c721c2df2c2cbf94 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: logfile.c,v 1.29 2005/12/04 22:56:55 martinea Exp $
+ * $Id: logfile.c,v 1.31 2006/06/01 14:54:39 martinea Exp $
  *
  * common log file writing routine
  */
@@ -73,11 +73,12 @@ static int logfd = -1;
   */
 
 /* local functions */
-static void open_log P((void));
-static void close_log P((void));
+static void open_log(void);
+static void close_log(void);
 
-void logerror(msg)
-char *msg;
+void
+logerror(
+    char *     msg)
 {
     log_add(L_FATAL, "%s", msg);
 }
@@ -101,7 +102,7 @@ printf_arglist_function2(char *log_genstring, logtype_t, typ, char *, pname, cha
     }
 
     arglist_start(argp, format);
-    vsnprintf(linebuf, sizeof(linebuf)-1, format, argp);
+    vsnprintf(linebuf, SIZEOF(linebuf)-1, format, argp);
                                                /* -1 to allow for '\n' */
     return(vstralloc(leader, linebuf, "\n", NULL));
 }
@@ -112,7 +113,7 @@ printf_arglist_function1(void log_add, logtype_t, typ, char *, format)
     int saved_errout;
     char *leader = NULL;
     char linebuf[STR_SIZE];
-    int n;
+    size_t n;
 
 
     /* format error message */
@@ -126,7 +127,7 @@ printf_arglist_function1(void log_add, logtype_t, typ, char *, format)
     }
 
     arglist_start(argp, format);
-    vsnprintf(linebuf, sizeof(linebuf)-1, format, argp);
+    vsnprintf(linebuf, SIZEOF(linebuf)-1, format, argp);
                                                /* -1 to allow for '\n' */
     arglist_end(argp);
 
@@ -139,8 +140,10 @@ printf_arglist_function1(void log_add, logtype_t, typ, char *, format)
 
     if(multiline == -1) open_log();
 
-    if (fullwrite(logfd, leader, strlen(leader)) < 0)
+    if (fullwrite(logfd, leader, strlen(leader)) < 0) {
        error("log file write error: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
     amfree(leader);
 
@@ -148,8 +151,10 @@ printf_arglist_function1(void log_add, logtype_t, typ, char *, format)
     if(n == 0 || linebuf[n-1] != '\n') linebuf[n++] = '\n';
     linebuf[n] = '\0';
 
-    if (fullwrite(logfd, linebuf, n) < 0)
+    if (fullwrite(logfd, linebuf, n) < 0) {
        error("log file write error: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
     if(multiline != -1) multiline++;
     else close_log();
@@ -157,7 +162,8 @@ printf_arglist_function1(void log_add, logtype_t, typ, char *, format)
     erroutput_type = saved_errout;
 }
 
-void log_start_multiline()
+void
+log_start_multiline(void)
 {
     assert(multiline == -1);
 
@@ -166,7 +172,8 @@ void log_start_multiline()
 }
 
 
-void log_end_multiline()
+void
+log_end_multiline(void)
 {
     assert(multiline != -1);
     multiline = -1;
@@ -174,8 +181,9 @@ void log_end_multiline()
 }
 
 
-void log_rename(datestamp)
-char *datestamp;
+void
+log_rename(
+    char *     datestamp)
 {
     char *conf_logdir;
     char *logfile;
@@ -195,7 +203,7 @@ char *datestamp;
     logfile = vstralloc(conf_logdir, "/log", NULL);
 
     for(seq = 0; 1; seq++) {   /* if you've got MAXINT files in your dir... */
-       snprintf(seq_str, sizeof(seq_str), "%d", seq);
+       snprintf(seq_str, SIZEOF(seq_str), "%u", seq);
        fname = newvstralloc(fname,
                             logfile,
                             ".", datestamp,
@@ -204,9 +212,11 @@ char *datestamp;
        if(stat(fname, &statbuf) == -1 && errno == ENOENT) break;
     }
 
-    if(rename(logfile, fname) == -1)
+    if(rename(logfile, fname) == -1) {
        error("could not rename \"%s\" to \"%s\": %s",
              logfile, fname, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     amfree(fname);
     amfree(logfile);
@@ -214,7 +224,8 @@ char *datestamp;
 }
 
 
-static void open_log()
+static void
+open_log(void)
 {
     char *conf_logdir;
 
@@ -229,29 +240,39 @@ static void open_log()
 
     logfd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600);
 
-    if(logfd == -1)
+    if(logfd == -1) {
        error("could not open log file %s: %s", logfile, strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    if(amflock(logfd, "log") == -1)
+    if(amflock(logfd, "log") == -1) {
        error("could not lock log file %s: %s", logfile, strerror(errno));
+       /*NOTREACHED*/
+    }
 }
 
 
-static void close_log()
+static void
+close_log(void)
 {
-    if(amfunlock(logfd, "log") == -1)
+    if(amfunlock(logfd, "log") == -1) {
        error("could not unlock log file %s: %s", logfile, strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    if(close(logfd) == -1)
+    if(close(logfd) == -1) {
        error("close log file: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
     logfd = -1;
     amfree(logfile);
 }
 
 
-int get_logline(logf)
-FILE *logf;
+int
+get_logline(
+    FILE *     logf)
 {
     static char *logline = NULL;
     char *logstr, *progstr;
@@ -259,7 +280,12 @@ FILE *logf;
     int ch;
 
     amfree(logline);
-    if((logline = agets(logf)) == NULL) return 0;
+    while ((logline = agets(logf)) != NULL) {
+       if (logline[0] != '\0')
+           break;
+       amfree(logline);
+    }
+    if (logline == NULL) return 0;
     curlinenum++;
     s = logline;
     ch = *s++;
index fbeda341c6421a56440e403690339063731363c8..ed5934728ad1120ff623a49c7e873af146de6884 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: logfile.h,v 1.12 2005/11/29 22:19:08 martinea Exp $
+ * $Id: logfile.h,v 1.13 2006/05/25 01:47:20 johnfranks Exp $
  *
  * interface to logfile module
  */
@@ -67,14 +67,14 @@ extern program_t curprog;
 extern char *curstr;
 extern char *program_str[];
 
-void logerror P((char *));
-void log_add P((logtype_t typ, char * format, ...))
+void logerror(char *);
+void log_add(logtype_t typ, char * format, ...)
     __attribute__ ((format (printf, 2, 3)));
-char* log_genstring P((logtype_t typ, char *pname, char * format, ...));
+char* log_genstring(logtype_t typ, char *pname, char * format, ...);
 /*    __attribute__ ((format (printf, 3, 4))); */
-void log_start_multiline P((void));
-void log_end_multiline P((void));
-void log_rename P((char *datestamp));
-int get_logline P((FILE *));
+void log_start_multiline(void);
+void log_end_multiline(void);
+void log_rename(char *datestamp);
+int get_logline(FILE *);
 
 #endif  /* ! LOGFILE_H */
index 5e44c577e734ae0d1e15aa783605352ebf9ad729..caa63967eb8f0ee549564e133b20ad76742b2dd6 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: planner.c,v 1.180.2.1 2006/04/24 11:16:43 martinea Exp $
+ * $Id: planner.c,v 1.206 2006/08/10 23:57:27 paddy_s Exp $
  *
  * backup schedule planner for the Amanda backup system.
  */
 
 /* configuration file stuff */
 
-char *conf_tapetype;
-am64_t conf_maxdumpsize;
-int conf_runtapes;
-int conf_dumpcycle;
-int conf_runspercycle;
-int conf_tapecycle;
-int conf_etimeout;
-int conf_reserve;
-int conf_autoflush;
+char * conf_tapetype;
+off_t  conf_maxdumpsize;
+int    conf_runtapes;
+int    conf_dumpcycle;
+int    conf_runspercycle;
+int    conf_tapecycle;
+time_t conf_etimeout;
+int    conf_reserve;
+int    conf_autoflush;
+int    conf_usetimestamps;
 
 #define HOST_READY                             ((void *)0)     /* must be 0 */
 #define HOST_ACTIVE                            ((void *)1)
@@ -77,11 +78,13 @@ typedef struct est_s {
     int got_estimate;
     int dump_priority;
     int dump_level;
-    long dump_size;
+    off_t dump_nsize;  /* native size */
+    off_t dump_csize;  /* compressed size */
     int degr_level;    /* if dump_level == 0, what would be the inc level */
-    long degr_size;
+    off_t degr_nsize;  /* native degraded size */
+    off_t degr_csize;  /* compressed degraded size */
     int last_level;
-    long last_lev0size;
+    off_t last_lev0size;
     int next_level0;
     int level_days;
     int promote;
@@ -90,23 +93,24 @@ typedef struct est_s {
     char *errstr;
     int level[MAX_LEVELS];
     char *dumpdate[MAX_LEVELS];
-    long est_size[MAX_LEVELS];
+    off_t est_size[MAX_LEVELS];
 } est_t;
 
 #define est(dp)        ((est_t *)(dp)->up)
 
 /* pestq = partial estimate */
 disklist_t startq, waitq, pestq, estq, failq, schedq;
-am64_t total_size;
+off_t total_size;
 double total_lev0, balanced_size, balance_threshold;
-am64_t tape_length, tape_mark;
+off_t tape_length;
+size_t tape_mark;
 
 tapetype_t *tape;
-long tt_blocksize;
-long tt_blocksize_kb;
+size_t tt_blocksize;
+size_t tt_blocksize_kb;
 int runs_per_cycle = 0;
 time_t today;
-char *datestamp = NULL;
+char *planner_timestamp = NULL;
 
 static am_feature_t *our_features = NULL;
 static char *our_feature_string = NULL;
@@ -122,7 +126,8 @@ typedef struct bi_s {
     int deleted;               /* 0=modified, 1=deleted */
     disk_t *dp;                        /* The disk that was changed */
     int level;                 /* The original level */
-    long size;                 /* The original size */
+    off_t nsize;               /* The original native size */
+    off_t csize;               /* The original compressed size */
     char *errstr;              /* A message describing why this disk is here */
 } bi_t;
 
@@ -138,45 +143,54 @@ bilist_t biq;                     /* The BI queue itself */
  *
  */
 
-static void setup_estimate P((disk_t *dp));
-static void get_estimates P((void));
-static void analyze_estimate P((disk_t *dp));
-static void handle_failed P((disk_t *dp));
-static void delay_dumps P((void));
-static int promote_highest_priority_incremental P((void));
-static int promote_hills P((void));
-static void output_scheduleline P((disk_t *dp));
-int main P((int, char **));
-
-int main(argc, argv)
-int argc;
-char **argv;
+static void setup_estimate(disk_t *dp);
+static void get_estimates(void);
+static void analyze_estimate(disk_t *dp);
+static void handle_failed(disk_t *dp);
+static void delay_dumps(void);
+static int promote_highest_priority_incremental(void);
+static int promote_hills(void);
+static void output_scheduleline(disk_t *dp);
+int main(int, char **);
+
+int main(int argc, char **argv)
 {
     disklist_t origq;
     disk_t *dp;
     int moved_one;
     unsigned long malloc_hist_1, malloc_size_1;
     unsigned long malloc_hist_2, malloc_size_2;
-    long initial_size;
+    off_t initial_size;
     int i;
     char *conffile;
     char *conf_diskfile;
     char *conf_tapelist;
     char *conf_infofile;
     times_t section_start;
+    uid_t ruid;
+    char *qname;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
+    int    nb_disk;
+    char  *errstr;
 
     safe_fd(-1, 0);
 
-    setvbuf(stderr, (char *)NULL, _IOLBF, 0);
+    setvbuf(stderr, (char *)NULL, (int)_IOLBF, 0);
 
-    if (argc > 1) {
-       config_name = stralloc(argv[1]);
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if (my_argc > 1) {
+       config_name = stralloc(my_argv[1]);
        config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
     } else {
        char my_cwd[STR_SIZE];
 
-       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
            error("cannot determine current working directory");
+           /*NOTREACHED*/
        }
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
@@ -188,6 +202,8 @@ char **argv;
 
     set_pname("planner");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -202,7 +218,7 @@ char **argv;
     our_feature_string = am_feature_to_string(our_features);
 
     fprintf(stderr, "%s: pid %ld executable %s version %s\n",
-           get_pname(), (long) getpid(), argv[0], version());
+           get_pname(), (long) getpid(), my_argv[0], version());
     for (i = 0; version_info[i] != NULL; i++)
        fprintf(stderr, "%s: %s", get_pname(), version_info[i]);
 
@@ -210,16 +226,14 @@ char **argv;
      * 1. Networking Setup
      *
      * Planner runs setuid to get a priviledged socket for BSD security.
-     * We get the socket right away as root, then setuid back to a normal
-     * user.  If we are not using BSD security, planner is not installed
-     * setuid root.
+     * We get the socket right away as root, then set euid to normal
+     * user. Keeping saved uid as root.
      */
 
     protocol_init();
 
+    ruid = getuid();
     if(geteuid() == 0) {
-       uid_t ruid = getuid();
-       setuid(0);
        seteuid(ruid);
        setgid(getgid());
     }
@@ -230,8 +244,10 @@ char **argv;
      * are a valid user.
      */
 
-    if(getpwuid(getuid()) == NULL)
+    if(getpwuid(getuid()) == NULL) {
        error("can't get login name for my uid %ld", (long)getuid());
+       /*NOTREACHED*/
+    }
 
     /*
      * 2. Read in Configuration Information
@@ -244,9 +260,14 @@ char **argv;
     conffile = stralloc2(config_dir, CONFFILE_NAME);
     if(read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     conf_diskfile = getconf_str(CNF_DISKFILE);
     if (*conf_diskfile == '/') {
        conf_diskfile = stralloc(conf_diskfile);
@@ -255,11 +276,31 @@ char **argv;
     }
     if (read_diskfile(conf_diskfile, &origq) < 0) {
        error("could not load disklist \"%s\"", conf_diskfile);
+       /*NOTREACHED*/
     }
-    match_disklist(&origq, argc-2, argv+2);
+    if(origq.head == NULL) {
+       error("empty disklist \"%s\"", conf_diskfile);
+       /*NOTREACHED*/
+    }
+
+    errstr = match_disklist(&origq, my_argc-2, my_argv+2);
+    if (errstr) {
+       fprintf(stderr,"%s",errstr);
+       amfree(errstr);
+    }
+    nb_disk = 0;
     for(dp = origq.head; dp != NULL; dp = dp->next) {
-       if(dp->todo)
-           log_add(L_DISK, "%s %s", dp->host->hostname, dp->name);
+       if(dp->todo) {
+           qname = quote_string(dp->name);
+           log_add(L_DISK, "%s %s", dp->host->hostname, qname);
+           amfree(qname);
+           nb_disk++;
+       }
+    }
+
+    if(nb_disk == 0) {
+       error("no DLE to backup");
+       /*NOTREACHED*/
     }
     amfree(conf_diskfile);
 
@@ -271,6 +312,7 @@ char **argv;
     }
     if(read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
     }
     amfree(conf_tapelist);
 
@@ -282,6 +324,7 @@ char **argv;
     }
     if(open_infofile(conf_infofile)) {
        error("could not open info db \"%s\"", conf_infofile);
+       /*NOTREACHED*/
     }
     amfree(conf_infofile);
 
@@ -291,14 +334,24 @@ char **argv;
     conf_dumpcycle = getconf_int(CNF_DUMPCYCLE);
     conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
     conf_tapecycle = getconf_int(CNF_TAPECYCLE);
-    conf_etimeout = getconf_int(CNF_ETIMEOUT);
+    conf_etimeout = getconf_time(CNF_ETIMEOUT);
     conf_reserve  = getconf_int(CNF_RESERVE);
-    conf_autoflush = getconf_int(CNF_AUTOFLUSH);
+    conf_autoflush = getconf_boolean(CNF_AUTOFLUSH);
+    conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS);
 
-    amfree(datestamp);
+    amfree(planner_timestamp);
     today = time(0);
-    datestamp = construct_datestamp(NULL);
-    log_add(L_START, "date %s", datestamp);
+    if(conf_usetimestamps == 0) {
+       planner_timestamp = construct_datestamp(NULL);
+    }
+    else {
+       planner_timestamp = construct_timestamp(NULL);
+    }
+    log_add(L_START, "date %s", planner_timestamp);
+    printf("DATE %s\n", planner_timestamp);
+    fflush(stdout);
+    fprintf(stderr, "%s: timestamp %s\n",
+                   get_pname(), planner_timestamp);
 
     /* some initializations */
 
@@ -322,14 +375,14 @@ char **argv;
      }
     
     tape = lookup_tapetype(conf_tapetype);
-    if(conf_maxdumpsize > 0) {
-       tape_length = conf_maxdumpsize;
+    if(conf_maxdumpsize > (off_t)0) {
+       tape_length = (off_t)conf_maxdumpsize;
     }
     else {
-       tape_length = tape->length * conf_runtapes;
+       tape_length = tapetype_get_length(tape) * (off_t)conf_runtapes;
     }
-    tape_mark   = tape->filemark;
-    tt_blocksize_kb = tape->blocksize;
+    tape_mark = (size_t)tapetype_get_filemark(tape);
+    tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape);
     tt_blocksize = tt_blocksize_kb * 1024;
 
     fprintf(stderr, "%s: time %s: startup took %s secs\n",
@@ -450,7 +503,7 @@ char **argv;
     section_start = curclock();
 
                        /* an empty tape still has a label and an endmark */
-    total_size = (tt_blocksize_kb + tape_mark) * 2;
+    total_size = ((off_t)tt_blocksize_kb + (off_t)tape_mark) * (off_t)2;
     total_lev0 = 0.0;
     balanced_size = 0.0;
 
@@ -466,11 +519,16 @@ char **argv;
     {
        disk_t *dp;
 
-       fprintf(stderr, "INITIAL SCHEDULE (size " AM64_FMT "):\n", total_size);
+       fprintf(stderr, "INITIAL SCHEDULE (size " OFF_T_FMT "):\n",
+               (OFF_T_FMT_TYPE)total_size);
        for(dp = schedq.head; dp != NULL; dp = dp->next) {
-           fprintf(stderr, "  %s %s pri %d lev %d size %ld\n",
-                   dp->host->hostname, dp->name, est(dp)->dump_priority,
-                   est(dp)->dump_level, est(dp)->dump_size);
+           qname = quote_string(dp->name);
+           fprintf(stderr, "  %s %s pri %d lev %d nsize " OFF_T_FMT " csize " OFF_T_FMT "\n",
+                   dp->host->hostname, qname, est(dp)->dump_priority,
+                   est(dp)->dump_level,
+                   (OFF_T_FMT_TYPE)est(dp)->dump_nsize,
+                    (OFF_T_FMT_TYPE)est(dp)->dump_csize);
+           amfree(qname);
        }
     }
 
@@ -487,17 +545,21 @@ char **argv;
      * until the dumps fit on the tape.
      */
 
-    fprintf(stderr,
-      "\nDELAYING DUMPS IF NEEDED, total_size " AM64_FMT ", tape length " AM64_FMT " mark " AM64_FMT "\n",
-           total_size, tape_length, tape_mark);
+    fprintf(stderr, "\nDELAYING DUMPS IF NEEDED, total_size " OFF_T_FMT
+           ", tape length " OFF_T_FMT " mark " SIZE_T_FMT "\n",
+           (OFF_T_FMT_TYPE)total_size,
+           (OFF_T_FMT_TYPE)tape_length,
+           (SIZE_T_FMT_TYPE)tape_mark);
 
     initial_size = total_size;
 
     delay_dumps();
 
     /* XXX - why bother checking this? */
-    if(empty(schedq) && total_size < initial_size)
+    if(empty(schedq) && total_size < initial_size) {
        error("cannot fit anything on tape, bailing out");
+       /*NOTREACHED*/
+    }
 
 
     /*
@@ -519,7 +581,7 @@ char **argv;
      */
 
     fprintf(stderr,
-     "\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0f, balanced_size %1.0f...\n",
+     "\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0lf, balanced_size %1.0lf...\n",
            total_lev0, balanced_size);
 
     balance_threshold = balanced_size * PROMOTE_THRESHOLD;
@@ -535,6 +597,12 @@ char **argv;
                    walltime_str(timessub(curclock(), section_start)));
 
 
+    /* done with prvileged ops, make sure root privilege is dropped */
+    if ( geteuid() == 0 ) {
+      setuid(ruid);
+      seteuid(ruid);
+    }
+
     /*
      * 9. Output Schedule
      *
@@ -548,9 +616,12 @@ char **argv;
     fprintf(stderr, "--------\n");
 
     close_infofile();
-    log_add(L_FINISH, "date %s time %s", datestamp, walltime_str(curclock()));
+    log_add(L_FINISH, "date %s time %s", planner_timestamp, walltime_str(curclock()));
 
-    amfree(datestamp);
+    clear_tapelist();
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
+    amfree(planner_timestamp);
     amfree(config_dir);
     amfree(config_name);
     amfree(our_feature_string);
@@ -563,6 +634,8 @@ char **argv;
        malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
     }
 
+    dbclose();
+
     return 0;
 }
 
@@ -574,34 +647,36 @@ char **argv;
  *
  */
 
-static void askfor P((est_t *, int, int, info_t *));
-static int last_level P((info_t *info));                 /* subroutines */
-static long est_size P((disk_t *dp, int level));
-static long est_tape_size P((disk_t *dp, int level));
-static int next_level0 P((disk_t *dp, info_t *info));
-static int runs_at P((info_t *info, int lev));
-static long bump_thresh P((int level, long size_level_0, int bumppercent, int bumpsize, double bumpmult));
-static int when_overwrite P((char *label));
-
-static void askfor(ep, seq, lev, info)
-est_t *ep;     /* esimate data block */
-int seq;       /* sequence number of request */
-int lev;       /* dump level being requested */
-info_t *info;  /* info block for disk */
+static void askfor(est_t *, int, int, info_t *);
+static int last_level(info_t *info);             /* subroutines */
+static off_t est_size(disk_t *dp, int level);
+static off_t est_tape_size(disk_t *dp, int level);
+static int next_level0(disk_t *dp, info_t *info);
+static int runs_at(info_t *info, int lev);
+static off_t bump_thresh(int level, off_t size_level_0, int bumppercent, off_t bumpsize, double bumpmult);
+static int when_overwrite(char *label);
+
+static void askfor(
+    est_t *ep, /* esimate data block */
+    int seq,   /* sequence number of request */
+    int lev,   /* dump level being requested */
+    info_t *info)      /* info block for disk */
 {
     if(seq < 0 || seq >= MAX_LEVELS) {
        error("error [planner askfor: seq out of range 0..%d: %d]",
              MAX_LEVELS, seq);
+       /*NOTREACHED*/
     }
     if(lev < -1 || lev >= DUMP_LEVELS) {
        error("error [planner askfor: lev out of range -1..%d: %d]",
              DUMP_LEVELS, lev);
+       /*NOTREACHED*/
     }
 
     if (lev == -1) {
        ep->level[seq] = -1;
        ep->dumpdate[seq] = (char *)0;
-       ep->est_size[seq] = -2;
+       ep->est_size[seq] = (off_t)-2;
        return;
     }
 
@@ -610,23 +685,27 @@ info_t *info;     /* info block for disk */
     ep->dumpdate[seq] = stralloc(get_dumpdate(info,lev));
     malloc_mark(ep->dumpdate[seq]);
 
-    ep->est_size[seq] = -2;
+    ep->est_size[seq] = (off_t)-2;
 
     return;
 }
 
 static void
-setup_estimate(dp)
-     disk_t *dp;
+setup_estimate(
+     disk_t *dp)
 {
     est_t *ep;
     info_t info;
     int i;
+    char *qname;
+    int overwrite_runs;
 
     assert(dp && dp->host);
+
+    qname = quote_string(dp->name);
     fprintf(stderr, "%s: time %s: setting up estimates for %s:%s\n",
                    get_pname(), walltime_str(curclock()),
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qname);
 
     /* get current information about disk */
 
@@ -637,11 +716,12 @@ setup_estimate(dp)
 
     /* setup working data struct for disk */
 
-    ep = alloc(sizeof(est_t));
+    ep = alloc(SIZEOF(est_t));
     malloc_mark(ep);
     dp->up = (void *) ep;
     ep->state = DISK_READY;
-    ep->dump_size = -1;
+    ep->dump_nsize = (off_t)-1;
+    ep->dump_csize = (off_t)-1;
     ep->dump_priority = dp->priority;
     ep->errstr = 0;
     ep->promote = 0;
@@ -664,13 +744,15 @@ setup_estimate(dp)
             */
            log_add(L_ERROR,
                    "Cannot force full dump of %s:%s with no-full option.",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qname);
 
            /* clear force command */
            CLR(info.command, FORCE_FULL);
-           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, dp->name, strerror(errno));
+                     dp->host->hostname, qname, strerror(errno));
+               /*NOTREACHED*/
+           }
            ep->last_level = last_level(&info);
            ep->next_level0 = next_level0(dp, &info);
        }
@@ -678,7 +760,7 @@ setup_estimate(dp)
            ep->last_level = -1;
            ep->next_level0 = -conf_dumpcycle;
            log_add(L_INFO, "Forcing full dump of %s:%s as directed.",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qname);
        }
     }
     else if(dp->strategy == DS_NOFULL) {
@@ -693,26 +775,27 @@ setup_estimate(dp)
 
     /* adjust priority levels */
 
+    /* warn if dump will be overwritten */
+    if(ep->last_level > -1) {
+       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);
+       }
+       else if(overwrite_runs <= RUNS_REDZONE) {
+           log_add(L_WARNING, "Last full dump of %s:%s on "
+                   "tape %s overwritten in %d run%s.",
+                   dp->host->hostname, qname, info.inf[0].label,
+                   overwrite_runs, overwrite_runs == 1? "" : "s");
+       }
+    }
+
     if(ep->next_level0 < 0) {
        fprintf(stderr,"%s:%s overdue %d day%s for level 0\n",
-               dp->host->hostname, dp->name,
+               dp->host->hostname, qname,
                - ep->next_level0, ((- ep->next_level0) == 1) ? "" : "s");
        ep->dump_priority -= ep->next_level0;
-       /* warn if dump will be overwritten */
-       if(ep->last_level > -1) {
-           int 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, dp->name, info.inf[0].label);
-           }
-           else if(overwrite_runs < RUNS_REDZONE) {
-               log_add(L_WARNING,
-                 "Last full dump of %s:%s on tape %s overwritten in %d run%s.",
-                       dp->host->hostname, dp->name, info.inf[0].label,
-                   overwrite_runs, overwrite_runs == 1? "" : "s");
-           }
-       }
     }
     else if (ISSET(info.command, FORCE_FULL))
        ep->dump_priority += 1;
@@ -727,21 +810,24 @@ setup_estimate(dp)
            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, dp->name, strerror(errno));
+                     dp->host->hostname, qname, strerror(errno));
+               /*NOTREACHED*/
+           }
            log_add(L_INFO, "Skipping full dump of %s:%s today.",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qname);
            fprintf(stderr,"%s:%s lev 0 skipped due to skip-full flag\n",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qname);
            /* don't enqueue the disk */
            askfor(ep, 0, -1, &info);
            askfor(ep, 1, -1, &info);
            askfor(ep, 2, -1, &info);
            fprintf(stderr, "%s: SKIPPED %s %s 0 [skip-full]\n",
-                   get_pname(), dp->host->hostname, dp->name);
+                   get_pname(), dp->host->hostname, qname);
            log_add(L_SUCCESS, "%s %s %s 0 [skipped: skip-full]",
-                   dp->host->hostname, dp->name, datestamp);
+                   dp->host->hostname, qname, planner_timestamp);
+           amfree(qname);
            return;
        }
 
@@ -752,7 +838,7 @@ setup_estimate(dp)
 
        if(ep->next_level0 == 1) {
            log_add(L_WARNING, "Skipping full dump of %s:%s tomorrow.",
-                   dp->host->hostname, dp->name);
+                   dp->host->hostname, qname);
        }
     }
 
@@ -762,9 +848,10 @@ setup_estimate(dp)
        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, dp->name);
+               dp->host->hostname, qname);
        fprintf(stderr,"%s:%s lev 1 skipped due to strategy incronly and no full dump were done\n",
-               dp->host->hostname, dp->name);
+               dp->host->hostname, qname);
+       amfree(qname);
        return;
     }
 
@@ -772,26 +859,27 @@ setup_estimate(dp)
 
     if(dp->skip_incr && ep->next_level0 > 0) {
        fprintf(stderr,"%s:%s lev 1 skipped due to skip-incr flag\n",
-               dp->host->hostname, dp->name);
+               dp->host->hostname, qname);
        /* don't enqueue the disk */
        askfor(ep, 0, -1, &info);
        askfor(ep, 1, -1, &info);
        askfor(ep, 2, -1, &info);
 
        fprintf(stderr, "%s: SKIPPED %s %s 1 [skip-incr]\n",
-               get_pname(), dp->host->hostname, dp->name);
+               get_pname(), dp->host->hostname, qname);
 
        log_add(L_SUCCESS, "%s %s %s 1 [skipped: skip-incr]",
-               dp->host->hostname, dp->name, datestamp);
+               dp->host->hostname, qname, planner_timestamp);
+       amfree(qname);
        return;
     }
 
     if( ep->last_level == -1 && ep->next_level0 > 0 && 
        dp->strategy != DS_NOFULL && dp->strategy != DS_INCRONLY &&
        conf_reserve == 100) {
-       log_add(L_WARNING,
-            "%s:%s mismatch: no tapelist record, but curinfo next_level0: %d.",
-               dp->host->hostname, dp->name, ep->next_level0);
+       log_add(L_WARNING, "%s:%s mismatch: no tapelist record, "
+               "but curinfo next_level0: %d.",
+               dp->host->hostname, qname, ep->next_level0);
        ep->next_level0 = 0;
     }
 
@@ -817,21 +905,21 @@ setup_estimate(dp)
        if(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, dp->name);
+                   dp->host->hostname, qname);
        }
        switch (dp->strategy) {
        case DS_STANDARD: 
        case DS_NOINC:
            askfor(ep, i++, 0, &info);
            if(dp->skip_full) {
-               log_add(L_INFO,
-                  "Ignoring skip_full for %s:%s because the strategy is NOINC.",
-                       dp->host->hostname, dp->name);
+               log_add(L_INFO, "Ignoring skip_full for %s:%s "
+                       "because the strategy is NOINC.",
+                       dp->host->hostname, qname);
            }
            if(info.command & FORCE_BUMP) {
                log_add(L_INFO,
                 "Ignoring FORCE_BUMP for %s:%s because the strategy is NOINC.",
-                       dp->host->hostname, dp->name);
+                       dp->host->hostname, qname);
            }
            
            break;
@@ -863,12 +951,12 @@ setup_estimate(dp)
                    askfor(ep, i++, curr_level, &info);
                }
                log_add(L_INFO,"Preventing bump of %s:%s as directed.",
-                       dp->host->hostname, dp->name);
+                       dp->host->hostname, qname);
            } else if (ISSET(info.command, FORCE_BUMP)
                       && curr_level + 1 < DUMP_LEVELS) {
                askfor(ep, i++, curr_level+1, &info);
                log_add(L_INFO,"Bumping of %s:%s at level %d as directed.",
-                       dp->host->hostname, dp->name, curr_level+1);
+                       dp->host->hostname, qname, curr_level+1);
            } else if (curr_level == 0) {
                askfor(ep, i++, 1, &info);
            } else {
@@ -880,7 +968,7 @@ setup_estimate(dp)
                 * 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 == 0 || /* no data, try it anyway */
+               if((info.inf[curr_level].size == (off_t)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) {
@@ -895,23 +983,26 @@ setup_estimate(dp)
 
     /* debug output */
 
-    fprintf(stderr, "setup_estimate: %s:%s: command %d, options: %s    last_level %d next_level0 %d level_days %d    getting estimates %d (%ld) %d (%ld) %d (%ld)\n",
-           dp->host->hostname, dp->name, info.command,
+    fprintf(stderr, "setup_estimate: %s:%s: command %u, options: %s    "
+           "last_level %d next_level0 %d level_days %d    getting estimates "
+           "%d (" OFF_T_FMT ") %d (" OFF_T_FMT ") %d (" OFF_T_FMT ")\n",
+           dp->host->hostname, qname, info.command,
            dp->strategy == DS_NOFULL ? "no-full" :
                 dp->strategy == DS_INCRONLY ? "incr-only" :
                 dp->skip_full ? "skip-full" :
                 dp->skip_incr ? "skip-incr" : "none",
            ep->last_level, ep->next_level0, ep->level_days,
-           ep->level[0], ep->est_size[0],
-           ep->level[1], ep->est_size[1],
-           ep->level[2], ep->est_size[2]);
+           ep->level[0], (OFF_T_FMT_TYPE)ep->est_size[0],
+           ep->level[1], (OFF_T_FMT_TYPE)ep->est_size[1],
+           ep->level[2], (OFF_T_FMT_TYPE)ep->est_size[2]);
 
     assert(ep->level[0] != -1);
     enqueue_disk(&startq, dp);
+    amfree(qname);
 }
 
-static int when_overwrite(label)
-char *label;
+static int when_overwrite(
+    char *label)
 {
     tape_t *tp;
     int runtapes;
@@ -921,7 +1012,7 @@ char *label;
 
     if((tp = lookup_tapelabel(label)) == NULL)
        return 1;       /* "shouldn't happen", but trigger warning message */
-    else if(!reusable_tape(tp))
+    else if(tp->reuse == 0)
        return 1024;
     else if(lookup_nb_tape() > conf_tapecycle)
        return (lookup_nb_tape() - tp->position) / runtapes;
@@ -930,9 +1021,9 @@ char *label;
 }
 
 /* Return the estimated size for a particular dump */
-static long est_size(dp, level)
-disk_t *dp;
-int level;
+static off_t est_size(
+    disk_t *dp,
+    int level)
 {
     int i;
 
@@ -940,20 +1031,20 @@ int level;
        if(level == est(dp)->level[i])
            return est(dp)->est_size[i];
     }
-    return -1;
+    return (off_t)-1;
 }
 
 /* Return the estimated on-tape size of a particular dump */
-static long est_tape_size(dp, level)
-disk_t *dp;
-int level;
+static off_t est_tape_size(
+    disk_t *dp,
+    int level)
 {
-    long size;
+    off_t size;
     double ratio;
 
     size = est_size(dp, level);
 
-    if(size == -1) return size;
+    if(size == (off_t)-1) return size;
 
     if(dp->compress == COMP_NONE)
        return size;
@@ -972,15 +1063,15 @@ int level;
 
     if(ratio > 1.1) ratio = 1.1;
 
-    size *= ratio;
+    size = (off_t)((double)size * ratio);
 
     /*
      * Ratio can be very small in some error situations, so make sure
      * size goes back greater than zero.  It may not be right, but
      * indicates we did get an estimate.
      */
-    if(size <= 0) {
-       size = 1;
+    if(size <= (off_t)0) {
+       size = (off_t)1;
     }
 
     return size;
@@ -988,8 +1079,8 @@ int level;
 
 
 /* what was the level of the last successful dump to tape? */
-static int last_level(info)
-info_t *info;
+static int last_level(
+    info_t *info)
 {
     int min_pos, min_level, i;
     time_t lev0_date, last_date;
@@ -1030,9 +1121,9 @@ info_t *info;
 
 /* when is next level 0 due? 0 = today, 1 = tomorrow, etc*/
 static int
-next_level0(dp, info)
-     disk_t *dp;
-     info_t *info;
+next_level0(
+    disk_t *dp,
+    info_t *info)
 {
     if(dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY)
        return 1;               /* fake it */
@@ -1045,9 +1136,9 @@ next_level0(dp, info)
 }
 
 /* how many runs at current level? */
-static int runs_at(info, lev)
-info_t *info;
-int lev;
+static int runs_at(
+    info_t *info,
+    int lev)
 {
     tape_t *cur_tape, *old_tape;
     int last, nb_runs;
@@ -1074,24 +1165,24 @@ int lev;
 }
 
 
-static long bump_thresh(level, size_level_0, bumppercent, bumpsize, bumpmult)
-int level;
-long size_level_0;
-int bumppercent;
-int bumpsize;
-double bumpmult;
+static off_t bump_thresh(
+    int level,
+    off_t size_level_0,
+    int bumppercent,
+    off_t bumpsize,
+    double bumpmult)
 {
     double bump;
 
-    if(bumppercent != 0 && size_level_0 > 1024) {
-       bump = (size_level_0 * bumppercent)/100.0;
+    if ((bumppercent != 0) && (size_level_0 > (off_t)1024)) {
+       bump = ((double)size_level_0 * (double)bumppercent) / 100.0;
     }
     else {
-       bump = bumpsize;
+       bump = (double)bumpsize;
     }
     while(--level) bump = bump * bumpmult;
 
-    return (long)bump;
+    return (off_t)bump;
 }
 
 
@@ -1102,12 +1193,12 @@ double bumpmult;
  *
  */
 
-static void getsize P((am_host_t *hostp));
-static disk_t *lookup_hostdisk P((am_host_t *hp, char *str));
-static void handle_result P((void *datap, pkt_t *pkt, security_handle_t *sech));
+static void getsize(am_host_t *hostp);
+static disk_t *lookup_hostdisk(am_host_t *hp, char *str);
+static void handle_result(void *datap, pkt_t *pkt, security_handle_t *sech);
 
 
-static void get_estimates P((void))
+static void get_estimates(void)
 {
     am_host_t *hostp;
     disk_t *dp;
@@ -1140,77 +1231,75 @@ static void get_estimates P((void))
 
     while(!empty(pestq)) {
        disk_t *dp = dequeue_disk(&pestq);
-
-       if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < 0) {
-           if(est(dp)->est_size[0] == -1) {
-               log_add(L_WARNING,
-                       "disk %s:%s, estimate of level %d failed.",
-                       dp->host->hostname, dp->name,
-                       est(dp)->level[0]);
+       char *  qname = quote_string(dp->name);
+       
+       if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < (off_t)0) {
+           if(est(dp)->est_size[0] == (off_t)-1) {
+               log_add(L_WARNING, "disk %s:%s, estimate of level %d failed.",
+                       dp->host->hostname, qname, est(dp)->level[0]);
            }
            else {
                log_add(L_WARNING,
                        "disk %s:%s, estimate of level %d timed out.",
-                       dp->host->hostname, dp->name,
-                       est(dp)->level[0]);
+                       dp->host->hostname, qname, est(dp)->level[0]);
            }
            est(dp)->level[0] = -1;
        }
 
-       if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < 0) {
-           if(est(dp)->est_size[1] == -1) {
+       if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < (off_t)0) {
+           if(est(dp)->est_size[1] == (off_t)-1) {
                log_add(L_WARNING,
                        "disk %s:%s, estimate of level %d failed.",
-                       dp->host->hostname, dp->name,
-                       est(dp)->level[1]);
+                       dp->host->hostname, qname, est(dp)->level[1]);
            }
            else {
                log_add(L_WARNING,
                        "disk %s:%s, estimate of level %d timed out.",
-                       dp->host->hostname, dp->name,
-                       est(dp)->level[1]);
+                       dp->host->hostname, qname, est(dp)->level[1]);
            }
            est(dp)->level[1] = -1;
        }
 
-       if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < 0) {
-           if(est(dp)->est_size[2] == -1) {
+       if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < (off_t)0) {
+           if(est(dp)->est_size[2] == (off_t)-1) {
                log_add(L_WARNING,
                        "disk %s:%s, estimate of level %d failed.",
-                       dp->host->hostname, dp->name,
-                       est(dp)->level[2]);
+                       dp->host->hostname, qname, est(dp)->level[2]);
            }
            else {
                log_add(L_WARNING,
                        "disk %s:%s, estimate of level %d timed out.",
-                       dp->host->hostname, dp->name,
-                       est(dp)->level[2]);
+                       dp->host->hostname, qname, est(dp)->level[2]);
            }
            est(dp)->level[2] = -1;
        }
 
-       if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > 0) ||
-          (est(dp)->level[1] != -1 && est(dp)->est_size[1] > 0) ||
-          (est(dp)->level[2] != -1 && est(dp)->est_size[2] > 0)) {
+       if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > (off_t)0) ||
+          (est(dp)->level[1] != -1 && est(dp)->est_size[1] > (off_t)0) ||
+          (est(dp)->level[2] != -1 && est(dp)->est_size[2] > (off_t)0)) {
            enqueue_disk(&estq, dp);
        }
        else {
-          est(dp)->errstr = vstralloc("disk ", dp->name,
+          est(dp)->errstr = vstralloc("disk ", qname,
                                       ", all estimate timed out", NULL);
           enqueue_disk(&failq, dp);
        }
+       amfree(qname);
     }
 }
 
-static void getsize(hostp)
-am_host_t *hostp;
+static void getsize(
+    am_host_t *hostp)
 {
-    char number[NUM_STR_SIZE], *req;
-    disk_t *dp;
-    int i, estimates, timeout, req_len;
-    const security_driver_t *secdrv;
-    char *dumper;
-    char *calcsize;
+    char       number[NUM_STR_SIZE], *req;
+    disk_t *   dp;
+    int                i;
+    time_t     estimates, timeout;
+    size_t     req_len;
+    const      security_driver_t *secdrv;
+    char *     dumper;
+    char *     calcsize;
+    char *     qname;
 
     assert(hostp->disks != NULL);
 
@@ -1235,8 +1324,10 @@ am_host_t *hostp;
                                          fe_req_options_hostname);
        int has_maxdumps = am_has_feature(hostp->features,
                                          fe_req_options_maxdumps);
+       int has_config   = am_has_feature(hostp->features,
+                                         fe_req_options_config);
 
-       snprintf(number, sizeof(number), "%d", hostp->maxdumps);
+       snprintf(number, SIZEOF(number), "%d", hostp->maxdumps);
        req = vstralloc("SERVICE ", "sendsize", "\n",
                        "OPTIONS ",
                        has_features ? "features=" : "",
@@ -1248,14 +1339,17 @@ am_host_t *hostp;
                        has_hostname ? "hostname=" : "",
                        has_hostname ? hostp->hostname : "",
                        has_hostname ? ";" : "",
+                       has_config   ? "config=" : "",
+                       has_config   ? config_name : "",
+                       has_config   ? ";" : "",
                        "\n",
                        NULL);
        req_len = strlen(req);
-       req_len += 128;                             /* room for SECURITY ... */
+       req_len += 128;                 /* room for SECURITY ... */
        estimates = 0;
        for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
            char *s = NULL;
-           int s_len = 0;
+           size_t s_len = 0;
 
            if(dp->todo == 0) continue;
 
@@ -1267,6 +1361,7 @@ am_host_t *hostp;
                continue;
            }
 
+           qname = quote_string(dp->name);
            if(dp->estimate == ES_CLIENT ||
               dp->estimate == ES_CALCSIZE) {
                nb_client++;
@@ -1276,36 +1371,61 @@ am_host_t *hostp;
                    char *exclude1 = "";
                    char *exclude2 = "";
                    char *excludefree = NULL;
+                   char *include1 = "";
+                   char *include2 = "";
+                   char *includefree = NULL;
                    char spindle[NUM_STR_SIZE];
                    char level[NUM_STR_SIZE];
                    int lev = est(dp)->level[i];
 
                    if(lev == -1) break;
 
-                   snprintf(level, sizeof(level), "%d", lev);
-                   snprintf(spindle, sizeof(spindle), "%d", dp->spindle);
+                   snprintf(level, SIZEOF(level), "%d", lev);
+                   snprintf(spindle, SIZEOF(spindle), "%d", dp->spindle);
                    if(am_has_feature(hostp->features,fe_sendsize_req_options)){
                        exclude1 = " OPTIONS |";
                        exclude2 = optionstr(dp, hostp->features, NULL);
+                       if ( exclude2 == NULL ) {
+                         error("problem with option string, check the dumptype definition.\n");
+                       }
                        excludefree = exclude2;
+                       includefree = NULL;
                    }
                    else {
                        if(dp->exclude_file &&
                           dp->exclude_file->nb_element == 1) {
                            exclude1 = " exclude-file=";
-                           exclude2 = dp->exclude_file->first->name;
+                           exclude2 =
+                               quote_string(dp->exclude_file->first->name);
+                           excludefree = exclude2;
                        }
                        else if(dp->exclude_list &&
                                dp->exclude_list->nb_element == 1) {
                            exclude1 = " exclude-list=";
-                           exclude2 = dp->exclude_list->first->name;
+                           exclude2 =
+                               quote_string(dp->exclude_list->first->name);
+                           excludefree = exclude2;
+                       }
+                       if(dp->include_file &&
+                          dp->include_file->nb_element == 1) {
+                           include1 = " include-file=";
+                           include2 =
+                               quote_string(dp->include_file->first->name);
+                           includefree = include2;
+                       }
+                       else if(dp->include_list &&
+                               dp->include_list->nb_element == 1) {
+                           include1 = " include-list=";
+                           include2 =
+                               quote_string(dp->include_list->first->name);
+                           includefree = include2;
                        }
                    }
 
                    if(dp->estimate == ES_CALCSIZE &&
                       !am_has_feature(hostp->features, fe_calcsize_estimate)) {
                        log_add(L_WARNING,"%s:%s does not support CALCSIZE for estimate, using CLIENT.\n",
-                               hostp->hostname, dp->name);
+                               hostp->hostname, qname);
                        dp->estimate = ES_CLIENT;
                    }
                    if(dp->estimate == ES_CLIENT)
@@ -1322,26 +1442,22 @@ am_host_t *hostp;
                    l = vstralloc(calcsize,
                                  dumper,
                                  dp->program,
-                                 " ", dp->name,
+                                 " ", qname,
                                  " ", dp->device ? dp->device : "",
                                  " ", level,
                                  " ", est(dp)->dumpdate[i],
                                  " ", spindle,
                                  " ", exclude1, exclude2,
+                                 ((includefree != NULL) ? " " : ""),
+                                   include1, include2,
                                  "\n",
                                  NULL);
                    strappend(s, l);
                    s_len += strlen(l);
                    amfree(l);
+                   amfree(includefree);
                    amfree(excludefree);
                }
-               /*
-                * Allow 2X for err response.
-                */
-               if(req_len + s_len > MAX_PACKET / 2) {
-                   amfree(s);
-                   break;
-               }
                if (s != NULL) {
                    estimates += i;
                    strappend(req, s);
@@ -1361,12 +1477,12 @@ am_host_t *hostp;
 
                    if(lev == -1) break;
                    if(lev == 0) { /* use latest level 0, should do extrapolation */
-                       long est_size = 0;
+                       off_t est_size = (off_t)0;
                        int nb_est = 0;
 
                        for(j=NB_HISTORY-2;j>=0;j--) {
                            if(info.history[j].level == 0) {
-                               if(info.history[j].size < 0) continue;
+                               if(info.history[j].size < (off_t)0) continue;
                                est_size = info.history[j].size;
                                nb_est++;
                            }
@@ -1374,27 +1490,27 @@ am_host_t *hostp;
                        if(nb_est > 0) {
                            est(dp)->est_size[i] = est_size;
                        }
-                       else if(info.inf[lev].size > 1000) { /* stats */
+                       else if(info.inf[lev].size > (off_t)1000) { /* stats */
                            est(dp)->est_size[i] = info.inf[lev].size;
                        }
                        else {
-                           est(dp)->est_size[i] = 1000000;
+                           est(dp)->est_size[i] = (off_t)1000000;
                        }
                    }
                    else if(lev == est(dp)->last_level) {
                        /* means of all X day at the same level */
                        #define NB_DAY 30
                        int nb_day = 0;
-                       long est_size_day[NB_DAY];
+                       off_t est_size_day[NB_DAY];
                        int nb_est_day[NB_DAY];
                        for(j=0;j<NB_DAY;j++) {
-                           est_size_day[j]=0;
+                           est_size_day[j]=(off_t)0;
                            nb_est_day[j]=0;
                        }
 
                        for(j=NB_HISTORY-2;j>=0;j--) {
                            if(info.history[j].level <= 0) continue;
-                           if(info.history[j].size < 0) continue;
+                           if(info.history[j].size < (off_t)0) continue;
                            if(info.history[j].level==info.history[j+1].level) {
                                if(nb_day <NB_DAY-1) nb_day++;
                                est_size_day[nb_day] += info.history[j].size;
@@ -1410,51 +1526,52 @@ am_host_t *hostp;
                        while(nb_day > 0 && nb_est_day[nb_day] == 0) nb_day--;
 
                        if(nb_est_day[nb_day] > 0) {
-                           est(dp)->est_size[i] =
-                                   est_size_day[nb_day] / nb_est_day[nb_day];
+                           est(dp)->est_size[i] = est_size_day[nb_day] /
+                                       (off_t)nb_est_day[nb_day];
                        }
-                       else if(info.inf[lev].size > 1000) { /* stats */
+                       else if(info.inf[lev].size > (off_t)1000) { /* stats */
                            est(dp)->est_size[i] = info.inf[lev].size;
                        }
                        else {
-                           est(dp)->est_size[i] = 10000;
+                           est(dp)->est_size[i] = (off_t)10000;
                        }
                    }
                    else if(lev == est(dp)->last_level + 1) {
                        /* means of all first day at a new level */
-                       long est_size = 0;
+                       off_t est_size = (off_t)0;
                        int nb_est = 0;
 
                        for(j=NB_HISTORY-2;j>=0;j--) {
                            if(info.history[j].level <= 0) continue;
-                           if(info.history[j].size < 0) continue;
+                           if(info.history[j].size < (off_t)0) continue;
                            if(info.history[j].level == info.history[j+1].level + 1 ) {
                                est_size += info.history[j].size;
                                nb_est++;
                            }
                        }
                        if(nb_est > 0) {
-                           est(dp)->est_size[i] = est_size / nb_est;
+                           est(dp)->est_size[i] = est_size / (off_t)nb_est;
                        }
-                       else if(info.inf[lev].size > 1000) { /* stats */
+                       else if(info.inf[lev].size > (off_t)1000) { /* stats */
                            est(dp)->est_size[i] = info.inf[lev].size;
                        }
                        else {
-                           est(dp)->est_size[i] = 100000;
+                           est(dp)->est_size[i] = (off_t)100000;
                        }
                    }
-               }
+               }
                fprintf(stderr,"%s time %s: got result for host %s disk %s:",
                        get_pname(), walltime_str(curclock()),
-                       dp->host->hostname, dp->name);
-               fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n",
-                       est(dp)->level[0], est(dp)->est_size[0],
-                       est(dp)->level[1], est(dp)->est_size[1],
-                       est(dp)->level[2], est(dp)->est_size[2]);
+                       dp->host->hostname, qname);
+               fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
+                       est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
+                       est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
+                       est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
                est(dp)->state = DISK_DONE;
                remove_disk(&startq, dp);
                enqueue_disk(&estq, dp);
            }
+           amfree(qname);
        }
 
        if(estimates == 0) {
@@ -1478,13 +1595,14 @@ am_host_t *hostp;
         * We use ctimeout for the "noop" request because it should be
         * very fast and etimeout has other side effects.
         */
-       timeout = getconf_int(CNF_CTIMEOUT);
+       timeout = getconf_time(CNF_CTIMEOUT);
     }
 
     secdrv = security_getdriver(hostp->disks->security_driver);
     if (secdrv == NULL) {
        error("could not find security driver '%s' for host '%s'",
            hostp->disks->security_driver, hostp->hostname);
+       /*NOTREACHED*/
     }
     hostp->up = HOST_ACTIVE;
 
@@ -1498,14 +1616,14 @@ am_host_t *hostp;
        }
     }
 
-    protocol_sendreq(hostp->hostname, secdrv, generic_get_security_conf, 
+    protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf, 
        req, timeout, handle_result, hostp);
     amfree(req);
 }
 
-static disk_t *lookup_hostdisk(hp, str)
-am_host_t *hp;
-char *str;
+static disk_t *lookup_hostdisk(
+    /*@keep@*/ am_host_t *hp,
+    char *str)
 {
     disk_t *dp;
 
@@ -1516,13 +1634,13 @@ char *str;
 }
 
 
-static void handle_result(datap, pkt, sech)
-void *datap;
-pkt_t *pkt;
-security_handle_t *sech;
+static void handle_result(
+    void *datap,
+    pkt_t *pkt,
+    security_handle_t *sech)
 {
     int level, i;
-    long size;
+    off_t size;
     disk_t *dp;
     am_host_t *hostp;
     char *msgdisk=NULL, *msgdisk_undo=NULL, msgdisk_undo_ch = '\0';
@@ -1533,6 +1651,8 @@ security_handle_t *sech;
     char *line;
     int ch;
     int tch;
+    char *qname;
+    char *disk;
 
     hostp = (am_host_t *)datap;
     hostp->up = HOST_READY;
@@ -1544,8 +1664,8 @@ security_handle_t *sech;
     }
     if (pkt->type == P_NAK) {
 #define sc "ERROR "
-       if(strncmp(pkt->body, sc, sizeof(sc)-1) == 0) {
-           s = pkt->body + sizeof(sc)-1;
+       if(strncmp(pkt->body, sc, SIZEOF(sc)-1) == 0) {
+           s = pkt->body + SIZEOF(sc)-1;
            ch = *s++;
 #undef sc
        } else {
@@ -1559,7 +1679,7 @@ security_handle_t *sech;
                *s = '\0';
        }
        if (strcmp(remoterr, "unknown service: noop") != 0
-                  && strcmp(remoterr, "noop: invalid service") != 0) {
+               && strcmp(remoterr, "noop: invalid service") != 0) {
            errbuf = vstralloc(hostp->hostname, " NAK: ", remoterr, NULL);
            if(s) *s = '\n';
            goto error_return;
@@ -1571,19 +1691,15 @@ security_handle_t *sech;
     ch = *s++;
     while(ch) {
        line = s - 1;
-       skip_line(s, ch);
-       if (s[-2] == '\n') {
-           s[-2] = '\0';
-       }
 
 #define sc "OPTIONS "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
 #undef sc
 
 #define sc "features="
            t = strstr(line, sc);
            if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
-               t += sizeof(sc)-1;
+               t += SIZEOF(sc)-1;
 #undef sc
                am_release_feature_set(hostp->features);
                if((hostp->features = am_string_to_feature(t)) == NULL) {
@@ -1595,13 +1711,13 @@ security_handle_t *sech;
                    goto error_return;
                }
            }
-
+           skip_quoted_line(s, ch);
            continue;
        }
 
 #define sc "ERROR "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
-           t = line + sizeof(sc)-1;
+       if(strncmp(line, sc, SIZEOF(sc) - 1) == 0) {
+           t = line + SIZEOF(sc) - 1;
            tch = t[-1];
 #undef sc
 
@@ -1610,6 +1726,7 @@ security_handle_t *sech;
            if (tch == '\n') {
                t[-1] = '\0';
            }
+
            /*
             * If the "error" is that the "noop" service is unknown, it
             * just means the client is "old" (does not support the servie).
@@ -1618,31 +1735,34 @@ security_handle_t *sech;
            if(hostp->features == NULL
               && pkt->type == P_NAK
               && (strcmp(t - 1, "unknown service: noop") == 0
-                  || strcmp(t - 1, "noop: invalid service") == 0)) {
+                  || strcmp(t - 1, "noop: invalid service") == 0)) {
                continue;
-           } else {
-               errbuf = vstralloc(hostp->hostname,
-                                  (pkt->type == P_NAK) ? "NAK " : "",
-                                  ": ",
-                                  fp,
-                                  NULL);
-               goto error_return;
            }
+           errbuf = vstralloc(hostp->hostname,
+                                  (pkt->type == P_NAK) ? "NAK " : "",
+                                  ": ",
+                                  fp,
+                                  NULL);
+           goto error_return;
        }
 
        msgdisk = t = line;
-       tch = *t++;
-       skip_non_whitespace(t, tch);
+       tch = *(t++);
+       skip_quoted_string(t, tch);
        msgdisk_undo = t - 1;
        msgdisk_undo_ch = *msgdisk_undo;
        *msgdisk_undo = '\0';
-
+       disk = unquote_string(msgdisk);
        skip_whitespace(t, tch);
-       if (sscanf(t - 1, "%d SIZE %ld", &level, &size) != 2) {
+       s = t;
+       ch = tch;
+
+       if (sscanf(t - 1, "%d SIZE " OFF_T_FMT , &level,
+                  (OFF_T_FMT_TYPE *)&size) != 2) {
            goto bad_msg;
        }
-
-       dp = lookup_hostdisk(hostp, msgdisk);
+       dp = lookup_hostdisk(hostp, disk);
+       amfree(disk);
 
        *msgdisk_undo = msgdisk_undo_ch;        /* for error message */
        msgdisk_undo = NULL;
@@ -1662,6 +1782,7 @@ security_handle_t *sech;
            }
            est(dp)->got_estimate++;
        }
+       skip_quoted_line(s, ch);
     }
 
     if(hostp->up == HOST_READY && hostp->features == NULL) {
@@ -1674,6 +1795,7 @@ security_handle_t *sech;
        hostp->features = am_set_default_feature_set();
     }
 
+    security_close_connection(sech, hostp->hostname);
 
     /* XXX what about disks that only got some estimates...  do we care? */
     /* XXX amanda 2.1 treated that case as a bad msg */
@@ -1700,47 +1822,46 @@ security_handle_t *sech;
        if(est(dp)->level[0] == -1) continue;   /* ignore this disk */
 
 
+       qname = quote_string(dp->name);
        if(pkt->type == P_PREP) {
                fprintf(stderr,"%s: time %s: got partial result for host %s disk %s:",
                        get_pname(), walltime_str(curclock()),
-                       dp->host->hostname, dp->name);
-               fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n",
-                       est(dp)->level[0], est(dp)->est_size[0],
-                       est(dp)->level[1], est(dp)->est_size[1],
-                       est(dp)->level[2], est(dp)->est_size[2]);
+                       dp->host->hostname, qname);
+               fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
+                       est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
+                       est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
+                       est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
            enqueue_disk(&pestq, dp);
        }
        else if(pkt->type == P_REP) {
                fprintf(stderr,"%s: time %s: got result for host %s disk %s:",
                        get_pname(), walltime_str(curclock()),
-                       dp->host->hostname, dp->name);
-               fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n",
-                       est(dp)->level[0], est(dp)->est_size[0],
-                       est(dp)->level[1], est(dp)->est_size[1],
-                       est(dp)->level[2], est(dp)->est_size[2]);
-               if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > 0) ||
-                  (est(dp)->level[1] != -1 && est(dp)->est_size[1] > 0) ||
-                  (est(dp)->level[2] != -1 && est(dp)->est_size[2] > 0)) {
-
-                   if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < 0) {
+                       dp->host->hostname, qname);
+               fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
+                       est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
+                       est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
+                       est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
+               if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > (off_t)0) ||
+                  (est(dp)->level[1] != -1 && est(dp)->est_size[1] > (off_t)0) ||
+                  (est(dp)->level[2] != -1 && est(dp)->est_size[2] > (off_t)0)) {
+
+                   if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < (off_t)0) {
                        log_add(L_WARNING,
                                "disk %s:%s, estimate of level %d failed.",
-                               dp->host->hostname, dp->name,
-                               est(dp)->level[2]);
+                               dp->host->hostname, qname, est(dp)->level[2]);
                        est(dp)->level[2] = -1;
                    }
-                   if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < 0) {
+                   if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < (off_t)0) {
                        log_add(L_WARNING,
                                "disk %s:%s, estimate of level %d failed.",
-                               dp->host->hostname, dp->name,
+                               dp->host->hostname, qname,
                                est(dp)->level[1]);
                        est(dp)->level[1] = -1;
                    }
-                   if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < 0) {
+                   if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < (off_t)0) {
                        log_add(L_WARNING,
                                "disk %s:%s, estimate of level %d failed.",
-                               dp->host->hostname, dp->name,
-                               est(dp)->level[0]);
+                               dp->host->hostname, qname, est(dp)->level[0]);
                        est(dp)->level[0] = -1;
                    }
                    enqueue_disk(&estq, dp);
@@ -1748,19 +1869,20 @@ security_handle_t *sech;
            else {
                enqueue_disk(&failq, dp);
                if(est(dp)->got_estimate) {
-                   est(dp)->errstr = vstralloc("disk ", dp->name,
+                   est(dp)->errstr = vstralloc("disk ", qname,
                                                ", all estimate failed", NULL);
                }
                else {
                    fprintf(stderr, "error result for host %s disk %s: missing estimate\n",
-                           dp->host->hostname, dp->name);
-                   est(dp)->errstr = vstralloc("missing result for ", dp->name,
+                           dp->host->hostname, qname);
+                   est(dp)->errstr = vstralloc("missing result for ", qname,
                                                " in ", dp->host->hostname,
                                                " response",
                                                NULL);
                }
            }
        }
+       amfree(qname);
     }
     getsize(hostp);
     return;
@@ -1778,21 +1900,21 @@ security_handle_t *sech;
     goto error_return;
 
  bad_msg:
-
     if(msgdisk_undo) {
        *msgdisk_undo = msgdisk_undo_ch;
        msgdisk_undo = NULL;
     }
     fprintf(stderr,"got a bad message, stopped at:\n");
+    /*@ignore@*/
     fprintf(stderr,"----\n%s----\n\n", line);
     errbuf = stralloc2("badly formatted response from ", hostp->hostname);
-    /* fall through to ... */
+    /*@end@*/
 
  error_return:
-
     i = 0;
     for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
        if(est(dp)->state != DISK_ACTIVE) continue;
+       qname = quote_string(dp->name);
        est(dp)->state = DISK_DONE;
        if(est(dp)->state == DISK_ACTIVE) {
            est(dp)->state = DISK_DONE;
@@ -1802,8 +1924,9 @@ security_handle_t *sech;
 
            est(dp)->errstr = stralloc(errbuf);
            fprintf(stderr, "error result for host %s disk %s: %s\n",
-               dp->host->hostname, dp->name, errbuf);
+                   dp->host->hostname, qname, errbuf);
        }
+       amfree(qname);
     }
     if(i == 0) {
        /*
@@ -1825,20 +1948,21 @@ security_handle_t *sech;
  *
  */
 
-static int schedule_order P((disk_t *a, disk_t *b));     /* subroutines */
-static int pick_inclevel P((disk_t *dp));
+static int schedule_order(disk_t *a, disk_t *b);         /* subroutines */
+static int pick_inclevel(disk_t *dp);
 
-static void analyze_estimate(dp)
-disk_t *dp;
+static void analyze_estimate(
+    disk_t *dp)
 {
     est_t *ep;
     info_t info;
     int have_info = 0;
+    char *qname = quote_string(dp->name);
 
     ep = est(dp);
 
     fprintf(stderr, "pondering %s:%s... ",
-           dp->host->hostname, dp->name);
+           dp->host->hostname, qname);
     fprintf(stderr, "next_level0 %d last_level %d ",
            ep->next_level0, ep->last_level);
 
@@ -1847,44 +1971,51 @@ disk_t *dp;
     }
 
     ep->degr_level = -1;
-    ep->degr_size = -1;
+    ep->degr_nsize = (off_t)-1;
+    ep->degr_csize = (off_t)-1;
 
-    if(ep->next_level0 <= 0
-       || (have_info && ep->last_level == 0 && (info.command & FORCE_NO_BUMP))) {
+    if(ep->next_level0 <= 0 || (have_info && ep->last_level == 0
+       && (info.command & FORCE_NO_BUMP))) {
        if(ep->next_level0 <= 0) {
            fprintf(stderr,"(due for level 0) ");
        }
        ep->dump_level = 0;
-       ep->dump_size = est_tape_size(dp, 0);
-       if(ep->dump_size <= 0) {
+       ep->dump_nsize = est_size(dp, 0);
+       ep->dump_csize = est_tape_size(dp, 0);
+       if(ep->dump_csize <= (off_t)0) {
            fprintf(stderr,
                    "(no estimate for level 0, picking an incr level)\n");
            ep->dump_level = pick_inclevel(dp);
-           ep->dump_size = est_tape_size(dp, ep->dump_level);
+           ep->dump_nsize = est_size(dp, ep->dump_level);
+           ep->dump_csize = est_tape_size(dp, ep->dump_level);
 
-           if(ep->dump_size == -1) {
+           if(ep->dump_nsize == (off_t)-1) {
                ep->dump_level = ep->dump_level + 1;
-               ep->dump_size = est_tape_size(dp, ep->dump_level);
+               ep->dump_nsize = est_size(dp, ep->dump_level);
+               ep->dump_csize = est_tape_size(dp, ep->dump_level);
            }
        }
        else {
-           total_lev0 += (double) ep->dump_size;
+           total_lev0 += (double) ep->dump_csize;
            if(ep->last_level == -1 || dp->skip_incr) {
                fprintf(stderr,"(%s disk, can't switch to degraded mode)\n",
                        dp->skip_incr? "skip-incr":"new");
                ep->degr_level = -1;
-               ep->degr_size = -1;
+               ep->degr_nsize = (off_t)-1;
+               ep->degr_csize = (off_t)-1;
            }
            else {
                /* fill in degraded mode info */
                fprintf(stderr,"(picking inclevel for degraded mode)");
                ep->degr_level = pick_inclevel(dp);
-               ep->degr_size = est_tape_size(dp, ep->degr_level);
-               if(ep->degr_size == -1) {
+               ep->degr_nsize = est_size(dp, ep->degr_level);
+               ep->degr_csize = est_tape_size(dp, ep->degr_level);
+               if(ep->degr_csize == (off_t)-1) {
                    ep->degr_level = ep->degr_level + 1;
-                   ep->degr_size = est_tape_size(dp, ep->degr_level);
+                   ep->degr_nsize = est_size(dp, ep->degr_level);
+                   ep->degr_csize = est_tape_size(dp, ep->degr_level);
                }
-               if(ep->degr_size == -1) {
+               if(ep->degr_csize == (off_t)-1) {
                    fprintf(stderr,"(no inc estimate)");
                    ep->degr_level = -1;
                }
@@ -1896,47 +2027,55 @@ disk_t *dp;
        fprintf(stderr,"(not due for a full dump, picking an incr level)\n");
        /* XXX - if this returns -1 may be we should force a total? */
        ep->dump_level = pick_inclevel(dp);
-       ep->dump_size = est_tape_size(dp, ep->dump_level);
+       ep->dump_nsize = est_size(dp, ep->dump_level);
+       ep->dump_csize = est_tape_size(dp, ep->dump_level);
 
-       if(ep->dump_size == -1) {
+       if(ep->dump_csize == (off_t)-1) {
            ep->dump_level = ep->last_level;
-           ep->dump_size = est_tape_size(dp, ep->dump_level);
+           ep->dump_nsize = est_size(dp, ep->dump_level);
+           ep->dump_csize = est_tape_size(dp, ep->dump_level);
        }
-       if(ep->dump_size == -1) {
+       if(ep->dump_csize == (off_t)-1) {
            ep->dump_level = ep->last_level + 1;
-           ep->dump_size = est_tape_size(dp, ep->dump_level);
+           ep->dump_nsize = est_size(dp, ep->dump_level);
+           ep->dump_csize = est_tape_size(dp, ep->dump_level);
        }
-       if(ep->dump_size == -1) {
+       if(ep->dump_csize == (off_t)-1) {
            ep->dump_level = 0;
-           ep->dump_size = est_tape_size(dp, ep->dump_level);
+           ep->dump_nsize = est_size(dp, ep->dump_level);
+           ep->dump_csize = est_tape_size(dp, ep->dump_level);
        }
     }
 
-    fprintf(stderr,"  curr level %d size %ld ", ep->dump_level, ep->dump_size);
+    fprintf(stderr,"  curr level %d nsize " OFF_T_FMT " csize " OFF_T_FMT " ",
+           ep->dump_level, (OFF_T_FMT_TYPE)ep->dump_nsize, 
+            (OFF_T_FMT_TYPE)ep->dump_csize);
 
     insert_disk(&schedq, dp, schedule_order);
 
-    total_size += tt_blocksize_kb + ep->dump_size + tape_mark;
+    total_size += (off_t)tt_blocksize_kb + ep->dump_csize + tape_mark;
 
     /* update the balanced size */
     if(!(dp->skip_full || dp->strategy == DS_NOFULL || 
         dp->strategy == DS_INCRONLY)) {
-       long lev0size;
+       off_t lev0size;
 
        lev0size = est_tape_size(dp, 0);
-       if(lev0size == -1) lev0size = ep->last_lev0size;
+       if(lev0size == (off_t)-1) lev0size = ep->last_lev0size;
 
-       balanced_size += lev0size / runs_per_cycle;
+       balanced_size += (double)(lev0size / (off_t)runs_per_cycle);
     }
 
-    fprintf(stderr,"total size " AM64_FMT " total_lev0 %1.0f balanced-lev0size %1.0f\n",
-           total_size, total_lev0, balanced_size);
+    fprintf(stderr,"total size " OFF_T_FMT " total_lev0 %1.0lf balanced-lev0size %1.0lf\n",
+           (OFF_T_FMT_TYPE)total_size, total_lev0, balanced_size);
+    amfree(qname);
 }
 
-static void handle_failed(dp)
-disk_t *dp;
+static void handle_failed(
+    disk_t *dp)
 {
     char *errstr;
+    char *qname = quote_string(dp->name);
 
 /*
  * From George Scott <George.Scott@cc.monash.edu.au>:
@@ -1954,9 +2093,10 @@ disk_t *dp;
 #ifdef old_behavior
     if(est(dp)->last_level != -1) {
        log_add(L_WARNING,
-               "Could not get estimate for %s:%s, using historical data.",
-               dp->host->hostname, dp->name);
+               "Could not get estimate for %s:%s, using historical data.",
+               dp->host->hostname, qname);
        analyze_estimate(dp);
+       amfree(qname);
        return;
     }
 #endif
@@ -1964,41 +2104,45 @@ disk_t *dp;
     errstr = est(dp)->errstr? est(dp)->errstr : "hmm, no error indicator!";
 
     fprintf(stderr, "%s: FAILED %s %s %s 0 [%s]\n",
-       get_pname(), dp->host->hostname, dp->name, datestamp, errstr);
+       get_pname(), dp->host->hostname, qname, planner_timestamp, errstr);
 
-    log_add(L_FAIL, "%s %s %s 0 [%s]", dp->host->hostname, dp->name, 
-           datestamp, errstr);
+    log_add(L_FAIL, "%s %s %s 0 [%s]", dp->host->hostname, qname, 
+           planner_timestamp, errstr);
 
+    amfree(qname);
     /* XXX - memory leak with *dp */
 }
 
 
-static int schedule_order(a, b)
-disk_t *a, *b;
 /*
  * insert-sort by decreasing priority, then
  * by decreasing size within priority levels.
  */
+
+static int schedule_order(
+    disk_t *a,
+    disk_t *b)
 {
     int diff;
-    long ldiff;
+    off_t ldiff;
 
     diff = est(b)->dump_priority - est(a)->dump_priority;
     if(diff != 0) return diff;
 
-    ldiff = est(b)->dump_size - est(a)->dump_size;
-    if(ldiff < 0) return -1; /* XXX - there has to be a better way to dothis */
-    if(ldiff > 0) return 1;
+    ldiff = est(b)->dump_csize - est(a)->dump_csize;
+    if(ldiff < (off_t)0) return -1; /* XXX - there has to be a better way to dothis */
+    if(ldiff > (off_t)0) return 1;
     return 0;
 }
 
 
-static int pick_inclevel(dp)
-disk_t *dp;
+static int pick_inclevel(
+    disk_t *dp)
 {
     int base_level, bump_level;
-    long base_size, bump_size;
-    long thresh;
+    off_t base_size, bump_size;
+    off_t thresh;
+    char *qname;
 
     base_level = est(dp)->last_level;
 
@@ -2017,9 +2161,9 @@ disk_t *dp;
     base_size = est_size(dp, base_level);
 
     /* if we didn't get an estimate, we can't do an inc */
-    if(base_size == -1) {
+    if(base_size == (off_t)-1) {
        base_size = est_size(dp, base_level+1);
-       if(base_size > 0) /* FORCE_BUMP */
+       if(base_size > (off_t)0) /* FORCE_BUMP */
            return base_level+1;
        fprintf(stderr,"   picklev: no estimate for level %d, so no incs\n", base_level);
        return base_level;
@@ -2028,9 +2172,9 @@ disk_t *dp;
     thresh = bump_thresh(base_level, est_size(dp, 0), dp->bumppercent, dp->bumpsize, dp->bumpmult);
 
     fprintf(stderr,
-           "   pick: size %ld level %d days %d (thresh %ldK, %d days)\n",
-           base_size, base_level, est(dp)->level_days,
-           thresh, dp->bumpdays);
+           "   pick: size " OFF_T_FMT " level %d days %d (thresh " OFF_T_FMT "K, %d days)\n",
+           (OFF_T_FMT_TYPE)base_size, base_level, est(dp)->level_days,
+           (OFF_T_FMT_TYPE)thresh, dp->bumpdays);
 
     if(base_level == 9
        || est(dp)->level_days < dp->bumpdays
@@ -2040,18 +2184,21 @@ disk_t *dp;
     bump_level = base_level + 1;
     bump_size = est_size(dp, bump_level);
 
-    if(bump_size == -1) return base_level;
+    if(bump_size == (off_t)-1) return base_level;
 
-    fprintf(stderr, "   pick: next size %ld... ", bump_size);
+    fprintf(stderr, "   pick: next size " OFF_T_FMT "... ",
+           (OFF_T_FMT_TYPE)bump_size);
 
     if(base_size - bump_size < thresh) {
        fprintf(stderr, "not bumped\n");
        return base_level;
     }
 
+    qname = quote_string(dp->name);
     fprintf(stderr, "BUMPED\n");
     log_add(L_INFO, "Incremental of %s:%s bumped to level %d.",
-           dp->host->hostname, dp->name, bump_level);
+           dp->host->hostname, qname, bump_level);
+    amfree(qname);
 
     return bump_level;
 }
@@ -2083,19 +2230,25 @@ disk_t *dp;
 ** more balanced cycle.
 */
 
-static void delay_one_dump P((disk_t *dp, int delete, ...));
+static void delay_one_dump(disk_t *dp, int delete, ...);
+static int promote_highest_priority_incremental(void);
+static int promote_hills(void);
 
-static void delay_dumps P((void))
 /* delay any dumps that will not fit */
+static void delay_dumps(void)
 {
-    disk_t *dp, *ndp, *preserve;
-    bi_t *bi, *nbi;
-    am64_t new_total;  /* New total_size */
-    char est_kb[20];     /* Text formatted dump size */
-    int nb_forced_level_0;
-    info_t info;
-    int delete;
-    char *message;
+    disk_t *   dp;
+    disk_t *   ndp;
+    disk_t *   preserve;
+    bi_t *     bi;
+    bi_t  *    nbi;
+    off_t      new_total;              /* New total_size */
+    char       est_kb[20];             /* Text formatted dump size */
+    int                nb_forced_level_0;
+    info_t     info;
+    int                delete;
+    char *     message;
+    off_t      full_size;
 
     biq.head = biq.tail = NULL;
 
@@ -2112,18 +2265,29 @@ static void delay_dumps P((void))
 
     for(dp = schedq.head; dp != NULL; dp = ndp) {
        int avail_tapes = 1;
-       if (dp->tape_splitsize > 0)
+       if (dp->tape_splitsize > (off_t)0)
            avail_tapes = conf_runtapes;
 
        ndp = dp->next; /* remove_disk zaps this */
 
-       if (est(dp)->dump_size == -1 ||
-           est(dp)->dump_size <= tape->length * avail_tapes) {
+       full_size = est_tape_size(dp, 0);
+       if (full_size > tapetype_get_length(tape) * (off_t)avail_tapes) {
+           char *qname = quote_string(dp->name);
+           log_add(L_WARNING, "disk %s:%s, full dump (" OFF_T_FMT 
+                   "KB) will be larger than available tape space",
+                   dp->host->hostname, qname,
+                   (OFF_T_FMT_TYPE)full_size);
+           amfree(qname);
+       }
+
+       if (est(dp)->dump_csize == (off_t)-1 ||
+           est(dp)->dump_csize <= tapetype_get_length(tape) * (off_t)avail_tapes) {
            continue;
        }
 
-        /* Format dumpsize for messages */
-       snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+       /* Format dumpsize for messages */
+       snprintf(est_kb, 20, OFF_T_FMT " KB,",
+                (OFF_T_FMT_TYPE)est(dp)->dump_csize);
 
        if(est(dp)->dump_level == 0) {
            if(dp->skip_incr) {
@@ -2138,7 +2302,7 @@ static void delay_dumps P((void))
                delete = 1;
                message = "but no incremental estimate";
            }
-           else if (est(dp)->degr_size > tape->length) {
+           else if (est(dp)->degr_csize > tapetype_get_length(tape)) {
                delete = 1;
                message = "incremental dump also larger than tape";
            }
@@ -2151,8 +2315,8 @@ static void delay_dumps P((void))
            delete = 1;
            message = "skipping incremental";
        }
-       delay_one_dump(dp, delete, "dump larger than available tape space,", est_kb,
-                      message, NULL);
+       delay_one_dump(dp, delete, "dump larger than available tape space,",
+                      est_kb, message, NULL);
     }
 
     /*
@@ -2191,8 +2355,9 @@ static void delay_dumps P((void))
 
        if(dp != preserve) {
 
-            /* Format dumpsize for messages */
-           snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+           /* Format dumpsize for messages */
+           snprintf(est_kb, 20, OFF_T_FMT " KB,",
+                    (OFF_T_FMT_TYPE)est(dp)->dump_csize);
 
            if(dp->skip_incr) {
                delete = 1;
@@ -2225,7 +2390,8 @@ static void delay_dumps P((void))
            if(est(dp)->dump_level == 0 && dp != preserve) {
 
                /* Format dumpsize for messages */
-               snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+               snprintf(est_kb, 20, OFF_T_FMT " KB,",
+                            (OFF_T_FMT_TYPE)est(dp)->dump_csize);
 
                if(dp->skip_incr) {
                    delete = 1;
@@ -2264,8 +2430,9 @@ static void delay_dumps P((void))
 
        if(est(dp)->dump_level != 0) {
 
-            /* Format dumpsize for messages */
-           snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+           /* Format dumpsize for messages */
+           snprintf(est_kb, 20, OFF_T_FMT " KB,",
+                    (OFF_T_FMT_TYPE)est(dp)->dump_csize);
 
            delay_one_dump(dp, 1,
                           "dumps way too big,",
@@ -2284,29 +2451,33 @@ static void delay_dumps P((void))
     ** in but why complicate the code?
     */
 
-    for(bi = biq.tail; bi != NULL; bi = nbi) {
+/*@i@*/ for(bi = biq.tail; bi != NULL; bi = nbi) {
        int avail_tapes = 1;
        nbi = bi->prev;
        dp = bi->dp;
-       if(dp->tape_splitsize > 0) avail_tapes = conf_runtapes;
-
-       if(bi->deleted)
-           new_total = total_size + tt_blocksize_kb + bi->size + tape_mark;
-       else
-           new_total = total_size - est(dp)->dump_size + bi->size;
+       if(dp->tape_splitsize > (off_t)0)
+           avail_tapes = conf_runtapes;
 
-       if(new_total <= tape_length && bi->size < tape->length * avail_tapes) {
+       if(bi->deleted) {
+           new_total = total_size + (off_t)tt_blocksize_kb +
+                       bi->csize + (off_t)tape_mark;
+       } else {
+           new_total = total_size - est(dp)->dump_csize + bi->csize;
+       }
+       if((new_total <= tape_length) &&
+         (bi->csize < (tapetype_get_length(tape) * (off_t)avail_tapes))) {
            /* reinstate it */
            total_size = new_total;
            if(bi->deleted) {
                if(bi->level == 0) {
-                   total_lev0 += (double) bi->size;
+                   total_lev0 += (double) bi->csize;
                }
                insert_disk(&schedq, dp, schedule_order);
            }
            else {
                est(dp)->dump_level = bi->level;
-               est(dp)->dump_size = bi->size;
+               est(dp)->dump_nsize = bi->nsize;
+               est(dp)->dump_csize = bi->csize;
            }
 
            /* Keep it clean */
@@ -2318,6 +2489,7 @@ static void delay_dumps P((void))
                biq.head = bi->next;
            else
                (bi->prev)->next = bi->next;
+
            amfree(bi->errstr);
            amfree(bi);
        }
@@ -2331,9 +2503,8 @@ static void delay_dumps P((void))
     ** now.
     */
 
-    for(bi = biq.head; bi != NULL; bi = nbi) {
+/*@i@*/ for(bi = biq.head; bi != NULL; bi = nbi) {
        nbi = bi->next;
-
        if(bi->deleted) {
            fprintf(stderr, "%s: FAILED %s\n", get_pname(), bi->errstr);
            log_add(L_FAIL, "%s", bi->errstr);
@@ -2344,13 +2515,14 @@ static void delay_dumps P((void))
                bi->errstr, est(dp)->dump_level);
            log_add(L_INFO, "%s", bi->errstr);
        }
-
-       /* Clean up - dont be too fancy! */
+       /*@ignore@*/
        amfree(bi->errstr);
        amfree(bi);
+       /*@end@*/
     }
 
-    fprintf(stderr, "  delay: Total size now " AM64_FMT ".\n", total_size);
+    fprintf(stderr, "  delay: Total size now " OFF_T_FMT ".\n",
+            (OFF_T_FMT_TYPE)total_size);
 
     return;
 }
@@ -2360,24 +2532,26 @@ static void delay_dumps P((void))
  * Remove a dump or modify it from full to incremental.
  * Keep track of it on the bi q in case we can add it back later.
  */
-arglist_function1(static void delay_one_dump,
-                 disk_t *, dp,
-                 int, delete)
+arglist_function1(
+    static void delay_one_dump,
+    disk_t *, dp,
+    int, delete)
 {
     bi_t *bi;
     va_list argp;
     char level_str[NUM_STR_SIZE];
     char *sep;
     char *next;
+    char *qname = quote_string(dp->name);
 
     arglist_start(argp, delete);
 
-    total_size -= tt_blocksize_kb + est(dp)->dump_size + tape_mark;
+    total_size -= (off_t)tt_blocksize_kb + est(dp)->dump_csize + (off_t)tape_mark;
     if(est(dp)->dump_level == 0) {
-       total_lev0 -= (double) est(dp)->dump_size;
+       total_lev0 -= (double) est(dp)->dump_csize;
     }
 
-    bi = alloc(sizeof(bi_t));
+    bi = alloc(SIZEOF(bi_t));
     bi->next = NULL;
     bi->prev = biq.tail;
     if(biq.tail == NULL)
@@ -2389,12 +2563,13 @@ arglist_function1(static void delay_one_dump,
     bi->deleted = delete;
     bi->dp = dp;
     bi->level = est(dp)->dump_level;
-    bi->size = est(dp)->dump_size;
+    bi->nsize = est(dp)->dump_nsize;
+    bi->csize = est(dp)->dump_csize;
 
-    snprintf(level_str, sizeof(level_str), "%d", est(dp)->dump_level);
+    snprintf(level_str, SIZEOF(level_str), "%d", est(dp)->dump_level);
     bi->errstr = vstralloc(dp->host->hostname,
-                          " ", dp->name,
-                          " ", datestamp ? datestamp : "?",
+                          " ", qname,
+                          " ", planner_timestamp ? planner_timestamp : "?",
                           " ", level_str,
                           NULL);
     sep = " [";
@@ -2409,21 +2584,23 @@ arglist_function1(static void delay_one_dump,
        remove_disk(&schedq, dp);
     } else {
        est(dp)->dump_level = est(dp)->degr_level;
-       est(dp)->dump_size = est(dp)->degr_size;
-       total_size += tt_blocksize_kb + est(dp)->dump_size + tape_mark;
+       est(dp)->dump_nsize = est(dp)->degr_nsize;
+       est(dp)->dump_csize = est(dp)->degr_csize;
+       total_size += (off_t)tt_blocksize_kb + est(dp)->dump_csize + (off_t)tape_mark;
     }
-
+    amfree(qname);
     return;
 }
 
 
-static int promote_highest_priority_incremental P((void))
+static int promote_highest_priority_incremental(void)
 {
     disk_t *dp, *dp1, *dp_promote;
-    long new_size, new_total, new_lev0;
+    off_t new_size, new_total, new_lev0;
     int check_days;
     int nb_today, nb_same_day, nb_today2;
     int nb_disk_today, nb_disk_same_day;
+    char *qname;
 
     /*
      * return 1 if did so; must update total_size correctly; must not
@@ -2435,7 +2612,7 @@ static int promote_highest_priority_incremental P((void))
 
        est(dp)->promote = -1000;
 
-       if(est_size(dp,0) <= 0)
+       if(est_size(dp,0) <= (off_t)0)
            continue;
 
        if(est(dp)->next_level0 <= 0)
@@ -2445,14 +2622,14 @@ static int promote_highest_priority_incremental P((void))
            continue;
 
        new_size = est_tape_size(dp, 0);
-       new_total = total_size - est(dp)->dump_size + new_size;
-       new_lev0 = total_lev0 + new_size;
+       new_total = total_size - est(dp)->dump_csize + new_size;
+       new_lev0 = (off_t)total_lev0 + new_size;
 
        nb_today = 0;
        nb_same_day = 0;
        nb_disk_today = 0;
        nb_disk_same_day = 0;
-        for(dp1 = schedq.head; dp1 != NULL; dp1 = dp1->next) {
+       for(dp1 = schedq.head; dp1 != NULL; dp1 = dp1->next) {
            if(est(dp1)->dump_level == 0)
                nb_disk_today++;
            else if(est(dp1)->next_level0 == est(dp)->next_level0)
@@ -2466,18 +2643,22 @@ static int promote_highest_priority_incremental P((void))
        }
 
        /* do not promote if overflow tape */
-       if(new_total > tape_length) continue;
+       if(new_total > tape_length)
+           continue;
 
        /* do not promote if overflow balanced size and something today */
        /* promote if nothing today */
-       if(new_lev0 > balanced_size+balance_threshold && nb_disk_today > 0)
+       if((new_lev0 > (off_t)(balanced_size + balance_threshold)) &&
+               (nb_disk_today > 0))
            continue;
 
        /* do not promote if only one disk due that day and nothing today */
-       if(nb_disk_same_day == 1 && nb_disk_today == 0) continue;
+       if(nb_disk_same_day == 1 && nb_disk_today == 0)
+           continue;
 
        nb_today2 = nb_today*nb_today;
-       if(nb_today == 0 && nb_same_day > 1) nb_same_day++;
+       if(nb_today == 0 && nb_same_day > 1)
+           nb_same_day++;
 
        if(nb_same_day >= nb_today2) {
            est(dp)->promote = ((nb_same_day - nb_today2)*(nb_same_day - nb_today2)) + 
@@ -2488,61 +2669,68 @@ static int promote_highest_priority_incremental P((void))
                               conf_dumpcycle - est(dp)->next_level0;
        }
 
-        if(!dp_promote || est(dp_promote)->promote < est(dp)->promote) {
+       qname = quote_string(dp->name);
+       if(!dp_promote || est(dp_promote)->promote < est(dp)->promote) {
            dp_promote = dp;
            fprintf(stderr,"   try %s:%s %d %d %d = %d\n",
-                   dp->host->hostname, dp->name, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
+                   dp->host->hostname, qname, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
        }
-        else {
+       else {
            fprintf(stderr,"no try %s:%s %d %d %d = %d\n",
-                   dp->host->hostname, dp->name, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
+                   dp->host->hostname, qname, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
        }
+       amfree(qname);
     }
 
     if(dp_promote) {
        dp = dp_promote;
 
+       qname = quote_string(dp->name);
        new_size = est_tape_size(dp, 0);
-       new_total = total_size - est(dp)->dump_size + new_size;
-       new_lev0 = total_lev0 + new_size;
+       new_total = total_size - est(dp)->dump_csize + new_size;
+       new_lev0 = (off_t)total_lev0 + new_size;
 
        total_size = new_total;
-       total_lev0 = new_lev0;
+       total_lev0 = (double)new_lev0;
        check_days = est(dp)->next_level0;
        est(dp)->degr_level = est(dp)->dump_level;
-       est(dp)->degr_size = est(dp)->dump_size;
+       est(dp)->degr_nsize = est(dp)->dump_nsize;
+       est(dp)->degr_csize = est(dp)->dump_csize;
        est(dp)->dump_level = 0;
-       est(dp)->dump_size = new_size;
+       est(dp)->dump_nsize = est_size(dp, 0);
+       est(dp)->dump_csize = new_size;
        est(dp)->next_level0 = 0;
 
        fprintf(stderr,
-             "   promote: moving %s:%s up, total_lev0 %1.0f, total_size " AM64_FMT "\n",
-               dp->host->hostname, dp->name,
-               total_lev0, total_size);
+             "   promote: moving %s:%s up, total_lev0 %1.0lf, total_size " OFF_T_FMT "\n",
+               dp->host->hostname, qname,
+               total_lev0, (OFF_T_FMT_TYPE)total_size);
 
        log_add(L_INFO,
                "Full dump of %s:%s promoted from %d day%s ahead.",
-               dp->host->hostname, dp->name,
+               dp->host->hostname, qname,
                check_days, (check_days == 1) ? "" : "s");
+       amfree(qname);
        return 1;
     }
     return 0;
 }
 
 
-static int promote_hills P((void))
+static int promote_hills(void)
 {
     disk_t *dp;
     struct balance_stats {
        int disks;
-       long size;
+       off_t size;
     } *sp = NULL;
     int days;
     int hill_days = 0;
-    long hill_size;
-    long new_size;
-    long new_total;
+    off_t hill_size;
+    off_t new_size;
+    off_t new_total;
     int my_dumpcycle;
+    char *qname;
 
     /* If we are already doing a level 0 don't bother */
     if(total_lev0 > 0)
@@ -2553,10 +2741,12 @@ static int promote_hills P((void))
     if(my_dumpcycle > 10000) my_dumpcycle = 10000;
 
     sp = (struct balance_stats *)
-       alloc(sizeof(struct balance_stats) * my_dumpcycle);
+       alloc(SIZEOF(struct balance_stats) * my_dumpcycle);
 
-    for(days = 0; days < my_dumpcycle; days++)
-       sp[days].disks = sp[days].size = 0;
+    for(days = 0; days < my_dumpcycle; days++) {
+       sp[days].disks = 0;
+       sp[days].size = (off_t)0;
+    }
 
     for(dp = schedq.head; dp != NULL; dp = dp->next) {
        days = est(dp)->next_level0;   /* This is > 0 by definition */
@@ -2570,7 +2760,7 @@ static int promote_hills P((void))
     /* Search for a suitable big hill and cut it down */
     while(1) {
        /* Find the tallest hill */
-       hill_size = 0;
+       hill_size = (off_t)0;
        for(days = 0; days < my_dumpcycle; days++) {
            if(sp[days].disks > 1 && sp[days].size > hill_size) {
                hill_size = sp[days].size;
@@ -2578,7 +2768,7 @@ static int promote_hills P((void))
            }
        }
 
-       if(hill_size <= 0) break;       /* no suitable hills */
+       if(hill_size <= (off_t)0) break;        /* no suitable hills */
 
        /* Find all the dumps in that hill and try and remove one */
        for(dp = schedq.head; dp != NULL; dp = dp->next) {
@@ -2589,28 +2779,32 @@ static int promote_hills P((void))
               dp->strategy == DS_INCRONLY)
                continue;
            new_size = est_tape_size(dp, 0);
-           new_total = total_size - est(dp)->dump_size + new_size;
+           new_total = total_size - est(dp)->dump_csize + new_size;
            if(new_total > tape_length)
                continue;
            /* We found a disk we can promote */
+           qname = quote_string(dp->name);
            total_size = new_total;
-           total_lev0 += new_size;
+           total_lev0 += (double)new_size;
            est(dp)->degr_level = est(dp)->dump_level;
-           est(dp)->degr_size = est(dp)->dump_size;
+           est(dp)->degr_nsize = est(dp)->dump_nsize;
+           est(dp)->degr_csize = est(dp)->dump_csize;
            est(dp)->dump_level = 0;
            est(dp)->next_level0 = 0;
-           est(dp)->dump_size = new_size;
+           est(dp)->dump_nsize = est_size(dp, 0);
+           est(dp)->dump_csize = new_size;
 
            fprintf(stderr,
-                   "   promote: moving %s:%s up, total_lev0 %1.0f, total_size " AM64_FMT "\n",
-                   dp->host->hostname, dp->name,
-                   total_lev0, total_size);
+                   "   promote: moving %s:%s up, total_lev0 %1.0lf, total_size " OFF_T_FMT "\n",
+                   dp->host->hostname, qname,
+                   total_lev0, (OFF_T_FMT_TYPE)total_size);
 
            log_add(L_INFO,
                    "Full dump of %s:%s specially promoted from %d day%s ahead.",
-                   dp->host->hostname, dp->name,
+                   dp->host->hostname, qname,
                    hill_days, (hill_days == 1) ? "" : "s");
 
+           amfree(qname);
            amfree(sp);
            return 1;
        }
@@ -2628,33 +2822,40 @@ static int promote_hills P((void))
  *
  * XXX - memory leak - we shouldn't just throw away *dp
  */
-static void output_scheduleline(dp)
-    disk_t *dp;
+static void output_scheduleline(
+    disk_t *dp)
 {
     est_t *ep;
-    long dump_time = 0, degr_time = 0;
+    time_t dump_time = 0, degr_time = 0;
+    double dump_kps = 0, degr_kps = 0;
     char *schedline = NULL, *degr_str = NULL;
     char dump_priority_str[NUM_STR_SIZE];
     char dump_level_str[NUM_STR_SIZE];
-    char dump_size_str[NUM_STR_SIZE];
+    char dump_nsize_str[NUM_STR_SIZE];
+    char dump_csize_str[NUM_STR_SIZE];
     char dump_time_str[NUM_STR_SIZE];
+    char dump_kps_str[NUM_STR_SIZE];
     char degr_level_str[NUM_STR_SIZE];
-    char degr_size_str[NUM_STR_SIZE];
+    char degr_nsize_str[NUM_STR_SIZE];
+    char degr_csize_str[NUM_STR_SIZE];
     char degr_time_str[NUM_STR_SIZE];
+    char degr_kps_str[NUM_STR_SIZE];
     char *dump_date, *degr_date;
     char *features;
     int i;
+    char *qname = quote_string(dp->name);
 
     ep = est(dp);
 
-    if(ep->dump_size == -1) {
+    if(ep->dump_csize == (off_t)-1) {
        /* no estimate, fail the disk */
        fprintf(stderr,
                "%s: FAILED %s %s %s %d [no estimate]\n",
                get_pname(),
-               dp->host->hostname, dp->name, datestamp, ep->dump_level);
+               dp->host->hostname, qname, planner_timestamp, ep->dump_level);
        log_add(L_FAIL, "%s %s %s %d [no estimate]",
-               dp->host->hostname, dp->name, datestamp, ep->dump_level);
+               dp->host->hostname, qname, planner_timestamp, ep->dump_level);
+       amfree(qname);
        return;
     }
 
@@ -2669,47 +2870,62 @@ static void output_scheduleline(dp)
 #define fix_rate(rate) (rate < 1.0 ? DEFAULT_DUMPRATE : rate)
 
     if(ep->dump_level == 0) {
-       dump_time = ep->dump_size / fix_rate(ep->fullrate);
+       dump_kps = fix_rate(ep->fullrate);
+       dump_time = (time_t)((double)ep->dump_csize / dump_kps);
 
-       if(ep->degr_size != -1) {
-           degr_time = ep->degr_size / fix_rate(ep->incrrate);
+       if(ep->degr_csize != (off_t)-1) {
+           degr_kps = fix_rate(ep->incrrate);
+           degr_time = (time_t)((double)ep->degr_csize / degr_kps);
        }
     }
     else {
-       dump_time = ep->dump_size / fix_rate(ep->incrrate);
+       dump_kps = fix_rate(ep->incrrate);
+       dump_time = (time_t)((double)ep->dump_csize / dump_kps);
     }
 
-    if(ep->dump_level == 0 && ep->degr_size != -1) {
+    if(ep->dump_level == 0 && ep->degr_csize != (off_t)-1) {
        snprintf(degr_level_str, sizeof(degr_level_str),
                    "%d", ep->degr_level);
-       snprintf(degr_size_str, sizeof(degr_size_str),
-                   "%ld", ep->degr_size);
+       snprintf(degr_nsize_str, sizeof(degr_nsize_str),
+                   OFF_T_FMT, (OFF_T_FMT_TYPE)ep->degr_nsize);
+       snprintf(degr_csize_str, sizeof(degr_csize_str),
+                   OFF_T_FMT, (OFF_T_FMT_TYPE)ep->degr_csize);
        snprintf(degr_time_str, sizeof(degr_time_str),
-                   "%ld", degr_time);
+                   OFF_T_FMT, (OFF_T_FMT_TYPE)degr_time);
+       snprintf(degr_kps_str, sizeof(degr_kps_str),
+                   "%.0lf", degr_kps);
        degr_str = vstralloc(" ", degr_level_str,
                             " ", degr_date,
-                            " ", degr_size_str,
+                            " ", degr_nsize_str,
+                            " ", degr_csize_str,
                             " ", degr_time_str,
+                            " ", degr_kps_str,
                             NULL);
     }
-    snprintf(dump_priority_str, sizeof(dump_priority_str),
+    snprintf(dump_priority_str, SIZEOF(dump_priority_str),
                "%d", ep->dump_priority);
-    snprintf(dump_level_str, sizeof(dump_level_str),
+    snprintf(dump_level_str, SIZEOF(dump_level_str),
                "%d", ep->dump_level);
-    snprintf(dump_size_str, sizeof(dump_size_str),
-               "%ld", ep->dump_size);
+    snprintf(dump_nsize_str, sizeof(dump_nsize_str),
+               OFF_T_FMT, (OFF_T_FMT_TYPE)ep->dump_nsize);
+    snprintf(dump_csize_str, sizeof(dump_csize_str),
+               OFF_T_FMT, (OFF_T_FMT_TYPE)ep->dump_csize);
     snprintf(dump_time_str, sizeof(dump_time_str),
-               "%ld", dump_time);
+               OFF_T_FMT, (OFF_T_FMT_TYPE)dump_time);
+    snprintf(dump_kps_str, sizeof(dump_kps_str),
+               "%.0lf", dump_kps);
     features = am_feature_to_string(dp->host->features);
     schedline = vstralloc("DUMP ",dp->host->hostname,
                          " ", features,
-                         " ", dp->name,
-                         " ", datestamp,
+                         " ", qname,
+                         " ", planner_timestamp,
                          " ", dump_priority_str,
                          " ", dump_level_str,
                          " ", dump_date,
-                         " ", dump_size_str,
+                         " ", dump_nsize_str,
+                         " ", dump_csize_str,
                          " ", dump_time_str,
+                         " ", dump_kps_str,
                          degr_str ? degr_str : "",
                          "\n", NULL);
 
@@ -2718,4 +2934,5 @@ static void output_scheduleline(dp)
     amfree(features);
     amfree(schedline);
     amfree(degr_str);
+    amfree(qname);
 }
index 43cf3fe6f474f598e1f84a1151398817e48afc07..73acd3d183f1d79c8cdc095201f46691d0d39841 100644 (file)
  *                        University of Maryland at College Park
  */
 /*
- * $Id: reporter.c,v 1.105 2006/03/09 16:51:42 martinea Exp $
+ * $Id: reporter.c,v 1.132 2006/08/28 17:02:48 martinea Exp $
  *
  * nightly Amanda Report generator
  */
 /*
-report format
-    tape label message
-    error messages
-    summary stats
-    details for errors
-    notes
-    success summary
-*/
+ * report format
*     tape label message
*     error messages
*     summary stats
*     details for errors
*     notes
*     success summary
+ */
 
 #include "amanda.h"
 #include "conffile.h"
@@ -58,9 +58,9 @@ typedef struct line_s {
 
 typedef struct timedata_s {
     logtype_t result;
-    float origsize, outsize;
+    double origsize, outsize;
     char *datestamp;
-    float sec, kps;
+    double sec, kps;
     int filenum;
     char *tapelabel;
 } timedata_t;
@@ -68,6 +68,7 @@ typedef struct timedata_s {
 typedef struct repdata_s {
     disk_t *disk;
     char *datestamp;
+    double est_nsize, est_csize;
     timedata_t taper;
     timedata_t dumper;
     timedata_t chunker;
@@ -90,7 +91,7 @@ typedef struct taper_s {
     char *label;
     double taper_time;
     double coutsize, corigsize;
-  int tapedisks, tapechunks;
+    int tapedisks, tapechunks;
     struct taper_s *next;
 } taper_t;
 
@@ -107,13 +108,12 @@ typedef struct strange_s {
 
 static strange_t *first_strange=NULL, *last_strange=NULL;
 
-static float total_time, startup_time, planner_time;
+static double total_time, startup_time, planner_time;
 
 /* count files to tape */
 static int tapefcount = 0;
 
 static char *run_datestamp;
-static char *today_datestamp;
 static char *tape_labels = NULL;
 static int last_run_tapes = 0;
 static int degraded_mode = 0; /* defined in driverio too */
@@ -141,44 +141,54 @@ char *displayunit;
 long int unitdivisor;
 
 /* local functions */
-static int contline_next P((void));
-static void addline P((line_t **lp, char *str));
-static void usage P((void));
-int main P((int argc, char **argv));
-
-static void copy_template_file P((char *lbl_templ));
-static void do_postscript_output P((void));
-static void handle_start P((void));
-static void handle_finish P((void));
-static void handle_note P((void));
-static void handle_summary P((void));
-static void handle_stats P((void));
-static void handle_error P((void));
-static void handle_disk P((void));
-static repdata_t *handle_success P((logtype_t logtype));
-static repdata_t *handle_chunk P((void));
-static void handle_partial P((void));
-static void handle_strange P((void));
-static void handle_failed P((void));
-static void generate_missing P((void));
-static void output_tapeinfo P((void));
-static void output_lines P((line_t *lp, FILE *f));
-static void output_stats P((void));
-static void output_summary P((void));
-static void output_strange P((void));
-static void sort_disks P((void));
-static int sort_by_name P((disk_t *a, disk_t *b));
-static void bogus_line P((void));
-static char *nicedate P((int datestamp));
-static char *prefix P((char *host, char *disk, int level));
-static char *prefixstrange P((char *host, char *disk, int level, int len_host, int len_disk));
-static void addtostrange P((char *host, char *disk, int level, char *str));
-static repdata_t *find_repdata P((disk_t *dp, char *datestamp, int level));
-
+int main(int argc, char **argv);
+
+static char *  nicedate(const char * datestamp);
+static char *  prefix(char *host, char *disk, int level);
+static char *  prefixstrange(char *host, char *disk, int level,
+                       size_t len_host, size_t len_disk);
+static char *  Rule(int From, int To);
+static char *  sDivZero(double a, double b, int cn);
+static char *  TextRule(int From, int To, char *s);
+static int     ColWidth(int From, int To);
+static int     contline_next(void);
+static int     sort_by_name(disk_t *a, disk_t *b);
+static repdata_t *find_repdata(disk_t *dp, char *datestamp, int level);
+static repdata_t *handle_chunk(void);
+static repdata_t *handle_success(logtype_t logtype);
+static void    addline(line_t **lp, char *str);
+static void    addtostrange(char *host, char *disk, int level, char *str);
+static void    bogus_line(const char *);
+static void    CalcMaxWidth(void);
+static void    CheckFloatMax(ColumnInfo *cd, double d);
+static void    CheckIntMax(ColumnInfo *cd, int n);
+static void    CheckStringMax(ColumnInfo *cd, char *s);
+static void    copy_template_file(char *lbl_templ);
+static void    do_postscript_output(void);
+static void    generate_missing(void);
+static void    generate_bad_estimate(void);
+static void    handle_disk(void);
+static void    handle_error(void);
+static void    handle_failed(void);
+static void    handle_finish(void);
+static void    handle_note(void);
+static void    handle_partial(void);
+static void    handle_start(void);
+static void    handle_stats(void);
+static void    handle_strange(void);
+static void    handle_summary(void);
+static void    output_lines(line_t *lp, FILE *f);
+static void    output_stats(void);
+static void    output_strange(void);
+static void    output_summary(void);
+static void    output_tapeinfo(void);
+static void    sort_disks(void);
+static void    usage(void);
 
 static int
-ColWidth(From, To)
-    int From, To;
+ColWidth(
+    int                From,
+    int                To)
 {
     int i, Width= 0;
     for (i=From; i<=To && ColumnData[i].Name != NULL; i++) {
@@ -188,12 +198,13 @@ ColWidth(From, To)
 }
 
 static char *
-Rule(From, To)
-    int From, To;
+Rule(
+    int                From,
+    int                To)
 {
     int i, ThisLeng;
     int Leng= ColWidth(0, ColumnDataCount());
-    char *RuleSpace= alloc(Leng+1);
+    char *RuleSpace= alloc((size_t)(Leng+1));
     ThisLeng= ColWidth(From, To);
     for (i=0;i<ColumnData[From].PrefixSpace; i++)
        RuleSpace[i]= ' ';
@@ -204,19 +215,21 @@ Rule(From, To)
 }
 
 static char *
-TextRule(From, To, s)
-    int From, To;
-    char *s;
+TextRule(
+    int                From,
+    int                To,
+    char *     s)
 {
     ColumnInfo *cd= &ColumnData[From];
-    int leng, nbrules, i, txtlength;
+    int leng;
+    int nbrules, i, txtlength;
     int RuleSpaceSize= ColWidth(0, ColumnDataCount());
-    char *RuleSpace= alloc(RuleSpaceSize), *tmp;
+    char *RuleSpace= alloc((size_t)RuleSpaceSize), *tmp;
 
-    lengstrlen(s);
+    leng = (int)strlen(s);
     if(leng >= (RuleSpaceSize - cd->PrefixSpace))
        leng = RuleSpaceSize - cd->PrefixSpace - 1;
-    snprintf(RuleSpace, RuleSpaceSize, "%*s%*.*s ", cd->PrefixSpace, "", 
+    snprintf(RuleSpace, (size_t)RuleSpaceSize, "%*s%*.*s ", cd->PrefixSpace, "", 
             leng, leng, s);
     txtlength = cd->PrefixSpace + leng + 1;
     nbrules = ColWidth(From,To) - txtlength;
@@ -227,60 +240,74 @@ TextRule(From, To, s)
 }
 
 static char *
-sDivZero(a, b, cn)
-    double a, b;
-    int cn;
+sDivZero(
+    double     a,
+    double     b,
+    int                cn)
 {
     ColumnInfo *cd= &ColumnData[cn];
     static char PrtBuf[256];
-    if (b == 0.0)
-       snprintf(PrtBuf, sizeof(PrtBuf),
+    if (!isnormal(b))
+       snprintf(PrtBuf, SIZEOF(PrtBuf),
          "%*s", cd->Width, "-- ");
     else
-       snprintf(PrtBuf, sizeof(PrtBuf),
+       snprintf(PrtBuf, SIZEOF(PrtBuf),
          cd->Format, cd->Width, cd->Precision, a/b);
     return PrtBuf;
 }
 
 static int
-contline_next()
+contline_next(void)
 {
     int ch;
 
-    ch = getc(logfile);
-    ungetc(ch, logfile);
-
+    if ((ch = getc(logfile)) != EOF) {
+           if (ungetc(ch, logfile) == EOF) {
+               if (ferror(logfile)) {
+                   error("ungetc failed: %s\n", strerror(errno));
+                   /*NOTREACHED*/
+               }
+               error("ungetc failed: EOF\n");
+               /*NOTREACHED*/
+           }
+    }
     return ch == ' ';
 }
 
 static void
-addline(lp, str)
-    line_t **lp;
-    char *str;
+addline(
+    line_t **  lp,
+    char *     str)
 {
-    line_t *new, *p, *q;
+    line_t *new, *p;
 
     /* allocate new line node */
-    new = (line_t *) alloc(sizeof(line_t));
+    new = (line_t *) alloc(SIZEOF(line_t));
     new->next = NULL;
     new->str = stralloc(str);
 
     /* add to end of list */
-    for(p = *lp, q = NULL; p != NULL; q = p, p = p->next);
-    if(q == NULL) *lp = new;
-    else q->next = new;
+    p = *lp;
+    if (p == NULL) {
+       *lp = new;
+    } else {
+       while (p->next != NULL)
+           p = p->next;
+       p->next = new;  
+    }
 }
 
 static void
-usage()
+usage(void)
 {
-    error("Usage: amreport conf [-f output-file] [-l logfile] [-p postscript-file]");
+    error("Usage: amreport conf [-i] [-M address] [-f output-file] [-l logfile] [-p postscript-file] [-o configoption]*");
+    /*NOTREACHED*/
 }
 
 int
-main(argc, argv)
-    int argc;
-    char **argv;
+main(
+    int                argc,
+    char **    argv)
 {
     char *conffile;
     char *conf_diskfile;
@@ -297,11 +324,18 @@ main(argc, argv)
     char *ColumnSpec = "";
     char *errstr = NULL;
     int cn;
+    int mailout = 1;
+    char *mailto = NULL;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
+    char *lbl_templ = NULL;
 
     safe_fd(-1, 0);
 
     set_pname("amreport");
 
+    dbopen(DBG_SUBDIR_SERVER);
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -314,28 +348,48 @@ main(argc, argv)
     psfname = NULL;
     logfname = NULL;
 
-    if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+    if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
        error("cannot determine current working directory");
+       /*NOTREACHED*/
     }
 
-    if (argc < 2) {
+    parse_server_conf(argc, argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
+    if (my_argc < 2) {
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
            config_name = stralloc(config_name + 1);
        }
     } else {
-       if (argv[1][0] == '-') {
+       if (my_argv[1][0] == '-') {
            usage();
            return 1;
        }
-       config_name = stralloc(argv[1]);
+       config_name = stralloc(my_argv[1]);
        config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
-       --argc; ++argv;
-       while((opt = getopt(argc, argv, "f:l:p:")) != EOF) {
+       --my_argc; ++my_argv;
+       while((opt = getopt(my_argc, my_argv, "M:f:l:p:i")) != EOF) {
            switch(opt) {
+           case 'i': 
+               mailout = 0;
+               break;
+            case 'M':
+               if (mailto != NULL) {
+                   error("you may specify at most one -M");
+                   /*NOTREACHED*/
+               }
+                mailto = stralloc(optarg);
+               if(!validate_mailto(mailto)) {
+                   error("mail address has invalid characters");
+                   /*NOTREACHED*/
+               }
+                break;
             case 'f':
                if (outfname != NULL) {
                    error("you may specify at most one -f");
+                   /*NOTREACHED*/
                }
                if (*optarg == '/') {
                     outfname = stralloc(optarg);
@@ -346,6 +400,7 @@ main(argc, argv)
             case 'l':
                if (logfname != NULL) {
                    error("you may specify at most one -l");
+                   /*NOTREACHED*/
                }
                if (*optarg == '/') {
                    logfname = stralloc(optarg);
@@ -356,6 +411,7 @@ main(argc, argv)
             case 'p':
                if (psfname != NULL) {
                    error("you may specify at most one -p");
+                   /*NOTREACHED*/
                }
                if (*optarg == '/') {
                     psfname = stralloc(optarg);
@@ -364,21 +420,22 @@ main(argc, argv)
                }
                 break;
             case '?':
-            default:
                usage();
                return 1;
+            default:
+               break;
            }
        }
 
-       argc -= optind;
-       argv += optind;
-
-       if (argc > 1) {
-           usage();
-           return 1;
-       }
+       my_argc -= optind;
+       my_argv += optind;
+    }
+    if( !mailout && mailto ){
+       printf("You cannot specify both -i & -M at the same time\n");
+       exit(1);
     }
 
+
 #if !defined MAILER
     if(!outfname) {
        printf("You must run amreport with '-f <output file>' because configure\n");
@@ -392,29 +449,38 @@ main(argc, argv)
     /* read configuration files */
 
     conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if(read_conffile(conffile)) {
-        error("errors processing config file \"%s\"", conffile);
-    }
+    /* Ignore error from read_conffile */
+    read_conffile(conffile);
     amfree(conffile);
+
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
     conf_diskfile = getconf_str(CNF_DISKFILE);
     if (*conf_diskfile == '/') {
        conf_diskfile = stralloc(conf_diskfile);
     } else {
        conf_diskfile = stralloc2(config_dir, conf_diskfile);
     }
-    if(read_diskfile(conf_diskfile, &diskq) < 0) {
-       error("could not load disklist \"%s\"", conf_diskfile);
-    }
+    /* Ignore error from read_diskfile */
+    read_diskfile(conf_diskfile, &diskq);
     amfree(conf_diskfile);
+    if(mailout && !mailto && 
+       getconf_seen(CNF_MAILTO) && strlen(getconf_str(CNF_MAILTO)) > 0) {
+               mailto = getconf_str(CNF_MAILTO);
+                if(!validate_mailto(mailto)){
+                  mailto = NULL;
+                }
+    }
+    
     conf_tapelist = getconf_str(CNF_TAPELIST);
     if (*conf_tapelist == '/') {
        conf_tapelist = stralloc(conf_tapelist);
     } else {
        conf_tapelist = stralloc2(config_dir, conf_tapelist);
     }
-    if(read_tapelist(conf_tapelist)) {
-       error("could not read tapelist \"%s\"", conf_tapelist);
-    }
+    /* Ignore error from read_tapelist */
+    read_tapelist(conf_tapelist);
     amfree(conf_tapelist);
     conf_infofile = getconf_str(CNF_INFOFILE);
     if (*conf_infofile == '/') {
@@ -424,11 +490,10 @@ main(argc, argv)
     }
     if(open_infofile(conf_infofile)) {
        error("could not open info db \"%s\"", conf_infofile);
+       /*NOTREACHED*/
     }
     amfree(conf_infofile);
 
-    today_datestamp = construct_datestamp(NULL);
-
     displayunit = getconf_str(CNF_DISPLAYUNIT);
     unitdivisor = getconf_unit_divisor();
 
@@ -515,13 +580,15 @@ main(argc, argv)
     }
     afclose(logfile);
     close_infofile();
-    if(!amflush_run)
+    if(!amflush_run) {
        generate_missing();
+       generate_bad_estimate();
+    }
 
     subj_str = vstralloc(getconf_str(CNF_ORG),
                         " ", amflush_run ? "AMFLUSH" : "AMANDA",
                         " ", "MAIL REPORT FOR",
-                        " ", nicedate(run_datestamp ? atoi(run_datestamp) : 0),
+                        " ", nicedate(run_datestamp ? run_datestamp : "0"),
                         NULL);
        
     /* lookup the tapetype and printer type from the amanda.conf file. */
@@ -537,19 +604,30 @@ main(argc, argv)
        /* output to a file */
        if((mailf = fopen(outfname,"w")) == NULL) {
            error("could not open output file: %s %s", outfname, strerror(errno));
+           /*NOTREACHED*/
        }
-       fprintf(mailf, "To: %s\n", getconf_str(CNF_MAILTO));
+       fprintf(mailf, "To: %s\n", mailto);
        fprintf(mailf, "Subject: %s\n\n", subj_str);
 
     } else {
 #ifdef MAILER
-       mail_cmd = vstralloc(MAILER,
+       if(mailto) {
+               mail_cmd = vstralloc(MAILER,
                             " -s", " \"", subj_str, "\"",
-                            " ", getconf_str(CNF_MAILTO),
-                            NULL);
-       if((mailf = popen(mail_cmd, "w")) == NULL)
-           error("could not open pipe to \"%s\": %s",
-                 mail_cmd, strerror(errno));
+                            " ", mailto, NULL);
+               if((mailf = popen(mail_cmd, "w")) == NULL) {
+               error("could not open pipe to \"%s\": %s",
+                       mail_cmd, strerror(errno));
+               /*NOTREACHED*/
+               }
+       }
+       else {
+               if(mailout) {
+                   printf("No mail sent! ");
+                  printf("No valid mail address has been specified in amanda.conf or on the commmand line\n");
+               }
+               mailf = NULL;
+       }
 #endif
     }
 
@@ -559,7 +637,9 @@ main(argc, argv)
        /* if the postscript_label_template (tp->lbl_templ) field is not */
        /* the empty string (i.e. it is set to something), open the      */
        /* postscript debugging file for writing.                        */
-       if ((strcmp(tp->lbl_templ, "")) != 0) {
+       if (tp)
+           lbl_templ = tapetype_get_lbl_templ(tp);
+       if (tp && lbl_templ && strcmp(lbl_templ, "") != 0) {
            if ((postscript = fopen(psfname, "w")) == NULL) {
                curlog = L_ERROR;
                curprog = P_REPORTER;
@@ -585,8 +665,9 @@ main(argc, argv)
            /* print to the default printer */
            printer_cmd = vstralloc(LPRCMD, NULL);
 #endif
-
-       if ((strcmp(tp->lbl_templ, "")) != 0) {
+       if (tp)
+           lbl_templ = tapetype_get_lbl_templ(tp);
+       if (tp && lbl_templ && strcmp(lbl_templ, "") != 0) {
 #ifdef LPRCMD
            if ((postscript = popen(printer_cmd, "w")) == NULL) {
                curlog = L_ERROR;
@@ -611,35 +692,37 @@ main(argc, argv)
 
     amfree(subj_str);
 
+    if(mailf) {
 
-    if(!got_finish) fputs("*** THE DUMPS DID NOT FINISH PROPERLY!\n\n", mailf);
-
-    output_tapeinfo();
-
-    if(first_strange || errsum) {
-       fprintf(mailf,"\nFAILURE AND STRANGE DUMP SUMMARY:\n");
-       if(first_strange) output_strange();
-       if(errsum) output_lines(errsum, mailf);
-    }
-    fputs("\n\n", mailf);
+       if(!got_finish) fputs("*** THE DUMPS DID NOT FINISH PROPERLY!\n\n", mailf);
 
-    output_stats();
+       output_tapeinfo();
 
-    if(errdet) {
-       fprintf(mailf,"\n\014\nFAILED AND STRANGE DUMP DETAILS:\n");
-       output_lines(errdet, mailf);
-    }
-    if(notes) {
-       fprintf(mailf,"\n\014\nNOTES:\n");
-       output_lines(notes, mailf);
-    }
-    sort_disks();
-    if(sortq.head != NULL) {
-       fprintf(mailf,"\n\014\nDUMP SUMMARY:\n");
-       output_summary();
+       if(first_strange || errsum) {
+               fprintf(mailf,"\nFAILURE AND STRANGE DUMP SUMMARY:\n");
+               if(first_strange) output_strange();
+               if(errsum) output_lines(errsum, mailf);
+       }
+       fputs("\n\n", mailf);
+       
+       output_stats();
+       
+       if(errdet) {
+               fprintf(mailf,"\n\014\nFAILED AND STRANGE DUMP DETAILS:\n");
+               output_lines(errdet, mailf);
+       }
+       if(notes) {
+               fprintf(mailf,"\n\014\nNOTES:\n");
+               output_lines(notes, mailf);
+       }
+       sort_disks();
+       if(sortq.head != NULL) {
+               fprintf(mailf,"\n\014\nDUMP SUMMARY:\n");
+               output_summary();
+       }
+       fprintf(mailf,"\n(brought to you by Amanda version %s)\n",
+               version());
     }
-    fprintf(mailf,"\n(brought to you by Amanda version %s)\n",
-           version());
 
     if (postscript) {
        do_postscript_output();
@@ -652,8 +735,10 @@ main(argc, argv)
        afclose(postscript);
     }
     else {
-       if (postscript != NULL && pclose(postscript) != 0)
+       if (postscript != NULL && pclose(postscript) != 0) {
            error("printer command failed: %s", printer_cmd);
+           /*NOTREACHED*/
+       }
        postscript = NULL;
     }
 
@@ -661,12 +746,18 @@ main(argc, argv)
     if(outfname) {
         afclose(mailf);
     }
-    else {
-        if(pclose(mailf) != 0)
+    else if(mailf) {
+        if(pclose(mailf) != 0) {
             error("mail command failed: %s", mail_cmd);
+           /*NOTREACHED*/
+       }
         mailf = NULL;
     }
 
+    clear_tapelist();
+    free_disklist(&diskq);
+    free_new_argv(new_argc, new_argv);
+    free_server_config();
     amfree(run_datestamp);
     amfree(tape_labels);
     amfree(config_dir);
@@ -681,6 +772,7 @@ main(argc, argv)
        malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
     }
 
+    dbclose();
     return 0;
 }
 
@@ -695,33 +787,40 @@ main(argc, argv)
 #define divzero(fp,a,b)                            \
     do {                                           \
        double q = (b);                     \
-       if (q == 0.0)                       \
+       if (!isnormal(q))                   \
            fprintf((fp),"  -- ");          \
        else if ((q = (a)/q) >= 999.95)     \
            fprintf((fp), "###.#");         \
        else                                \
-           fprintf((fp), "%5.1f",q);       \
+           fprintf((fp), "%5.1lf",q);      \
     } while(0)
 #define divzero_wide(fp,a,b)               \
     do {                                           \
        double q = (b);                     \
-       if (q == 0.0)                       \
+       if (!isnormal(q))                   \
            fprintf((fp),"    -- ");        \
        else if ((q = (a)/q) >= 99999.95)   \
            fprintf((fp), "#####.#");       \
        else                                \
-           fprintf((fp), "%7.1f",q);       \
+           fprintf((fp), "%7.1lf",q);      \
     } while(0)
 
 static void
-output_stats()
+output_stats(void)
 {
     double idle_time;
     tapetype_t *tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
-    int tapesize, marksize, lv, first;
+    off_t tapesize;
+    off_t marksize;
+    int lv, first;
 
-    tapesize = tp->length;
-    marksize = tp->filemark;
+    if (tp) {
+       tapesize = tapetype_get_length(tp);
+       marksize = tapetype_get_filemark(tp);
+    } else {
+       tapesize = 100 * 1024 * 1024;
+       marksize = 1   * 1024 * 1024;
+    }
 
     stats[2].dumpdisks   = stats[0].dumpdisks   + stats[1].dumpdisks;
     stats[2].tapedisks   = stats[0].tapedisks   + stats[1].tapedisks;
@@ -758,11 +857,11 @@ output_stats()
            hrmn(stats[1].dumper_time));
 
     fprintf(mailf,
-           "Output Size (meg)      %8.1f   %8.1f   %8.1f\n",
+           "Output Size (meg)      %8.1lf   %8.1lf   %8.1lf\n",
            mb(stats[2].outsize), mb(stats[0].outsize), mb(stats[1].outsize));
 
     fprintf(mailf,
-           "Original Size (meg)    %8.1f   %8.1f   %8.1f\n",
+           "Original Size (meg)    %8.1lf   %8.1lf   %8.1lf\n",
            mb(stats[2].origsize), mb(stats[0].origsize),
            mb(stats[1].origsize));
 
@@ -806,16 +905,16 @@ output_stats()
            hrmn(stats[1].taper_time));
 
     fprintf(mailf,
-           "Tape Size (meg)        %8.1f   %8.1f   %8.1f\n",
+           "Tape Size (meg)        %8.1lf   %8.1lf   %8.1lf\n",
            mb(stats[2].tapesize), mb(stats[0].tapesize),
            mb(stats[1].tapesize));
 
     fprintf(mailf, "Tape Used (%%)             ");
-    divzero(mailf, pct(stats[2].tapesize+marksize*(stats[2].tapedisks+stats[2].tapechunks)),tapesize);
+    divzero(mailf, pct(stats[2].tapesize+marksize*(stats[2].tapedisks+stats[2].tapechunks)),(double)tapesize);
     fputs("      ", mailf);
-    divzero(mailf, pct(stats[0].tapesize+marksize*(stats[0].tapedisks+stats[0].tapechunks)),tapesize);
+    divzero(mailf, pct(stats[0].tapesize+marksize*(stats[0].tapedisks+stats[0].tapechunks)),(double)tapesize);
     fputs("      ", mailf);
-    divzero(mailf, pct(stats[1].tapesize+marksize*(stats[1].tapedisks+stats[1].tapechunks)),tapesize);
+    divzero(mailf, pct(stats[1].tapesize+marksize*(stats[1].tapedisks+stats[1].tapechunks)),(double)tapesize);
 
     if(stats[1].tapedisks > 0) fputs("   (level:#disks ...)", mailf);
     putc('\n', mailf);
@@ -862,7 +961,7 @@ output_stats()
     putc('\n', mailf);
 
     if(stats_by_tape) {
-       int label_length = strlen(stats_by_tape->label) + 5;
+       int label_length = (int)strlen(stats_by_tape->label) + 5;
        fprintf(mailf,"\nUSAGE BY TAPE:\n");
        fprintf(mailf,"  %-*s  Time      Size      %%    Nb    Nc\n",
                label_length, "Label");
@@ -870,21 +969,20 @@ output_stats()
            current_tape = current_tape->next) {
            fprintf(mailf, "  %-*s", label_length, current_tape->label);
            fprintf(mailf, " %2d:%02d", hrmn(current_tape->taper_time));
-           fprintf(mailf, " %8.0f%s  ", du(current_tape->coutsize), displayunit);
-           divzero(mailf, pct(current_tape->coutsize + 
-                              marksize * (current_tape->tapedisks+current_tape->tapechunks)),
-                          tapesize);
+           fprintf(mailf, " %8.0lf%s  ", du(current_tape->coutsize), displayunit);
+           divzero(mailf, pct(current_tape->coutsize + marksize *
+                  (current_tape->tapedisks+current_tape->tapechunks)),
+                  (double)tapesize);
            fprintf(mailf, "  %4d", current_tape->tapedisks);
            fprintf(mailf, "  %4d\n", current_tape->tapechunks);
        }
     }
-
 }
 
 /* ----- */
 
 static void
-output_tapeinfo()
+output_tapeinfo(void)
 {
     tape_t *tp, *lasttp;
     int run_tapes;
@@ -921,10 +1019,15 @@ output_tapeinfo()
                run_tapes);
     
     while(run_tapes > 0) {
-       if(tp != NULL)
+       if(tp != NULL) {
            fprintf(mailf, "%s", tp->label);
-       else
-           fputs("a new tape", mailf);
+       } else {
+           if (run_tapes == 1)
+               fprintf(mailf, "a new tape");
+           else
+               fprintf(mailf, "%d new tapes", run_tapes);
+           run_tapes = 1;
+       }
 
        if(run_tapes > 1) fputs(", ", mailf);
 
@@ -936,9 +1039,9 @@ output_tapeinfo()
 
     lasttp = lookup_tapepos(lookup_nb_tape());
     run_tapes = getconf_int(CNF_RUNTAPES);
-    if(lasttp && run_tapes > 0 && lasttp->datestamp == 0) {
+    if(lasttp && run_tapes > 0 && strcmp(lasttp->datestamp,"0") == 0) {
        int c = 0;
-       while(lasttp && run_tapes > 0 && lasttp->datestamp == 0) {
+       while(lasttp && run_tapes > 0 && strcmp(lasttp->datestamp,"0") == 0) {
            c++;
            lasttp = lasttp->prev;
            run_tapes--;
@@ -953,7 +1056,7 @@ output_tapeinfo()
                    lasttp->label);
            lasttp = lasttp->prev;
            c--;
-           while(lasttp && c > 0 && lasttp->datestamp == 0) {
+           while(lasttp && c > 0 && strcmp(lasttp->datestamp,"0") == 0) {
                fprintf(mailf, ", %s", lasttp->label);
                lasttp = lasttp->prev;
                c--;
@@ -964,9 +1067,10 @@ output_tapeinfo()
 }
 
 /* ----- */
-static void output_strange()
+static void
+output_strange(void)
 {
-    int len_host=0, len_disk=0;
+    size_t len_host=0, len_disk=0;
     strange_t *strange;
     char *str = NULL;
 
@@ -980,13 +1084,14 @@ static void output_strange()
        str = vstralloc("  ", prefixstrange(strange->hostname, strange->diskname, strange->level, len_host, len_disk),
                        "  ", strange->str, NULL);
        fprintf(mailf, "%s\n", str);
+       amfree(str);
     }
 }
 
 static void
-output_lines(lp, f)
-    line_t *lp;
-    FILE *f;
+output_lines(
+    line_t *   lp,
+    FILE *     f)
 {
     line_t *next;
 
@@ -1003,8 +1108,9 @@ output_lines(lp, f)
 /* ----- */
 
 static int
-sort_by_name(a, b)
-    disk_t *a, *b;
+sort_by_name(
+    disk_t *   a,
+    disk_t *   b)
 {
     int rc;
 
@@ -1014,7 +1120,7 @@ sort_by_name(a, b)
 }
 
 static void
-sort_disks()
+sort_disks(void)
 {
     disk_t *dp;
 
@@ -1029,44 +1135,46 @@ sort_disks()
 }
 
 static void
-CheckStringMax(cd, s)
-    ColumnInfo *cd;
-    char *s;
+CheckStringMax(
+    ColumnInfo *cd,
+    char *     s)
 {
     if (cd->MaxWidth) {
-       int l= strlen(s);
+       int l = (int)strlen(s);
+
        if (cd->Width < l)
            cd->Width= l;
     }
 }
 
 static void
-CheckIntMax(cd, n)
-    ColumnInfo *cd;
-    int n;
+CheckIntMax(
+    ColumnInfo *cd,
+    int                n)
 {
     if (cd->MaxWidth) {
        char testBuf[200];
        int l;
-       snprintf(testBuf, sizeof(testBuf),
+
+       snprintf(testBuf, SIZEOF(testBuf),
          cd->Format, cd->Width, cd->Precision, n);
-       lstrlen(testBuf);
+       l = (int)strlen(testBuf);
        if (cd->Width < l)
            cd->Width= l;
     }
 }
 
 static void
-CheckFloatMax(cd, d)
-    ColumnInfo *cd;
-    double d;
+CheckFloatMax(
+    ColumnInfo *cd,
+    double     d)
 {
     if (cd->MaxWidth) {
        char testBuf[200];
        int l;
-       snprintf(testBuf, sizeof(testBuf),
+       snprintf(testBuf, SIZEOF(testBuf),
          cd->Format, cd->Width, cd->Precision, d);
-       lstrlen(testBuf);
+       l = (int)strlen(testBuf);
        if (cd->Width < l)
            cd->Width= l;
     }
@@ -1084,7 +1192,7 @@ static int TapeTime;
 static int TapeRate;
 
 static void
-CalcMaxWidth()
+CalcMaxWidth(void)
 {
     /* we have to look for columspec's, that require the recalculation.
      * we do here the same loops over the sortq as is done in
@@ -1093,12 +1201,11 @@ CalcMaxWidth()
      *                                                 ElB, 1999-02-24.
      */
     disk_t *dp;
-    float f;
+    double f;
     repdata_t *repdata;
     for(dp = sortq.head; dp != NULL; dp = dp->next) {
       if(dp->todo) {
        for(repdata = data(dp); repdata != NULL; repdata = repdata->next) {
-           ColumnInfo *cd;
            char TimeRateBuffer[40];
 
            CheckStringMax(&ColumnData[HostName], dp->host->hostname);
@@ -1109,8 +1216,10 @@ CalcMaxWidth()
            CheckIntMax(&ColumnData[Level], repdata->level);
             if(repdata->dumper.result == L_SUCCESS || 
                    repdata->dumper.result == L_CHUNKSUCCESS) {
-               CheckFloatMax(&ColumnData[OrigKB], du(repdata->dumper.origsize));
-               CheckFloatMax(&ColumnData[OutKB], du(repdata->dumper.outsize));
+               CheckFloatMax(&ColumnData[OrigKB],
+                             (double)du(repdata->dumper.origsize));
+               CheckFloatMax(&ColumnData[OutKB],
+                             (double)du(repdata->dumper.outsize));
                if(dp->compress == COMP_NONE)
                    f = 0.0;
                else 
@@ -1119,43 +1228,41 @@ CalcMaxWidth()
                        sDivZero(pct(repdata->dumper.outsize), f, Compress));
 
                if(!amflush_run)
-                   snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+                   snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
                                "%3d:%02d", mnsc(repdata->dumper.sec));
                else
-                   snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+                   snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
                                "N/A ");
                CheckStringMax(&ColumnData[DumpTime], TimeRateBuffer);
 
                CheckFloatMax(&ColumnData[DumpRate], repdata->dumper.kps); 
            }
 
-           cd= &ColumnData[TapeTime];
            if(repdata->taper.result == L_FAIL) {
-               CheckStringMax(cd, "FAILED");
+               CheckStringMax(&ColumnData[TapeTime], "FAILED");
                continue;
            }
            if(repdata->taper.result == L_SUCCESS ||
               repdata->taper.result == L_CHUNKSUCCESS)
-               snprintf(TimeRateBuffer, sizeof(TimeRateBuffer), 
+               snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer), 
                  "%3d:%02d", mnsc(repdata->taper.sec));
            else
-               snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+               snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
                  "N/A ");
-           CheckStringMax(cd, TimeRateBuffer);
+           CheckStringMax(&ColumnData[TapeTime], TimeRateBuffer);
 
-           cd= &ColumnData[TapeRate];
            if(repdata->taper.result == L_SUCCESS ||
                    repdata->taper.result == L_CHUNKSUCCESS)
-               CheckFloatMax(cd, repdata->taper.kps);
+               CheckFloatMax(&ColumnData[TapeRate], repdata->taper.kps);
            else
-               CheckStringMax(cd, "N/A ");
+               CheckStringMax(&ColumnData[TapeRate], "N/A ");
        }
       }
     }
 }
 
 static void
-output_summary()
+output_summary(void)
 {
     disk_t *dp;
     repdata_t *repdata;
@@ -1164,8 +1271,8 @@ output_summary()
     char *tmp;
 
     int i, h, w1, wDump, wTape;
-    float outsize, origsize;
-    float f;
+    double outsize, origsize;
+    double f;
 
     HostName = StringToColumn("HostName");
     Disk = StringToColumn("Disk");
@@ -1188,19 +1295,19 @@ output_summary()
     wTape= ColWidth(TapeTime, TapeRate);
 
     /* print centered top titles */
-    hstrlen(ds);
+    h = (int)strlen(ds);
     if (h > wDump) {
-       h= 0;
+       h = 0;
     } else {
-       h= (wDump-h)/2;
+       h = (wDump-h)/2;
     }
     fprintf(mailf, "%*s", w1+h, "");
     fprintf(mailf, "%-*s", wDump-h, ds);
-    hstrlen(ts);
+    h = (int)strlen(ts);
     if (h > wTape) {
-       h= 0;
+       h = 0;
     } else {
-       h= (wTape-h)/2;
+       h = (wTape-h)/2;
     }
     fprintf(mailf, "%*s", h, "");
     fprintf(mailf, "%-*s", wTape-h, ts);
@@ -1240,7 +1347,8 @@ output_summary()
        ColumnInfo *cd;
        char TimeRateBuffer[40];
        for(repdata = data(dp); repdata != NULL; repdata = repdata->next) {
-           int devlen;
+           char *devname;
+           size_t devlen;
 
            cd= &ColumnData[HostName];
            fprintf(mailf, "%*s", cd->PrefixSpace, "");
@@ -1248,15 +1356,16 @@ output_summary()
 
            cd= &ColumnData[Disk];
            fprintf(mailf, "%*s", cd->PrefixSpace, "");
-           devlen= strlen(dp->name);
-           if (devlen > cd->Width) {
+           devname = sanitize_string(dp->name);
+           devlen = strlen(devname);
+           if (devlen > (size_t)cd->Width) {
                fputc('-', mailf); 
                fprintf(mailf, cd->Format, cd->Width-1, cd->Precision-1,
-                 dp->name+devlen - (cd->Width-1) );
+                 devname+devlen - (cd->Width-1) );
            }
            else
-               fprintf(mailf, cd->Format, cd->Width, cd->Width, dp->name);
-
+               fprintf(mailf, cd->Format, cd->Width, cd->Width, devname);
+           amfree(devname);
            cd= &ColumnData[Level];
            if (repdata->dumper.result == L_BOGUS &&
                repdata->taper.result  == L_BOGUS) {
@@ -1309,7 +1418,7 @@ output_summary()
 
            cd= &ColumnData[OrigKB];
            fprintf(mailf, "%*s", cd->PrefixSpace, "");
-           if(origsize != 0.0)
+           if(isnormal(origsize))
                fprintf(mailf, cd->Format, cd->Width, cd->Precision, du(origsize));
            else
                fprintf(mailf, "%*.*s", cd->Width, cd->Width, "N/A");
@@ -1335,10 +1444,10 @@ output_summary()
            fprintf(mailf, "%*s", cd->PrefixSpace, "");
            if(repdata->dumper.result == L_SUCCESS ||
               repdata->dumper.result == L_CHUNKSUCCESS)
-               snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+               snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
                  "%3d:%02d", mnsc(repdata->dumper.sec));
            else
-               snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+               snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
                  "N/A ");
            fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer);
 
@@ -1362,10 +1471,10 @@ output_summary()
            if(repdata->taper.result == L_SUCCESS || 
               repdata->taper.result == L_PARTIAL ||
               repdata->taper.result == L_CHUNKSUCCESS)
-               snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+               snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
                  "%3d:%02d", mnsc(repdata->taper.sec));
            else
-               snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+               snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
                  "N/A ");
            fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer);
 
@@ -1389,40 +1498,49 @@ output_summary()
 }
 
 static void
-bogus_line()
+bogus_line(
+    const char *err_text)
 {
-    printf("line %d of log is bogus\n", curlinenum);
+    printf("line %d of log is bogus: <%s>\n", curlinenum, curstr);
+    printf("  Scan failed at: <%s>\n", err_text);
 }
 
 
-static char *
-nicedate(datestamp)
-    int datestamp;
 /*
- * Formats an integer of the form YYYYMMDD into the string
+ * Formats an integer of the form YYYYMMDDHHMMSS into the string
  * "Monthname DD, YYYY".  A pointer to the statically allocated string
  * is returned, so it must be copied to other storage (or just printed)
  * before calling nicedate() again.
  */
+static char *
+nicedate(
+    const char *datestamp)
 {
     static char nice[64];
+    char date[9];
+    int  numdate;
     static char *months[13] = { "BogusMonth",
        "January", "February", "March", "April", "May", "June",
        "July", "August", "September", "October", "November", "December"
     };
     int year, month, day;
 
-    year  = datestamp / 10000;
-    day   = datestamp % 100;
-    month = (datestamp / 100) % 100;
+    strncpy(date, datestamp, 8);
+    date[8] = '\0';
+    numdate = atoi(date);
+    year  = numdate / 10000;
+    day   = numdate % 100;
+    month = (numdate / 100) % 100;
+    if (month > 12 )
+       month = 0;
 
-    snprintf(nice, sizeof(nice), "%s %d, %d", months[month], day, year);
+    snprintf(nice, SIZEOF(nice), "%s %d, %d", months[month], day, year);
 
     return nice;
 }
 
 static void
-handle_start()
+handle_start(void)
 {
     static int started = 0;
     char *label;
@@ -1436,36 +1554,36 @@ handle_start()
 
        skip_whitespace(s, ch);
 #define sc "datestamp"
-       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
-           bogus_line();
+       if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+           bogus_line(s - 1);
            return;
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
        skip_whitespace(s, ch);
        if(ch == '\0') {
-           bogus_line();
+           bogus_line(s - 1);
            return;
        }
        fp = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        run_datestamp = newstralloc(run_datestamp, fp);
-       s[-1] = ch;
+       s[-1] = (char)ch;
 
        skip_whitespace(s, ch);
 #define sc "label"
-       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
-           bogus_line();
+       if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+           bogus_line(s - 1);
            return;
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
        skip_whitespace(s, ch);
        if(ch == '\0') {
-           bogus_line();
+           bogus_line(s - 1);
            return;
        }
        fp = s - 1;
@@ -1473,7 +1591,7 @@ handle_start()
        s[-1] = '\0';
 
        label = stralloc(fp);
-       s[-1] = ch;
+       s[-1] = (char)ch;
 
        if(tape_labels) {
            fp = vstralloc(tape_labels, ", ", label, NULL);
@@ -1486,10 +1604,10 @@ handle_start()
        last_run_tapes++;
 
        if(stats_by_tape == NULL) {
-           stats_by_tape = current_tape = (taper_t *)alloc(sizeof(taper_t));
+           stats_by_tape = current_tape = (taper_t *)alloc(SIZEOF(taper_t));
        }
        else {
-           current_tape->next = (taper_t *)alloc(sizeof(taper_t));
+           current_tape->next = (taper_t *)alloc(SIZEOF(taper_t));
            current_tape = current_tape->next;
        }
        current_tape->label = label;
@@ -1520,22 +1638,22 @@ handle_start()
 
        skip_whitespace(s, ch);
 #define sc "date"
-       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
            return;                             /* ignore bogus line */
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
        skip_whitespace(s, ch);
        if(ch == '\0') {
-           bogus_line();
+           bogus_line(s - 1);
            return;
        }
        fp = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
        run_datestamp = newstralloc(run_datestamp, fp);
-       s[-1] = ch;
+       s[-1] = (char)ch;
 
        started = 1;
     }
@@ -1548,11 +1666,11 @@ handle_start()
 
 
 static void
-handle_finish()
+handle_finish(void)
 {
     char *s;
     int ch;
-    float a_time;
+    double a_time;
 
     if(curprog == P_DRIVER || curprog == P_AMFLUSH || curprog == P_PLANNER) {
        s = curstr;
@@ -1560,40 +1678,40 @@ handle_finish()
 
        skip_whitespace(s, ch);
 #define sc "date"
-       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
-           bogus_line();
+       if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+           bogus_line(s - 1);
            return;
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
 
        skip_whitespace(s, ch);
        if(ch == '\0') {
-           bogus_line();
+           bogus_line(s - 1);
            return;
        }
        skip_non_whitespace(s, ch);     /* ignore the date string */
 
        skip_whitespace(s, ch);
 #define sc "time"
-       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
            /* older planner doesn't write time */
            if(curprog == P_PLANNER) return;
-           bogus_line();
+           bogus_line(s - 1);
            return;
        }
-       s += sizeof(sc)-1;
+       s += SIZEOF(sc)-1;
        ch = s[-1];
 #undef sc
 
        skip_whitespace(s, ch);
        if(ch == '\0') {
-           bogus_line();
+           bogus_line(s - 1);
            return;
        }
-       if(sscanf(s - 1, "%f", &a_time) != 1) {
-           bogus_line();
+       if(sscanf(s - 1, "%lf", &a_time) != 1) {
+           bogus_line(s - 1);
            return;
        }
        if(curprog == P_PLANNER) {
@@ -1607,10 +1725,15 @@ handle_finish()
 }
 
 static void
-handle_stats()
+handle_stats(void)
 {
-    char *s;
+    char *s, *fp;
     int ch;
+    char *hostname, *diskname, *datestamp;
+    int level = 0;
+    double sec, kps, nbytes, cbytes;
+    repdata_t *repdata;
+    disk_t *dp;
 
     if(curprog == P_DRIVER) {
        s = curstr;
@@ -1618,30 +1741,122 @@ handle_stats()
 
        skip_whitespace(s, ch);
 #define sc "startup time"
-       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
-           bogus_line();
-           return;
+       if(ch != '\0' && strncmp(s - 1, sc, sizeof(sc)-1) == 0) {
+           s += sizeof(sc)-1;
+           ch = s[-1];
+#undef sc
+
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               bogus_line(s - 1);
+               return;
+           }
+           if(sscanf(s - 1, "%lf", &startup_time) != 1) {
+               bogus_line(s - 1);
+               return;
+           }
+           planner_time = startup_time;
        }
-       s += sizeof(sc)-1;
-       ch = s[-1];
+#define sc "estimate"
+       else if(ch != '\0' && strncmp(s - 1, sc, sizeof(sc)-1) == 0) {
+           s += sizeof(sc)-1;
+           ch = s[-1];
 #undef sc
 
-       skip_whitespace(s, ch);
-       if(ch == '\0') {
-           bogus_line();
-           return;
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               bogus_line(s - 1);
+               return;
+           }
+           fp = s - 1;
+           skip_non_whitespace(s, ch);
+           s[-1] = '\0';
+           hostname = stralloc(fp);
+           s[-1] = (char)ch;
+
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               bogus_line(s - 1);
+               amfree(hostname);
+               return;
+           }
+           fp = s - 1;
+           skip_non_whitespace(s, ch);
+           s[-1] = '\0';
+           diskname = stralloc(fp);
+           s[-1] = (char)ch;
+
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               bogus_line(s - 1);
+               amfree(hostname);
+               amfree(diskname);
+               return;
+           }
+           fp = s - 1;
+           skip_non_whitespace(s, ch);
+           s[-1] = '\0';
+           datestamp = stralloc(fp);
+           s[-1] = (char)ch;
+
+           skip_whitespace(s, ch);
+           if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+               bogus_line(s - 1);
+               amfree(hostname);
+               amfree(diskname);
+               amfree(datestamp);
+               return;
+           }
+           skip_integer(s, ch);
+           if(level < 0 || level > 9) {
+               amfree(hostname);
+               amfree(diskname);
+               amfree(datestamp);
+               return;
+           }
+
+           skip_whitespace(s, ch);
+
+           if(sscanf(s - 1,"[sec %lf nkb %lf ckb %lf kps %lf",
+                     &sec, &nbytes, &cbytes, &kps) != 4)  {
+               bogus_line(s - 1);
+               amfree(hostname);
+               amfree(diskname);
+               amfree(datestamp);
+               return;
+           }
+
+           dp = lookup_disk(hostname, diskname);
+           if(dp == NULL) {
+               addtostrange(hostname, diskname, level,
+                            "ERROR [not in disklist]");
+               amfree(hostname);
+               amfree(diskname);
+               amfree(datestamp);
+               return;
+           }
+
+           repdata = find_repdata(dp, datestamp, level);
+
+           repdata->est_nsize = nbytes;
+           repdata->est_csize = cbytes;
+
+           amfree(hostname);
+           amfree(diskname);
+           amfree(datestamp);
        }
-       if(sscanf(s - 1, "%f", &startup_time) != 1) {
-           bogus_line();
+       else {
+           bogus_line(s - 1);
            return;
        }
-       planner_time = startup_time;
+#undef sc
+
     }
 }
 
 
 static void
-handle_note()
+handle_note(void)
 {
     char *str = NULL;
 
@@ -1654,7 +1869,7 @@ handle_note()
 /* ----- */
 
 static void
-handle_error()
+handle_error(void)
 {
     char *s = NULL, *nl;
     int ch;
@@ -1665,8 +1880,8 @@ handle_error()
 
        skip_whitespace(s, ch);
 #define sc "no-tape"
-       if(ch != '\0' && strncmp(s - 1, sc, sizeof(sc)-1) == 0) {
-           s += sizeof(sc)-1;
+       if(ch != '\0' && strncmp(s - 1, sc, SIZEOF(sc)-1) == 0) {
+           s += SIZEOF(sc)-1;
            ch = s[-1];
 #undef sc
 
@@ -1693,24 +1908,24 @@ handle_error()
 /* ----- */
 
 static void
-handle_summary()
+handle_summary(void)
 {
-    bogus_line();
+    bogus_line(curstr);
 }
 
 /* ----- */
 
 static int nb_disk=0;
 static void
-handle_disk()
+handle_disk(void)
 {
     disk_t *dp;
-    char *s, *fp;
+    char *s, *fp, *qdiskname;
     int ch;
     char *hostname = NULL, *diskname = NULL;
 
     if(curprog != P_PLANNER && curprog != P_AMFLUSH) {
-       bogus_line();
+       bogus_line(curstr);
        return;
     }
 
@@ -1725,26 +1940,26 @@ handle_disk()
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        return;
     }
     fp = s - 1;
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     hostname = newstralloc(hostname, fp);
-    s[-1] = ch;
+    s[-1] = (char)ch;
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        amfree(hostname);
        return;
     }
-    fp = s - 1;
-    skip_non_whitespace(s, ch);
+    qdiskname = s - 1;
+    skip_quoted_string(s, ch);
     s[-1] = '\0';
-    diskname = newstralloc(diskname, fp);
-    s[-1] = ch;
+    diskname = unquote_string(qdiskname);
+    s[-1] = (char)ch;
 
     dp = lookup_disk(hostname, diskname);
     if(dp == NULL) {
@@ -1761,10 +1976,10 @@ handle_disk()
  * for a split chunk of the overall dumpfile.
  */
 static repdata_t *
-handle_chunk()
+handle_chunk(void)
 {
     disk_t *dp;
-    float sec, kps, kbytes;
+    double sec, kps, kbytes;
     timedata_t *sp;
     int i;
     char *s, *fp;
@@ -1776,7 +1991,7 @@ handle_chunk()
     char *datestamp;
     
     if(curprog != P_TAPER) {
-       bogus_line();
+       bogus_line(curstr);
        return NULL;
     }
     
@@ -1785,30 +2000,30 @@ handle_chunk()
     
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        return NULL;
     }
     fp = s - 1;
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     hostname = stralloc(fp);
-    s[-1] = ch;
+    s[-1] = (char)ch;
     
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        amfree(hostname);
        return NULL;
     }
     fp = s - 1;
-    skip_non_whitespace(s, ch);
+    skip_quoted_string(s, ch);
     s[-1] = '\0';
-    diskname = stralloc(fp);
-    s[-1] = ch;
+    diskname = unquote_string(fp);
+    s[-1] = (char)ch;
     
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        amfree(hostname);
        amfree(diskname);
        return NULL;
@@ -1817,44 +2032,40 @@ handle_chunk()
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     datestamp = stralloc(fp);
-    s[-1] = ch;
-    
-    level = atoi(datestamp);
-    if(level < 100)  {
-       datestamp = newstralloc(datestamp, run_datestamp);
-    }
-    else {
-       skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf(s - 1, "%d", &chunk) != 1) {
-           bogus_line();
-           amfree(hostname);
-           amfree(diskname);
-           amfree(datestamp);
-           return NULL;
-       }
-       skip_integer(s, ch);
-       
-       skip_whitespace(s, ch);
-       if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
-           bogus_line();
-           amfree(hostname);
-           amfree(diskname);
-           amfree(datestamp);
-           return NULL;
-       }
-       skip_integer(s, ch);
+    s[-1] = (char)ch;
+    skip_whitespace(s, ch);
+    if(ch == '\0' || sscanf(s - 1, "%d", &chunk) != 1) {
+       bogus_line(s - 1);
+       amfree(hostname);
+       amfree(diskname);
+       amfree(datestamp);
+       return NULL;
     }
+    skip_integer(s, ch);
+
     skip_whitespace(s, ch);
+    if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+       bogus_line(s - 1);
+       amfree(hostname);
+       amfree(diskname);
+       amfree(datestamp);
+       return NULL;
+    }
+    skip_integer(s, ch);
     
+    /*@ignore@*/
     if(level < 0 || level > 9) {
        amfree(hostname);
        amfree(diskname);
        amfree(datestamp);
        return NULL;
     }
-    
-    if(sscanf(s - 1,"[sec %f kb %f kps %f", &sec, &kbytes, &kps) != 3)  {
-       bogus_line();
+    /*@end@*/
+    skip_whitespace(s, ch);
+    if(sscanf(s - 1,"[sec %lf kb %lf kps %lf", &sec, &kbytes, &kps) != 3)  {
+       bogus_line(s - 1);
        amfree(hostname);
        amfree(diskname);
        amfree(datestamp);
@@ -1903,23 +2114,27 @@ handle_chunk()
 }
 
 static repdata_t *
-handle_success(logtype_t logtype)
+handle_success(
+    logtype_t  logtype)
 {
     disk_t *dp;
-    float sec, kps, kbytes, origkb;
+    double sec = 0.0;
+    double kps = 0.0;
+    double kbytes = 0.0;
+    double origkb = 0.0;
     timedata_t *sp;
     int i;
-    char *s, *fp;
+    char *s, *fp, *qdiskname;
     int ch;
     char *hostname = NULL;
     char *diskname = NULL;
     repdata_t *repdata;
-    int level;
+    int level = 0;
     char *datestamp;
 
     if(curprog != P_TAPER && curprog != P_DUMPER && curprog != P_PLANNER &&
        curprog != P_CHUNKER) {
-       bogus_line();
+       bogus_line(curstr);
        return NULL;
     }
 
@@ -1928,30 +2143,29 @@ handle_success(logtype_t logtype)
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        return NULL;
     }
     fp = s - 1;
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     hostname = stralloc(fp);
-    s[-1] = ch;
+    s[-1] = (char)ch;
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        amfree(hostname);
        return NULL;
     }
-    fp = s - 1;
-    skip_non_whitespace(s, ch);
+    qdiskname = s - 1;
+    skip_quoted_string(s, ch);
     s[-1] = '\0';
-    diskname = stralloc(fp);
-    s[-1] = ch;
+    diskname = unquote_string(qdiskname);
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        amfree(hostname);
        amfree(diskname);
        return NULL;
@@ -1960,16 +2174,16 @@ handle_success(logtype_t logtype)
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     datestamp = stralloc(fp);
-    s[-1] = ch;
+    s[-1] = (char)ch;
 
-    level = atoi(datestamp);
-    if(level < 100)  {
+    if(strlen(datestamp) < 3) {
+       level = atoi(datestamp);
        datestamp = newstralloc(datestamp, run_datestamp);
     }
     else {
        skip_whitespace(s, ch);
        if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
-           bogus_line();
+           bogus_line(s - 1);
            amfree(hostname);
            amfree(diskname);
            amfree(datestamp);
@@ -1977,6 +2191,7 @@ handle_success(logtype_t logtype)
        }
        skip_integer(s, ch);
     }
+
     if(level < 0 || level > 9) {
        amfree(hostname);
        amfree(diskname);
@@ -1988,13 +2203,15 @@ handle_success(logtype_t logtype)
                                /* Planner success messages (for skipped
                                   dumps) do not contain statistics */
     if(curprog != P_PLANNER) {
-       if(curprog != P_DUMPER ||
-          sscanf(s - 1,"[sec %f kb %f kps %f orig-kb %f", 
-                 &sec, &kbytes, &kps, &origkb) != 4)  {
+       if(*(s - 1) == '"')
+           s++;
+       if((curprog != P_DUMPER)
+           || (sscanf(s - 1,"[sec %lf kb %lf kps %lf orig-kb %lf", 
+                 &sec, &kbytes, &kps, &origkb) != 4))  {
            origkb = -1;
-           if(sscanf(s - 1,"[sec %f kb %f kps %f",
+           if(sscanf(s - 1,"[sec %lf kb %lf kps %lf",
                      &sec, &kbytes, &kps) != 3) {
-               bogus_line();
+               bogus_line(s - 1);
                amfree(hostname);
                amfree(diskname);
                amfree(datestamp);
@@ -2002,14 +2219,15 @@ handle_success(logtype_t logtype)
            }
        }
        else {
-           if(origkb == 0.0) origkb = 0.1;
+           if(!isnormal(origkb))
+               origkb = 0.1;
        }
     }
 
 
     dp = lookup_disk(hostname, diskname);
     if(dp == NULL) {
-       addtostrange(hostname, diskname, level, "ERROR [not in disklist]");
+       addtostrange(hostname, qdiskname, level, "ERROR [not in disklist]");
        amfree(hostname);
        amfree(diskname);
        amfree(datestamp);
@@ -2034,15 +2252,19 @@ handle_success(logtype_t logtype)
 
     i = level > 0;
 
-    if(origkb == -1) {
+    if(origkb < 0.0) {
        info_t inf;
        struct tm *tm;
        int Idatestamp;
 
        get_info(hostname, diskname, &inf);
         tm = localtime(&inf.inf[level].date);
-        Idatestamp = 10000*(tm->tm_year+1900) +
-                      100*(tm->tm_mon+1) + tm->tm_mday;
+       if (tm) {
+            Idatestamp = 10000*(tm->tm_year+1900) +
+                        100*(tm->tm_mon+1) + tm->tm_mday;
+       } else {
+           Idatestamp = 19000101;
+       }
 
        if(atoi(datestamp) == Idatestamp) {
            /* grab original size from record */
@@ -2051,6 +2273,12 @@ handle_success(logtype_t logtype)
        else
            origkb = 0.0;
     }
+
+    if (curprog == P_DUMPER &&
+       (sp->result == L_FAIL || sp->result == L_PARTIAL)) {
+       addtostrange(hostname, qdiskname, level, "was successfully retried");
+    }
+
     amfree(hostname);
     amfree(diskname);
     amfree(datestamp);
@@ -2065,6 +2293,7 @@ handle_success(logtype_t logtype)
     if(curprog == P_TAPER) {
        if(current_tape == NULL) {
            error("current_tape == NULL");
+           /*NOTREACHED*/
        }
        stats[i].taper_time += sec;
        sp->filenum = ++tapefcount;
@@ -2073,7 +2302,7 @@ handle_success(logtype_t logtype)
        stats[i].tapedisks +=1;
        stats[i].tapesize += kbytes;
        sp->outsize = kbytes;
-       if(repdata->chunker.outsize == 0.0 && repdata->dumper.outsize != 0.0) { /* dump to tape */
+       if(!isnormal(repdata->chunker.outsize) && isnormal(repdata->dumper.outsize)) { /* dump to tape */
            stats[i].outsize += kbytes;
            if(dp->compress != COMP_NONE) {
                stats[i].coutsize += kbytes;
@@ -2111,12 +2340,14 @@ handle_success(logtype_t logtype)
 }
 
 static void
-handle_partial()
+handle_partial(void)
 {
     repdata_t *repdata;
     timedata_t *sp;
 
     repdata = handle_success(L_PARTIAL);
+    if (!repdata)
+       return;
 
     if(curprog == P_TAPER)
        sp = &(repdata->taper);
@@ -2128,17 +2359,22 @@ handle_partial()
 }
 
 static void
-handle_strange()
+handle_strange(void)
 {
     char *str = NULL;
     char *strangestr = NULL;
     repdata_t *repdata;
+    char *qdisk;
 
     repdata = handle_success(L_SUCCESS);
+    if (!repdata)
+       return;
+
+    qdisk = quote_string(repdata->disk->name);
 
     addline(&errdet,"");
     str = vstralloc("/-- ", prefix(repdata->disk->host->hostname, 
-                                  repdata->disk->name, repdata->level),
+                                  qdisk, repdata->level),
                    " ", "STRANGE",
                    NULL);
     addline(&errdet, str);
@@ -2147,30 +2383,30 @@ handle_strange()
     while(contline_next()) {
        get_logline(logfile);
 #define sc "sendbackup: warning "
-       if(strncmp(curstr, sc, sizeof(sc)-1) == 0) {
-           strangestr = newstralloc(strangestr, curstr+sizeof(sc)-1);
+       if(strncmp(curstr, sc, SIZEOF(sc)-1) == 0) {
+           strangestr = newstralloc(strangestr, curstr+SIZEOF(sc)-1);
        }
        addline(&errdet, curstr);
     }
     addline(&errdet,"\\--------");
 
     str = vstralloc("STRANGE", " ", strangestr, NULL);
-    addtostrange(repdata->disk->host->hostname, repdata->disk->name, repdata->level,
-                str);
+    addtostrange(repdata->disk->host->hostname, qdisk, repdata->level, str);
+    amfree(qdisk);
     amfree(str);
     amfree(strangestr);
 }
 
 static void
-handle_failed()
+handle_failed(void)
 {
     disk_t *dp;
     char *hostname;
     char *diskname;
     char *datestamp;
     char *errstr;
-    int level;
-    char *s, *fp;
+    int level = 0;
+    char *s, *fp, *qdiskname;
     int ch;
     char *str = NULL;
     repdata_t *repdata;
@@ -2184,7 +2420,7 @@ handle_failed()
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        return;
     }
     hostname = s - 1;
@@ -2193,16 +2429,18 @@ handle_failed()
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        return;
     }
-    diskname = s - 1;
-    skip_non_whitespace(s, ch);
+    qdiskname = s - 1;
+    skip_quoted_string(s, ch);
     s[-1] = '\0';
+    diskname = unquote_string(qdiskname);
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
+       amfree(diskname);
        return;
     }
     fp = s - 1;
@@ -2217,8 +2455,9 @@ handle_failed()
     else { /* read the level */
        skip_whitespace(s, ch);
        if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
-           bogus_line();
+           bogus_line(s - 1);
            amfree(datestamp);
+           amfree(diskname);
            return;
        }
        skip_integer(s, ch);
@@ -2226,8 +2465,9 @@ handle_failed()
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       bogus_line();
+       bogus_line(s - 1);
        amfree(datestamp);
+       amfree(diskname);
        return;
     }
     errstr = s - 1;
@@ -2236,8 +2476,9 @@ handle_failed()
     }
 
     dp = lookup_disk(hostname, diskname);
+    amfree(diskname);
     if(dp == NULL) {
-       addtostrange(hostname, diskname, level, "ERROR [not in disklist]");
+       addtostrange(hostname, qdiskname, level, "ERROR [not in disklist]");
     } else {
        repdata = find_repdata(dp, datestamp, level);
 
@@ -2251,12 +2492,12 @@ handle_failed()
     amfree(datestamp);
 
     str = vstralloc("FAILED", " ", errstr, NULL);
-    addtostrange(hostname, diskname, level, str);
+    addtostrange(hostname, qdiskname, level, str);
     amfree(str);
 
     if(curprog == P_DUMPER) {
        addline(&errdet,"");
-       str = vstralloc("/-- ", prefix(hostname, diskname, level),
+       str = vstralloc("/-- ", prefix(hostname, qdiskname, level),
                        " ", "FAILED",
                        " ", errstr,
                        NULL);
@@ -2273,28 +2514,89 @@ handle_failed()
 
 
 static void
-generate_missing()
+generate_missing(void)
 {
     disk_t *dp;
+    char *qdisk;
 
     for(dp = diskq.head; dp != NULL; dp = dp->next) {
        if(dp->todo && data(dp) == NULL) {
-           addtostrange(dp->host->hostname, dp->name, -987, "RESULTS MISSING");
+           qdisk = quote_string(dp->name);
+           addtostrange(dp->host->hostname, qdisk, -987, "RESULTS MISSING");
+           amfree(qdisk);
        }
     }
 }
 
+static void
+generate_bad_estimate(void)
+{
+    disk_t *dp;
+    repdata_t *repdata;
+    char s[1000];
+    double outsize;
+
+    for(dp = diskq.head; dp != NULL; dp = dp->next) {
+       if(dp->todo) {
+           for(repdata = data(dp); repdata != NULL; repdata = repdata->next) {
+               if(repdata->est_csize >= 0.1) {
+                   if(repdata->taper.result == L_SUCCESS ||
+                      repdata->taper.result == L_PARTIAL ||
+                      repdata->taper.result == L_CHUNKSUCCESS)
+                       outsize  = repdata->taper.outsize;
+                   else if(repdata->chunker.result == L_SUCCESS ||
+                           repdata->chunker.result == L_PARTIAL ||
+                           repdata->chunker.result == L_CHUNKSUCCESS)
+                       outsize  = repdata->chunker.outsize;
+                   else
+                       outsize  = repdata->dumper.outsize;
+
+                   if(repdata->est_csize * 0.9 > outsize) {
+                       snprintf(s, 1000,
+                               "  big estimate: %s %s %d",
+                                repdata->disk->host->hostname,
+                                repdata->disk->name,
+                                repdata->level);
+                       s[999] = '\0';
+                       addline(&notes, s);
+                       snprintf(s, 1000,
+                                "                est: %.0lf%s    out %.0lf%s",
+                                du(repdata->est_csize), displayunit,
+                                du(outsize), displayunit);
+                       s[999] = '\0';
+                       addline(&notes, s);
+                   }
+                   else if(repdata->est_csize * 1.1 < outsize) {
+                       snprintf(s, 1000,
+                               "  small estimate: %s %s %d",
+                                repdata->disk->host->hostname,
+                                repdata->disk->name,
+                                repdata->level);
+                       s[999] = '\0';
+                       addline(&notes, s);
+                       snprintf(s, 1000,
+                                "                  est: %.0lf%s    out %.0lf%s",
+                                du(repdata->est_csize), displayunit,
+                                du(outsize), displayunit);
+                       s[999] = '\0';
+                       addline(&notes, s);
+                   }
+               }
+           }
+       }
+    }
+}
 
 static char *
-prefix (host, disk, level)
-    char *host;
-    char *disk;
-    int level;
+prefix (
+    char *     host,
+    char *     disk,
+    int                level)
 {
     char number[NUM_STR_SIZE];
     static char *str = NULL;
 
-    snprintf(number, sizeof(number), "%d", level);
+    snprintf(number, SIZEOF(number), "%d", level);
     str = newvstralloc(str,
                       " ", host ? host : "(host?)",
                       " ", disk ? disk : "(disk?)",
@@ -2306,19 +2608,20 @@ prefix (host, disk, level)
 
 
 static char *
-prefixstrange (host, disk, level, len_host, len_disk)
-    char *host;
-    char *disk;
-    int level;
-    int len_host, len_disk;
+prefixstrange (
+    char *     host,
+    char *     disk,
+    int                level,
+    size_t     len_host,
+    size_t     len_disk)
 {
     char *h, *d;
-    int l;
+    size_t l;
     char number[NUM_STR_SIZE];
     static char *str = NULL;
 
-    snprintf(number, sizeof(number), "%d", level);
-    h=malloc(len_host+1);
+    snprintf(number, SIZEOF(number), "%d", level);
+    h=alloc(len_host+1);
     if(host) {
        strncpy(h, host, len_host);
     } else {
@@ -2328,7 +2631,7 @@ prefixstrange (host, disk, level, len_host, len_disk)
     for(l = strlen(h); l < len_host; l++) {
        h[l] = ' ';
     }
-    d=malloc(len_disk+1);
+    d=alloc(len_disk+1);
     if(disk) {
        strncpy(d, disk, len_disk);
     } else {
@@ -2351,15 +2654,15 @@ prefixstrange (host, disk, level, len_host, len_disk)
 
 
 static void
-addtostrange (host, disk, level, str)
-    char *host;
-    char *disk;
-    int  level;
-    char *str;
+addtostrange (
+    char *     host,
+    char *     disk,
+    int                level,
+    char *     str)
 {
     strange_t *strange;
 
-    strange = malloc(sizeof(strange_t));
+    strange = alloc(SIZEOF(strange_t));
     strange->hostname = stralloc(host);
     strange->diskname = stralloc(disk);
     strange->level    = level;
@@ -2376,12 +2679,12 @@ addtostrange (host, disk, level, str)
 
 
 static void
-copy_template_file(lbl_templ)
-    char *lbl_templ;
+copy_template_file(
+    char *     lbl_templ)
 {
   char buf[BUFSIZ];
   int fd;
-  int numread;
+  ssize_t numread;
 
   if (strchr(lbl_templ, '/') == NULL) {
     lbl_templ = stralloc2(config_dir, lbl_templ);
@@ -2402,8 +2705,8 @@ copy_template_file(lbl_templ)
     afclose(postscript);
     return;
   }
-  while ((numread = read(fd, buf, sizeof(buf))) > 0) {
-    if (fwrite(buf, numread, 1, postscript) != 1) {
+  while ((numread = read(fd, buf, SIZEOF(buf))) > 0) {
+    if (fwrite(buf, (size_t)numread, 1, postscript) != 1) {
       curlog = L_ERROR;
       curprog = P_REPORTER;
       curstr = vstralloc("error copying PostScript template file ",
@@ -2437,10 +2740,10 @@ copy_template_file(lbl_templ)
 }
 
 static repdata_t *
-find_repdata(dp, datestamp, level)
-    disk_t *dp;
-    char *datestamp;
-    int level;
+find_repdata(
+    /*@keep@*/ disk_t *dp,
+               char *  datestamp,
+               int     level)
 {
     repdata_t *repdata, *prev;
 
@@ -2451,8 +2754,8 @@ find_repdata(dp, datestamp, level)
        prev = repdata;
     }
     if(!repdata) {
-       repdata = (repdata_t *)alloc(sizeof(repdata_t));
-       memset(repdata, '\0',sizeof(repdata_t));
+       repdata = (repdata_t *)alloc(SIZEOF(repdata_t));
+       memset(repdata, '\0', SIZEOF(repdata_t));
        repdata->disk = dp;
        repdata->datestamp = stralloc(datestamp ? datestamp : "");
        repdata->level = level;
@@ -2468,16 +2771,21 @@ find_repdata(dp, datestamp, level)
 }
 
 
-static void do_postscript_output()
+static void
+do_postscript_output(void)
 {
     tapetype_t *tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
     disk_t *dp;
     repdata_t *repdata;
-    float outsize, origsize;
-    int tapesize, marksize;
+    double outsize, origsize;
+    off_t tapesize;
+    off_t marksize;
+
+    if (!tp)
+       return;
 
-    tapesize = tp->length;
-    marksize = tp->filemark;
+    tapesize = tapetype_get_length(tp);
+    marksize = tapetype_get_filemark(tp);
 
     for(current_tape = stats_by_tape; current_tape != NULL;
            current_tape = current_tape->next) {
@@ -2486,21 +2794,21 @@ static void do_postscript_output()
            break;
        }
 
-       copy_template_file(tp->lbl_templ);
+       copy_template_file(tapetype_get_lbl_templ(tp));
 
        /* generate a few elements */
        fprintf(postscript,"(%s) DrawDate\n\n",
-                   nicedate(run_datestamp ? atoi(run_datestamp) : 0));
+                   nicedate(run_datestamp ? run_datestamp : "0"));
        fprintf(postscript,"(Amanda Version %s) DrawVers\n",version());
        fprintf(postscript,"(%s) DrawTitle\n", current_tape->label);
 
        /* Stats */
-       fprintf(postscript, "(Total Size:        %6.1f MB) DrawStat\n",
+       fprintf(postscript, "(Total Size:        %6.1lf MB) DrawStat\n",
              mb(current_tape->coutsize));
        fprintf(postscript, "(Tape Used (%%)       ");
        divzero(postscript, pct(current_tape->coutsize + 
                                marksize * (current_tape->tapedisks + current_tape->tapechunks)),
-                               tapesize);
+                               (double)tapesize);
        fprintf(postscript," %%) DrawStat\n");
        fprintf(postscript, "(Compression Ratio:  ");
        divzero(postscript, pct(current_tape->coutsize),current_tape->corigsize);
@@ -2538,14 +2846,14 @@ static void do_postscript_output()
 
                if (repdata->taper.result == L_SUCCESS ||
                    repdata->taper.result == L_PARTIAL) {
-                   if(origsize != 0.0) {
-                       fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8.0f) (%8.0f) DrawHost\n",
+                   if(isnormal(origsize)) {
+                       fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8.0lf) (%8.0lf) DrawHost\n",
                            dp->host->hostname, dp->name, repdata->level,
                            repdata->taper.filenum, origsize, 
                            outsize);
                    }
                    else {
-                       fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8s) (%8.0f) DrawHost\n",
+                       fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8s) (%8.0lf) DrawHost\n",
                            dp->host->hostname, dp->name, repdata->level,
                            repdata->taper.filenum, "N/A", 
                            outsize);
index 13d5317bbda2326385a94bad6867782e0a30e454..9f8835e47bb33b81f4b052aa3d2a51bc1295f83a 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: server_util.c,v 1.13.2.1 2006/04/23 18:52:04 martinea Exp $
+ * $Id: server_util.c,v 1.17 2006/05/25 01:47:20 johnfranks Exp $
  *
  */
 
 #include "server_util.h"
 #include "arglist.h"
 #include "token.h"
+#include "logfile.h"
+#include "util.h"
+#include "conffile.h"
+#include "diskfile.h"
 
 const char *cmdstr[] = {
     "BOGUS", "QUIT", "QUITTING", "DONE", "PARTIAL", 
-    "START", "FILE-DUMP", "PORT-DUMP", "CONTINUE", "ABORT",    /* dumper cmds */
+    "START", "FILE-DUMP", "PORT-DUMP", "CONTINUE", "ABORT",/* dumper cmds */
     "FAILED", "TRY-AGAIN", "NO-ROOM", "RQ-MORE-DISK",  /* dumper results */
     "ABORT-FINISHED", "BAD-COMMAND",                   /* dumper results */
     "START-TAPER", "FILE-WRITE", "PORT-WRITE",         /* taper cmds */
@@ -45,8 +49,9 @@ const char *cmdstr[] = {
 };
 
 
-cmd_t getcmd(cmdargs)
-struct cmdargs *cmdargs;
+cmd_t
+getcmd(
+    struct cmdargs *   cmdargs)
 {
     char *line;
     cmd_t cmd_i;
@@ -56,14 +61,16 @@ struct cmdargs *cmdargs;
     if (isatty(0)) {
        printf("%s> ", get_pname());
        fflush(stdout);
+        line = readline(NULL);
+    } else {
+        line = agets(stdin);
     }
-
-    if ((line = agets(stdin)) == NULL) {
+    if (line == NULL) {
        line = stralloc("QUIT");
     }
 
     cmdargs->argc = split(line, cmdargs->argv,
-       sizeof(cmdargs->argv) / sizeof(cmdargs->argv[0]), " ");
+       (int)(sizeof(cmdargs->argv) / sizeof(cmdargs->argv[0])), " ");
     amfree(line);
 
 #if DEBUG
@@ -95,3 +102,28 @@ printf_arglist_function1(void putresult, cmd_t, result, const char *, format)
     fflush(stdout);
     arglist_end(argp);
 }
+
+char *
+amhost_get_security_conf(
+    char *     string,
+    void *     arg)
+{
+    if(!string || !*string)
+       return(NULL);
+
+    if(strcmp(string, "krb5principal")==0)
+       return(getconf_str(CNF_KRB5PRINCIPAL));
+    else if(strcmp(string, "krb5keytab")==0)
+       return(getconf_str(CNF_KRB5KEYTAB));
+
+    if(!arg || !((am_host_t *)arg)->disks) return(NULL);
+
+    if(strcmp(string, "amandad_path")==0)
+       return ((am_host_t *)arg)->disks->amandad_path;
+    else if(strcmp(string, "client_username")==0)
+       return ((am_host_t *)arg)->disks->client_username;
+    else if(strcmp(string, "ssh_keys")==0)
+       return ((am_host_t *)arg)->disks->ssh_keys;
+
+    return(NULL);
+}
index 34f7125fe464272c1ffb9324ccacaf3a028ba5a9..7087231bb4695b331fc7f831b98ed4995a4d4dd4 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: server_util.h,v 1.8.2.1 2006/04/23 18:52:04 martinea Exp $
+ * $Id: server_util.h,v 1.11 2006/05/25 01:47:20 johnfranks Exp $
  *
  */
 #ifndef SERVER_UTIL_H
 
 #define MAX_ARGS 32
 
-typedef enum {
+/*
+ * Some lints are confused by: typedef enum (...) xxx_t;
+ * So here we use an equivalent of type int and an unnamed enum for constants.
+ */
+typedef int cmd_t;
+enum {
     BOGUS, QUIT, QUITTING, DONE, PARTIAL,
     START, FILE_DUMP, PORT_DUMP, CONTINUE, ABORT,      /* dumper cmds */
     FAILED, TRYAGAIN, NO_ROOM, RQ_MORE_DISK,           /* dumper results */
@@ -43,7 +48,7 @@ typedef enum {
     PORT, TAPE_ERROR, TAPER_OK,        SPLIT_NEEDNEXT,         /* taper results */
     SPLIT_CONTINUE,
     LAST_TOK
-} cmd_t;
+};
 extern const char *cmdstr[];
 
 struct cmdargs {
@@ -51,8 +56,19 @@ struct cmdargs {
     char *argv[MAX_ARGS + 1];
 };
 
-cmd_t getcmd P((struct cmdargs *cmdargs));
-void putresult P((cmd_t result, const char *, ...))
+cmd_t getcmd(struct cmdargs *cmdargs);
+cmd_t getresult(int fd, int show, int *result_argc, char **result_argv, int max_arg);
+void putresult(cmd_t result, const char *, ...)
      __attribute__ ((format (printf, 2, 3)));
+int taper_cmd(cmd_t cmd, void *ptr, char *destname, int level, char *datestamp);
+
+struct disk_s;
+struct chunker_s;
+int chunker_cmd(struct chunker_s *chunker, cmd_t cmd, struct disk_s *dp);
+
+struct dumper_s;
+int dumper_cmd(struct dumper_s *dumper, cmd_t cmd, struct disk_s *dp);
+
+char *amhost_get_security_conf(char *string, void *arg);
 
 #endif /* SERVER_UTIL_H */
index 6cbbd96d203f8555bd6bf88528f3d996c4911c43..1b2e7c6e1323d2194452009c1954cd4a0ded03b9 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: tapefile.c,v 1.28 2003/10/24 13:44:35 martinea Exp $
+ * $Id: tapefile.c,v 1.37 2006/07/21 00:25:52 martinea Exp $
  *
  * routines to read and write the amanda active tape list
  */
 static tape_t *tape_list = NULL;
 
 /* local functions */
-static tape_t *parse_tapeline P((int *status, char *line));
-static tape_t *insert P((tape_t *list, tape_t *tp));
-static time_t stamp2time P((int datestamp));
+static tape_t *parse_tapeline(int *status, char *line);
+static tape_t *insert(tape_t *list, tape_t *tp);
+static time_t stamp2time(char *datestamp);
 
-
-
-int read_tapelist(tapefile)
-char *tapefile;
+int
+read_tapelist(
+    char *tapefile)
 {
     tape_t *tp;
     FILE *tapef;
     int pos;
     char *line = NULL;
-    int status;
+    int status = 0;
 
     tape_list = NULL;
     if((tapef = fopen(tapefile,"r")) == NULL) {
@@ -56,10 +55,16 @@ char *tapefile;
     }
 
     while((line = agets(tapef)) != NULL) {
+       if (line[0] == '\0') {
+           amfree(line);
+           continue;
+       }
        tp = parse_tapeline(&status, line);
        amfree(line);
-       if(tp == NULL && status != 0) return 1;
-       if(tp != NULL) tape_list = insert(tape_list, tp);
+       if(tp == NULL && status != 0)
+           return 1;
+       if(tp != NULL)
+           tape_list = insert(tape_list, tp);
     }
     afclose(tapef);
 
@@ -70,8 +75,9 @@ char *tapefile;
     return 0;
 }
 
-int write_tapelist(tapefile)
-char *tapefile;
+int
+write_tapelist(
+    char *tapefile)
 {
     tape_t *tp;
     FILE *tapef;
@@ -86,7 +92,7 @@ char *tapefile;
     }
 
     for(tp = tape_list; tp != NULL; tp = tp->next) {
-       fprintf(tapef, "%d %s", tp->datestamp, tp->label);
+       fprintf(tapef, "%s %s", tp->datestamp, tp->label);
        if(tp->reuse) fprintf(tapef, " reuse");
        else fprintf(tapef, " no-reuse");
        fprintf(tapef, "\n");
@@ -94,6 +100,7 @@ char *tapefile;
 
     if (fclose(tapef) == EOF) {
        fprintf(stderr,"error [closing %s: %s]", newtapefile, strerror(errno));
+       amfree(newtapefile);
        return 1;
     }
     rc = rename(newtapefile, tapefile);
@@ -102,20 +109,23 @@ char *tapefile;
     return(rc != 0);
 }
 
-void clear_tapelist()
+void
+clear_tapelist(void)
 {
     tape_t *tp, *next;
 
     for(tp = tape_list; tp; tp = next) {
        amfree(tp->label);
+       amfree(tp->datestamp);
        next = tp->next;
        amfree(tp);
     }
     tape_list = NULL;
 }
 
-tape_t *lookup_tapelabel(label)
-char *label;
+tape_t *
+lookup_tapelabel(
+    char *label)
 {
     tape_t *tp;
 
@@ -127,8 +137,9 @@ char *label;
 
 
 
-tape_t *lookup_tapepos(pos)
-int pos;
+tape_t *
+lookup_tapepos(
+    int pos)
 {
     tape_t *tp;
 
@@ -139,18 +150,20 @@ int pos;
 }
 
 
-tape_t *lookup_tapedate(datestamp)
-int datestamp;
+tape_t *
+lookup_tapedate(
+    char *datestamp)
 {
     tape_t *tp;
 
     for(tp = tape_list; tp != NULL; tp = tp->next) {
-       if(tp->datestamp == datestamp) return tp;
+       if(strcmp(tp->datestamp, datestamp) == 0) return tp;
     }
     return NULL;
 }
 
-int lookup_nb_tape()
+int
+lookup_nb_tape(void)
 {
     tape_t *tp;
     int pos=0;
@@ -161,8 +174,9 @@ int lookup_nb_tape()
     return pos;
 }
 
-tape_t *lookup_last_reusable_tape(skip)
-     int skip;
+tape_t *
+lookup_last_reusable_tape(
+     int skip)
 {
     tape_t *tp, **tpsave;
     int count=0;
@@ -176,12 +190,12 @@ tape_t *lookup_last_reusable_tape(skip)
      * caller.  If skip is zero, the oldest is returned, if it is
      * one, the next oldest, two, the next to next oldest and so on.
      */
-    tpsave = alloc((skip + 1) * sizeof (*tpsave));
+    tpsave = alloc((skip + 1) * SIZEOF(*tpsave));
     for(s = 0; s <= skip; s++) {
        tpsave[s] = NULL;
     }
     for(tp = tape_list; tp != NULL; tp = tp->next) {
-       if(tp->reuse == 1 && tp->datestamp > 0 && match (labelstr, tp->label)) {
+       if(tp->reuse == 1 && strcmp(tp->datestamp,"0") != 0 && match (labelstr, tp->label)) {
            count++;
            for(s = skip; s > 0; s--) {
                tpsave[s] = tpsave[s - 1];
@@ -197,14 +211,15 @@ tape_t *lookup_last_reusable_tape(skip)
     return tp;
 }
 
-int reusable_tape(tp)
-    tape_t *tp;
+int
+reusable_tape(
+    tape_t *tp)
 {
     int count = 0;
 
     if(tp == NULL) return 0;
     if(tp->reuse == 0) return 0;
-    if(tp->datestamp == 0) return 1;
+    if( strcmp(tp->datestamp,"0") == 0) return 1;
     while(tp != NULL) {
        if(tp->reuse == 1) count++;
        tp = tp->prev;
@@ -212,8 +227,9 @@ int reusable_tape(tp)
     return (count >= getconf_int(CNF_TAPECYCLE));
 }
 
-void remove_tapelabel(label)
-char *label;
+void
+remove_tapelabel(
+    char *label)
 {
     tape_t *tp, *prev, *next;
 
@@ -221,32 +237,36 @@ char *label;
     if(tp != NULL) {
        prev = tp->prev;
        next = tp->next;
+       /*@ignore@*/
        if(prev != NULL)
            prev->next = next;
        else /* begin of list */
            tape_list = next;
        if(next != NULL)
            next->prev = prev;
+       /*@end@*/
        while (next != NULL) {
            next->position--;
            next = next->next;
        }
+       amfree(tp->datestamp);
        amfree(tp->label);
        amfree(tp);
     }
 }
 
-tape_t *add_tapelabel(datestamp, label)
-int datestamp;
-char *label;
+tape_t *
+add_tapelabel(
+    char *datestamp,
+    char *label)
 {
     tape_t *cur, *new;
 
     /* insert a new record to the front of the list */
 
-    new = (tape_t *) alloc(sizeof(tape_t));
+    new = (tape_t *) alloc(SIZEOF(tape_t));
 
-    new->datestamp = datestamp;
+    new->datestamp = stralloc(datestamp);
     new->position = 0;
     new->reuse = 1;
     new->label = stralloc(label);
@@ -266,7 +286,8 @@ char *label;
     return new;
 }
 
-int guess_runs_from_tapelist()
+int
+guess_runs_from_tapelist(void)
 {
     tape_t *tp;
     int i, ntapes, tape_ndays, dumpcycle, runtapes, runs;
@@ -283,7 +304,7 @@ int guess_runs_from_tapelist()
        if((tp = lookup_tapepos(i)) == NULL) break;
 
        tape_time  = stamp2time(tp->datestamp);
-       tape_ndays = days_diff(tape_time, today);
+       tape_ndays = (int)days_diff(tape_time, today);
 
        if(tape_ndays < dumpcycle) ntapes++;
        else break;
@@ -305,16 +326,17 @@ int guess_runs_from_tapelist()
     return runs;
 }
 
-static tape_t *parse_tapeline(status, line)
-int *status;
-char *line;
+static tape_t *
+parse_tapeline(
+    int *status,
+    char *line)
 {
     tape_t *tp = NULL;
     char *s, *s1;
     int ch;
 
     *status = 0;
-    tp = (tape_t *) alloc(sizeof(tape_t));
+    tp = (tape_t *) alloc(SIZEOF(tape_t));
 
     tp->prev = NULL;
     tp->next = NULL;
@@ -327,26 +349,25 @@ char *line;
        amfree(tp);
        return NULL;
     }
-    if (sscanf(s - 1, "%d", &tp->datestamp) != 1) {
-       amfree(tp);
-       *status = 1;
-       return NULL;
-    }
-    skip_integer(s, ch);
+    s1 = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    tp->datestamp = stralloc(s1);
 
     skip_whitespace(s, ch);
     s1 = s - 1;
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
     tp->label = stralloc(s1);
+
     skip_whitespace(s, ch);
     tp->reuse = 1;
 #define sc "reuse"
-    if(strncmp(s - 1, sc, sizeof(sc)-1) == 0)
+    if(strncmp(s - 1, sc, SIZEOF(sc)-1) == 0)
        tp->reuse = 1;
 #undef sc
 #define sc "no-reuse"
-    if(strncmp(s - 1, sc, sizeof(sc)-1) == 0)
+    if(strncmp(s - 1, sc, SIZEOF(sc)-1) == 0)
        tp->reuse = 0;
 #undef sc
 
@@ -355,46 +376,74 @@ char *line;
 
 
 /* insert in reversed datestamp order */
-static tape_t *insert(list, tp)
-tape_t *list, *tp;
+/*@ignore@*/
+static tape_t *
+insert(
+    tape_t *list,
+    tape_t *tp)
 {
     tape_t *prev, *cur;
 
     prev = NULL;
     cur = list;
 
-    while(cur != NULL && cur->datestamp >= tp->datestamp) {
+    while(cur != NULL && strcmp(cur->datestamp, tp->datestamp) >= 0) {
        prev = cur;
        cur = cur->next;
     }
     tp->prev = prev;
     tp->next = cur;
-    if(prev == NULL) list = tp;
-    else prev->next = tp;
-    if(cur !=NULL) cur->prev = tp;
+    if(prev == NULL) {
+       list = tp;
+#ifndef __lint
+    } else {
+       prev->next = tp;
+#endif
+    }
+    if(cur !=NULL)
+       cur->prev = tp;
 
     return list;
 }
+/*@end@*/
 
-
-static time_t stamp2time(datestamp)
-int datestamp;
 /*
- * Converts datestamp (an int of the form YYYYMMDD) into a real time_t value.
+ * Converts datestamp (an char of the form YYYYMMDD or YYYYMMDDHHMMSS) into a real
+ * time_t value.
  * Since the datestamp contains no timezone or hh/mm/ss information, the
  * value is approximate.  This is ok for our purposes, since we round off
  * scheduling calculations to the nearest day.
  */
+
+static time_t
+stamp2time(
+    char *datestamp)
 {
-    struct tm tm;
+    struct tm *tm;
     time_t now;
+    char date[9];
+    int dateint;
 
+    strncpy(date, datestamp, 8);
+    date[8] = '\0';
+    dateint = atoi(date);
     now = time(0);
-    tm = *localtime(&now);     /* initialize sec/min/hour & gmtoff */
+    tm = localtime(&now);      /* initialize sec/min/hour & gmtoff */
+
+    if (!tm) {
+       tm = alloc(SIZEOF(struct tm));
+       tm->tm_sec   = 0;
+       tm->tm_min   = 0;
+       tm->tm_hour  = 0;
+       tm->tm_wday  = 0;
+       tm->tm_yday  = 0;
+       tm->tm_isdst = 0;
+    }
+
 
-    tm.tm_year = ( datestamp          / 10000) - 1900;
-    tm.tm_mon  = ((datestamp % 10000) /   100) - 1;
-    tm.tm_mday = ((datestamp %   100)        );
+    tm->tm_year = ( dateint          / 10000) - 1900;
+    tm->tm_mon  = ((dateint % 10000) /   100) - 1;
+    tm->tm_mday = ((dateint %   100)        );
 
-    return mktime(&tm);
+    return mktime(tm);
 }
index c9d866aeefea48356f3548d36ee02ac36e7d752e..6d8fdb97c9e0c1802279788d76a67a8499a483a2 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: tapefile.h,v 1.7 1999/05/14 21:40:21 kashmir Exp $
+ * $Id: tapefile.h,v 1.9 2006/05/25 01:47:20 johnfranks Exp $
  *
  * interface for active tape list manipulation routines
  */
 typedef struct tape_s {
     struct tape_s *next, *prev;
     int position;
-    int datestamp;
+    char * datestamp;
     int reuse;
     char *label;
 } tape_t;
 
-int read_tapelist P((char *tapefile));
-int write_tapelist P((char *tapefile));
-void clear_tapelist P((void));
-tape_t *lookup_tapelabel P((char *label));
-tape_t *lookup_tapepos P((int pos));
-tape_t *lookup_tapedate P((int datestamp));
-int lookup_nb_tape P((void));
-tape_t *lookup_last_reusable_tape P((int skip));
-void remove_tapelabel P((char *label));
-tape_t *add_tapelabel P((int datestamp, char *label));
-int reusable_tape P((tape_t *tp));
+int read_tapelist(char *tapefile);
+int write_tapelist(char *tapefile);
+void clear_tapelist(void);
+tape_t *lookup_tapelabel(char *label);
+tape_t *lookup_tapepos(int pos);
+tape_t *lookup_tapedate(char *datestamp);
+int lookup_nb_tape(void);
+tape_t *lookup_last_reusable_tape(int skip);
+void remove_tapelabel(char *label);
+tape_t *add_tapelabel(char *datestamp, char *label);
+int reusable_tape(tape_t *tp);
 
-int guess_runs_from_tapelist P((void));
+int guess_runs_from_tapelist(void);
 
 #endif /* !TAPEFILE_H */
index f403171f2d2867d208ef6bfba0e9400286b799cd..37d17ee51054e0b5017ca32c155a7dcfeebf3d74 100644 (file)
@@ -23,7 +23,7 @@
  * Authors: the Amanda Development Team.  Its members are listed in a
  * file named AUTHORS, in the root directory of this distribution.
  */
-/* $Id: taper.c,v 1.118.2.1 2006/05/04 21:31:15 martinea Exp $
+/* $Id: taper.c,v 1.144 2006/08/24 11:23:32 martinea Exp $
  *
  * moves files from holding disk to tape, or from a socket to tape
  */
@@ -61,10 +61,10 @@ static int len       =  0;
 static int offset    =  0;
 static char *datestr = NULL;
 static char start_datestr[20];
-time_t raw_time;
-struct tm tape_time;
-struct tm backup_time;
-struct tm *tape_timep = &tape_time;
+static time_t raw_time;
+static struct tm tape_time;
+static struct tm backup_time;
+static struct tm *tape_timep = &tape_time;
 typedef struct vtbl_lbls {
     u_int8_t  label[45];
     u_int8_t  date[20];
@@ -76,46 +76,46 @@ static vtbl_lbls vtbl_entry[MAX_VOLUMES];
  * XXX advance to next tape first in next_tape
  * XXX label is being read twice?
  */
-long splitsize = 0; /* max size of dumpfile before split (Kb) */
-char *splitbuf = NULL;
-char *splitbuf_wr_ptr = NULL; /* the number of Kb we've written into splitbuf */
+static off_t splitsize = (off_t)0; /* max size of dumpfile before split (Kb) */
+static off_t mmap_splitsize = (off_t)0;
+static char *mmap_filename = NULL;
+static char *mmap_splitbuf = NULL;
+static char *mem_splitbuf = NULL;
+static char *splitbuf = NULL;
+static off_t mem_splitsize = (off_t)0;
+static char *splitbuf_wr_ptr = NULL; /* the number of Kb we've written into splitbuf */
 int orig_holdfile = -1;
 
 /* NBUFS replaced by conf_tapebufs */
 /* #define NBUFS               20 */
-int conf_tapebufs;
+static int conf_tapebufs;
 
-off_t maxseek = (off_t)1 << ((sizeof(off_t) * 8) - 11);
+static off_t maxseek = (off_t)1 << ((SIZEOF(off_t) * 8) - 11);
 
-char *holdfile_path = NULL;
-char *holdfile_path_thischunk = NULL;
-int num_holdfile_chunks = 0;
-dumpfile_t holdfile_hdr;
-dumpfile_t holdfile_hdr_thischunk;
-off_t holdfile_offset_thischunk = (off_t)0;
-int splitbuffer_fd = -1;
-char *splitbuffer_path = NULL;
+static char *holdfile_path = NULL;
+static char *holdfile_path_thischunk = NULL;
+static int num_holdfile_chunks = 0;
+static off_t holdfile_offset_thischunk = (off_t)0;
+static int mmap_splitbuffer_fd = -1;
 
 #define MODE_NONE 0
 #define MODE_FILE_WRITE 1
 #define MODE_PORT_WRITE 2
 
-int mode = MODE_NONE;
+static mode_t mode = MODE_NONE;
 
 /* This is now the number of empties, not full bufs */
 #define THRESHOLD      1
 
 #define CONNECT_TIMEOUT 2*60
 
-
-
 #define EMPTY 1
 #define FILLING 2
 #define FULL 3
 
 typedef struct buffer_s {
     long status;
-    unsigned int size;
+    ssize_t size;
     char *buffer;
 } buffer_t;
 
@@ -123,14 +123,15 @@ typedef struct buffer_s {
 #define prevbuf(p)    ((p) == buftable? buftable+conf_tapebufs-1 : (p)-1)
 
 /* major modules */
-int main P((int main_argc, char **main_argv));
-void file_reader_side P((int rdpipe, int wrpipe));
-void tape_writer_side P((int rdpipe, int wrpipe));
+int main(int main_argc, char **main_argv);
+void file_reader_side(int rdpipe, int wrpipe);
+void tape_writer_side(int rdpipe, int wrpipe);
+void put_syncpipe_fault_result(char *handle);
 
 /* shared-memory routines */
-char *attach_buffers P((unsigned int size));
-void detach_buffers P((char *bufp));
-void destroy_buffers P((void));
+char *attach_buffers(size_t size);
+void detach_buffers(char *bufp);
+void destroy_buffers(void);
 #define REMOVE_SHARED_MEMORY() \
     detach_buffers(buffers); \
     if (strcmp(procname, "reader") == 0) { \
@@ -138,29 +139,31 @@ void destroy_buffers P((void));
     }
 
 /* synchronization pipe routines */
-void syncpipe_init P((int rd, int wr));
-char syncpipe_get P((int *intp));
-int  syncpipe_getint P((void));
-char *syncpipe_getstr P((void));
-void syncpipe_put P((int ch, int intval));
-void syncpipe_putint P((int i));
-void syncpipe_putstr P((const char *str));
+void syncpipe_init(int rd, int wr);
+void syncpipe_read_error(ssize_t rc, ssize_t expected);
+void syncpipe_write_error(ssize_t rc, ssize_t expected);
+int syncpipe_get(int *intp);
+int syncpipe_getint(void);
+char *syncpipe_getstr(void);
+int syncpipe_put(int ch, int intval);
+int syncpipe_putint(int i);
+int syncpipe_putstr(const char *str);
 
 /* tape manipulation subsystem */
-int first_tape P((char *new_datestamp));
-int next_tape P((int writerr));
-int end_tape P((int writerr));
-int write_filemark P((void));
+int first_tape(char *new_datestamp);
+int next_tape(int writerr);
+int end_tape(int writerr);
+int write_filemark(void);
 
 /* support crap */
-int seek_holdfile P((int fd, buffer_t *bp, long kbytes));
+int seek_holdfile(int fd, buffer_t *bp, off_t kbytes);
 
 /* signal handling */
-static void install_signal_handlers P((void));
-static void signal_handler P((int));
+static void install_signal_handlers(void);
+static void signal_handler(int);
 
 /* exit routine */
-static void cleanup P((void));
+static void cleanup(void);
 
 /*
  * ========================================================================
@@ -168,7 +171,7 @@ static void cleanup P((void));
  *
  */
 int interactive;
-int writerpid;
+pid_t writerpid;
 times_t total_wait;
 #ifdef TAPER_DEBUG
 int bufdebug = 1;
@@ -182,7 +185,7 @@ int err;
 
 char *procname = "parent";
 
-char *taper_datestamp = NULL;
+char *taper_timestamp = NULL;
 char *label = NULL;
 int filenum;
 char *errstr = NULL;
@@ -190,15 +193,15 @@ int tape_fd = -1;
 char *tapedev = NULL;
 char *tapetype = NULL;
 tapetype_t *tt = NULL;
-long tt_blocksize;
-long tt_blocksize_kb;
-long buffer_size;
+size_t tt_blocksize;
+size_t tt_blocksize_kb;
+size_t buffer_size;
 int tt_file_pad;
 static unsigned long malloc_hist_1, malloc_size_1;
 static unsigned long malloc_hist_2, malloc_size_2;
 dumpfile_t file;
 dumpfile_t *save_holdfile = NULL;
-long cur_span_chunkstart = 0; /* start of current split dump chunk (Kb) */
+off_t cur_span_chunkstart = (off_t)0; /* start of current split dump chunk (Kb) */
 char *holdfile_name;
 int num_splits = 0;
 int expected_splits = 0;
@@ -219,41 +222,53 @@ int first_seg, last_seg;
  * MAIN PROGRAM
  *
  */
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+int
+main(
+    int main_argc,
+    char **main_argv)
 {
     int p2c[2], c2p[2];                /* parent-to-child, child-to-parent pipes */
     char *conffile;
-    unsigned int size;
+    size_t size;
     int i;
-    int j;
-    int page_size;
+    size_t j;
+    size_t page_size;
     char *first_buffer;
+    int    new_argc,   my_argc;
+    char **new_argv, **my_argv;
 
     safe_fd(-1, 0);
 
     set_pname("taper");
 
+    dbopen("server");
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
 
+    parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+    my_argc = new_argc;
+    my_argv = new_argv;
+
     fprintf(stderr, "%s: pid %ld executable %s version %s\n",
-           get_pname(), (long) getpid(), main_argv[0], version());
+           get_pname(), (long) getpid(), my_argv[0], version());
+    dbprintf(("%s: pid %ld executable %s version %s\n",
+           get_pname(), (long) getpid(), my_argv[0], version()));
     fflush(stderr);
 
-    if (main_argc > 1 && main_argv[1][0] != '-') {
-       config_name = stralloc(main_argv[1]);
-       config_dir = vstralloc(CONFIG_DIR, "/", main_argv[1], "/", NULL);
-       main_argc--;
-       main_argv++;
+    if (my_argc > 1 && my_argv[1][0] != '-') {
+       config_name = stralloc(my_argv[1]);
+       config_dir = vstralloc(CONFIG_DIR, "/", my_argv[1], "/", NULL);
+       my_argc--;
+       my_argv++;
     } else {
        char my_cwd[STR_SIZE];
 
-       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
            error("cannot determine current working directory");
+           /*NOTREACHED*/
        }
        config_dir = stralloc2(my_cwd, "/");
        if ((config_name = strrchr(my_cwd, '/')) != NULL) {
@@ -268,35 +283,43 @@ char **main_argv;
 
     /* print prompts and debug messages if running interactive */
 
-    interactive = (main_argc > 1 && strcmp(main_argv[1],"-t") == 0);
-    if(interactive) {
+    interactive = (my_argc > 1 && strcmp(my_argv[1],"-t") == 0);
+    if (interactive) {
        erroutput_type = ERR_INTERACTIVE;
     } else {
        erroutput_type = ERR_AMANDALOG;
        set_logerror(logerror);
     }
 
+    free_new_argv(new_argc, new_argv);
+
     conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if(read_conffile(conffile)) {
+    if (read_conffile(conffile)) {
        error("errors processing config file \"%s\"", conffile);
+       /*NOTREACHED*/
     }
     amfree(conffile);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
+
+    report_bad_conf_arg();
+
     conf_tapelist = getconf_str(CNF_TAPELIST);
     if (*conf_tapelist == '/') {
        conf_tapelist = stralloc(conf_tapelist);
     } else {
        conf_tapelist = stralloc2(config_dir, conf_tapelist);
     }
-    if(read_tapelist(conf_tapelist)) {
+    if (read_tapelist(conf_tapelist)) {
        error("could not load tapelist \"%s\"", conf_tapelist);
+       /*NOTREACHED*/
     }
 
-    tapedev    = getconf_str(CNF_TAPEDEV);
+    tapedev    = stralloc(getconf_str(CNF_TAPEDEV));
     tapetype    = getconf_str(CNF_TAPETYPE);
     tt         = lookup_tapetype(tapetype);
 #ifdef HAVE_LIBVTBLC
-    rawtapedev = getconf_str(CNF_RAWTAPEDEV);
+    rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
 #endif /* HAVE_LIBVTBLC */
     tapedays   = getconf_int(CNF_TAPECYCLE);
     labelstr   = getconf_str(CNF_LABELSTR);
@@ -306,38 +329,52 @@ char **main_argv;
 
     conf_tapebufs = getconf_int(CNF_TAPEBUFS);
 
-    tt_blocksize_kb = tt->blocksize;
+    tt_blocksize_kb = (size_t)tapetype_get_blocksize(tt);
     tt_blocksize = tt_blocksize_kb * 1024;
-    tt_file_pad = tt->file_pad;
+    tt_file_pad = tapetype_get_file_pad(tt);
 
-    if(interactive) {
+    if (interactive) {
        fprintf(stderr,"taper: running in interactive test mode\n");
+       dbprintf(("taper: running in interactive test mode\n"));
        fflush(stderr);
     }
 
     /* create read/write syncronization pipes */
 
-    if(pipe(p2c) || pipe(c2p))
+    if (pipe(p2c)) {
+       error("creating sync pipes: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+    if (pipe(c2p)) {
        error("creating sync pipes: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
     /* create shared memory segment */
 
 #if defined(HAVE_GETPAGESIZE)
-    page_size = getpagesize();
-    fprintf(stderr, "%s: page size is %d\n", get_pname(), page_size);
+    page_size = (size_t)getpagesize();
+    fprintf(stderr, "%s: page size = " SIZE_T_FMT "\n",
+               get_pname(), (SIZE_T_FMT_TYPE)page_size);
+    dbprintf(("%s: page size = " SIZE_T_FMT "\n", get_pname(),
+               (SIZE_T_FMT_TYPE)page_size));
 #else
     page_size = 1024;
-    fprintf(stderr, "%s: getpagesize() not available, using %d\n",
-           get_pname(),
-           page_size);
+    fprintf(stderr, "%s: getpagesize() not available, using " SIZE_T_FMT "\n",
+           get_pname(), page_size);
+    dbprintf((stderr, "%s: getpagesize() not available, using " SIZE_T_FMT "\n",
+           get_pname(), page_size));
 #endif
     buffer_size = am_round(tt_blocksize, page_size);
-    fprintf(stderr, "%s: buffer size is %ld\n", get_pname(), buffer_size);
-    while(conf_tapebufs > 0) {
+    fprintf(stderr, "%s: buffer size is " SIZE_T_FMT "\n",
+           get_pname(), (SIZE_T_FMT_TYPE)buffer_size);
+    dbprintf(("%s: buffer size is " SIZE_T_FMT "\n",
+           get_pname(), (SIZE_T_FMT_TYPE)buffer_size));
+    while (conf_tapebufs > 0) {
        size  = page_size;
        size += conf_tapebufs * buffer_size;
-       size += conf_tapebufs * sizeof(buffer_t);
-       if((buffers = attach_buffers(size)) != NULL) {
+       size += conf_tapebufs * SIZEOF(buffer_t);
+       if ((buffers = attach_buffers(size)) != NULL) {
            break;
        }
        log_add(L_INFO, "attach_buffers: (%d tapebuf%s: %d bytes) %s",
@@ -347,45 +384,50 @@ char **main_argv;
                        strerror(errno));
        conf_tapebufs--;
     }
-    if(buffers == NULL) {
+    if (buffers == NULL) {
        error("cannot allocate shared memory");
+       /*NOTREACHED*/
     }
-    i = (buffers - (char *)0) & (page_size - 1);  /* page boundary offset */
-    if(i != 0) {
+
+    /* page boundary offset */
+    i = (int)((buffers - (char *)0) & (page_size - 1));
+    if (i != 0) {
        first_buffer = buffers + page_size - i;
-       fprintf(stderr, "%s: shared memory at %p, first buffer at %p\n",
+       dbprintf(("%s: shared memory at %p, first buffer at %p\n",
                get_pname(),
-               buffers,
-               first_buffer);
+               (void *)buffers,
+               (void *)first_buffer));
     } else {
        first_buffer = buffers;
     }
-    buftable = (buffer_t *)(first_buffer + conf_tapebufs * buffer_size);
-    memset(buftable, 0, conf_tapebufs * sizeof(buffer_t));
-    if(conf_tapebufs < 10) {
+
+    /*LINTED  first_buffer, conf_tapebufs and buffer size are all * pagesize */
+    buftable = (buffer_t *)(first_buffer + (conf_tapebufs * buffer_size));
+    memset(buftable, 0, conf_tapebufs * SIZEOF(buffer_t));
+    if (conf_tapebufs < 10) {
        j = 1;
-    } else if(conf_tapebufs < 100) {
+    } else if (conf_tapebufs < 100) {
        j = 2;
     } else {
        j = 3;
     }
-    for(i = 0; i < conf_tapebufs; i++) {
+    for (i = 0; i < conf_tapebufs; i++) {
        buftable[i].buffer = first_buffer + i * buffer_size;
-       fprintf(stderr, "%s: buffer[%0*d] at %p\n",
+       dbprintf(("%s: buffer[%0*d] at %p\n",
                get_pname(),
-               j, i,
-               buftable[i].buffer);
+               (int)j, i,
+               (void *)buftable[i].buffer));
     }
-    fprintf(stderr, "%s: buffer structures at %p for %d bytes\n",
+    dbprintf(("%s: buffer structures at %p for %d bytes\n",
            get_pname(),
-           buftable,
-           (int)(conf_tapebufs * sizeof(buffer_t)));
+           (void *)buftable,
+           (int)(conf_tapebufs * SIZEOF(buffer_t))));
 
     /* fork off child writer process, parent becomes reader process */
-
     switch(writerpid = fork()) {
     case -1:
        error("fork: %s", strerror(errno));
+       /*NOTREACHED*/
 
     case 0:    /* child */
        aclose(p2c[1]);
@@ -393,6 +435,7 @@ char **main_argv;
 
        tape_writer_side(p2c[0], c2p[1]);
        error("tape writer terminated unexpectedly");
+       /*NOTREACHED*/
 
     default:   /* parent */
        aclose(p2c[0]);
@@ -400,9 +443,10 @@ char **main_argv;
 
        file_reader_side(c2p[0], p2c[1]);
        error("file reader terminated unexpectedly");
+       /*NOTREACHED*/
     }
 
-    /* NOTREACHED */
+    /*NOTREACHED*/
     return 0;
 }
 
@@ -412,33 +456,34 @@ char **main_argv;
  * FILE READER SIDE
  *
  */
-int read_file P((int fd, char *handle,
+int read_file(int fd, char *handle,
                  char *host, char *disk, char *datestamp, 
-                 int level));
-int taper_fill_buffer P((int fd, buffer_t *bp, int buflen));
-void dumpbufs P((char *str1));
-void dumpstatus P((buffer_t *bp));
-int get_next_holding_file P((int fd, buffer_t *bp, char *strclosing, int rc));
-int predict_splits P((char *filename));
-void create_split_buffer P((char *split_diskbuffer, long fallback_splitsize, char *id_string));
-void free_split_buffer P(());
+                 int level);
+ssize_t taper_fill_buffer(int fd, buffer_t *bp, size_t buflen);
+void dumpbufs(char *str1);
+void dumpstatus(buffer_t *bp);
+ssize_t get_next_holding_file(int fd, buffer_t *bp, char **strclosing, size_t rc);
+int predict_splits(char *filename);
+void create_split_buffer(char *split_diskbuffer, size_t fallback_splitsize, char *id_string);
+void free_split_buffer(void);
 
 
 /*
  * Create a buffer, either in an mmapped file or in memory, where PORT-WRITE
  * dumps can buffer the current split chunk in case of retry.
  */
-void create_split_buffer(split_diskbuffer, fallback_splitsize, id_string)
-char *split_diskbuffer;
-long fallback_splitsize;
-char *id_string;
+void
+create_split_buffer(
+    char *split_diskbuffer,
+    size_t fallback_splitsize,
+    char *id_string)
 {
     char *buff_err = NULL;
-    void *nulls = NULL;
-    int c;
+    off_t offset;
+    char *splitbuffer_path = NULL;
     
     /* don't bother if we're not actually splitting */
-    if(splitsize <= 0){
+    if (splitsize <= (off_t)0) {
        splitbuf = NULL;
        splitbuf_wr_ptr = NULL;
        return;
@@ -446,56 +491,107 @@ char *id_string;
 
 #ifdef HAVE_MMAP
 #ifdef HAVE_SYS_MMAN_H
-    if(strcmp(split_diskbuffer, "NULL")){
+    if (strcmp(split_diskbuffer, "NULL")) {
+       void *nulls = NULL;
+       char *quoted;
+       off_t c;
+
        splitbuffer_path = vstralloc(split_diskbuffer,
-                                    "/splitdump_buffer_XXXXXX",
+                                    "/splitdump_buffer",
                                     NULL);
-#ifdef HAVE_MKSTEMP
-       splitbuffer_fd = mkstemp(splitbuffer_path);
-#else
-       log_add(L_INFO, "mkstemp not available, using plain open() for split buffer- make sure %s has safe permissions", split_diskbuffer);
-       splitbuffer_fd = open(splitbuffer_path, O_RDWR|O_CREAT, 0600);
-#endif
-       if(splitbuffer_fd == -1){
-           buff_err = newvstralloc(buff_err, "mkstemp/open of ", 
-                                   splitbuffer_path, "failed (",
-                                   strerror(errno), ")", NULL);
-           goto fallback;
+       /* different file, munmap the previous */
+       if (mmap_filename && strcmp(mmap_filename, splitbuffer_path) != 0) {
+           dbprintf(("create_split_buffer: new file %s\n", splitbuffer_path));
+           munmap(splitbuf, (size_t)mmap_splitsize);
+           aclose(mmap_splitbuffer_fd);
+           mmap_splitbuf = NULL;
+           amfree(mmap_filename);
+           mmap_splitsize = 0;
        }
-       nulls = alloc(1024); /* lame */
-       memset(nulls, 0, 1024);
-       for(c = 0; c < splitsize ; c++) {
-           if(fullwrite(splitbuffer_fd, nulls, 1024) < 1024){
-               buff_err = newvstralloc(buff_err, "write to ", splitbuffer_path,
-                                       "failed (", strerror(errno), ")", NULL);
-               free_split_buffer();
+       if (!mmap_filename) {
+           dbprintf(("create_split_buffer: open file %s\n",
+                     splitbuffer_path));
+           mmap_splitbuffer_fd = open(splitbuffer_path, O_RDWR|O_CREAT, 0600);
+           if (mmap_splitbuffer_fd == -1) {
+               buff_err = newvstralloc(buff_err, "open of ", 
+                                       splitbuffer_path, "failed (",
+                                       strerror(errno), ")", NULL);
                goto fallback;
            }
        }
+       offset = lseek(mmap_splitbuffer_fd, (off_t)0, SEEK_END) / 1024;
+       if (offset < splitsize) { /* Increase file size */
+           dbprintf(("create_split_buffer: increase file size of %s to "
+                     OFF_T_FMT "kb\n",
+                     splitbuffer_path, (OFF_T_FMT_TYPE)splitsize));
+           if (mmap_filename) {
+               dbprintf(("create_split_buffer: munmap old file %s\n",
+                         mmap_filename));
+               munmap(splitbuf, (size_t)mmap_splitsize);
+               mmap_splitsize = 0;
+               mmap_splitbuf = NULL;
+           }
+           nulls = alloc(1024); /* lame */
+           memset(nulls, 0, 1024);
+           for (c = offset; c < splitsize ; c += (off_t)1) {
+               if (fullwrite(mmap_splitbuffer_fd, nulls, 1024) < 1024) {
+                   buff_err = newvstralloc(buff_err, "write to ",
+                                           splitbuffer_path,
+                                           "failed (", strerror(errno),
+                                           ")", NULL);
+                   c -= 1;
+                   if (c <= (off_t)fallback_splitsize) {
+                       goto fallback;
+                   }
+                   splitsize = c;
+                   break;
+               }
+           }
+       }
        amfree(nulls);
 
-        splitbuf = mmap(NULL, (size_t)splitsize*1024, PROT_READ|PROT_WRITE,
-                       MAP_SHARED, splitbuffer_fd, (off_t)0);
-       if(splitbuf == (char*)-1){
-           buff_err = newvstralloc(buff_err, "mmap failed (", strerror(errno),
-                                   ")", NULL);
-           free_split_buffer();
-           goto fallback;
+       if (mmap_splitsize < splitsize*1024) {
+           mmap_splitsize = splitsize*1024;
+           mmap_filename = stralloc(splitbuffer_path);
+           dbprintf(("create_split_buffer: mmap file %s for " OFF_T_FMT "kb\n",
+                         mmap_filename,(OFF_T_FMT_TYPE)splitsize));
+            mmap_splitbuf = mmap(NULL, (size_t)mmap_splitsize,
+                                PROT_READ|PROT_WRITE,
+                                MAP_SHARED, mmap_splitbuffer_fd, (off_t)0);
+           if (mmap_splitbuf == (char*)-1) {
+               buff_err = newvstralloc(buff_err, "mmap failed (",
+                                       strerror(errno), ")", NULL);
+               aclose(mmap_splitbuffer_fd);
+               amfree(mmap_filename);
+               mmap_splitsize = 0;
+               mmap_splitbuf = NULL;
+               goto fallback;
+           }
        }
+       quoted = quote_string(splitbuffer_path);
        fprintf(stderr,
-               "taper: r: buffering %ldkb split chunks in mmapped file %s\n",
-               splitsize, splitbuffer_path);
+               "taper: r: buffering " OFF_T_FMT
+               "kb split chunks in mmapped file %s\n",
+               (OFF_T_FMT_TYPE)splitsize, quoted);
+       dbprintf(("taper: r: buffering " OFF_T_FMT
+               "kb split chunks in mmapped file %s\n",
+               (OFF_T_FMT_TYPE)splitsize, quoted));
+       amfree(splitbuffer_path);
+       amfree(quoted);
+       amfree(buff_err);
+       splitbuf = mmap_splitbuf;
        splitbuf_wr_ptr = splitbuf;
        return;
-    }
-    else{
+    } else {
        buff_err = stralloc("no split_diskbuffer specified");
     }
 #else
+    (void)split_diskbuffer;    /* Quite unused parameter warning */
     buff_err = stralloc("mman.h not available");
     goto fallback;
 #endif
 #else
+    (void)split_diskbuffer;    /* Quite unused parameter warning */
     buff_err = stralloc("mmap not available");
     goto fallback;
 #endif
@@ -504,64 +600,93 @@ char *id_string;
       Buffer split dumps in memory, if we can't use a file.
     */
     fallback:
-        splitsize = fallback_splitsize;
+       amfree(splitbuffer_path);
+        splitsize = (off_t)fallback_splitsize;
+       dbprintf(("create_split_buffer: fallback size " OFF_T_FMT "\n",
+                 (OFF_T_FMT_TYPE)splitsize));
        log_add(L_INFO,
                "%s: using fallback split size of %dkb to buffer %s in-memory",
                buff_err, splitsize, id_string);
-       splitbuf = alloc(splitsize * 1024);
+       amfree(buff_err);
+       if (splitsize > mem_splitsize) {
+           amfree(mem_splitbuf);
+           mem_splitbuf = alloc(fallback_splitsize * 1024);
+           mem_splitsize = fallback_splitsize;
+           dbprintf(("create_split_buffer: alloc buffer size " OFF_T_FMT "\n",
+                         (OFF_T_FMT_TYPE)splitsize *1024));
+       }
+       splitbuf = mem_splitbuf;
        splitbuf_wr_ptr = splitbuf;
 }
 
 /*
  * Free up resources that create_split_buffer eats.
  */
-void free_split_buffer()
+void
+free_split_buffer(void)
 {
-    if(splitbuffer_fd != -1){
+    if (mmap_splitbuffer_fd != -1) {
 #ifdef HAVE_MMAP
 #ifdef HAVE_SYS_MMAN_H
-       if(splitbuf != NULL) munmap(splitbuf, splitsize);
+       if (splitbuf != NULL)
+           munmap(splitbuf, (size_t)mmap_splitsize);
 #endif
 #endif
-       aclose(splitbuffer_fd);
-       splitbuffer_fd = -1;
-
-       if(unlink(splitbuffer_path) == -1){
-           log_add(L_WARNING, "Failed to unlink %s: %s",
-                   splitbuffer_path, strerror(errno));
-       }
-       amfree(splitbuffer_path);
-       splitbuffer_path = NULL;
+       aclose(mmap_splitbuffer_fd);
+       amfree(mmap_filename);
+       mmap_splitsize = 0;
     }
-    else if(splitbuf){
+    if (mem_splitbuf) {
        amfree(splitbuf);
-       splitbuf = NULL;
+       mem_splitsize = 0;
     }
 }
 
+void
+put_syncpipe_fault_result(
+    char *     handle)
+{
+    char *q;
+
+    if (handle == NULL)
+       handle = "<nohandle>";
+
+    q = squotef("[Taper syncpipe fault]");
+    putresult(TAPE_ERROR, "%s %s\n", handle, q);
+    log_add(L_ERROR, "tape-error %s %s", handle, q);
+    amfree(q);
+}
 
-void file_reader_side(rdpipe, wrpipe)
-int rdpipe, wrpipe;
+void
+file_reader_side(
+    int rdpipe,
+    int wrpipe)
 {
     cmd_t cmd;
     struct cmdargs cmdargs;
     char *handle = NULL;
     char *filename = NULL;
+    char *qfilename = NULL;
     char *hostname = NULL;
     char *diskname = NULL;
+    char *qdiskname = NULL;
     char *result = NULL;
     char *datestamp = NULL;
     char *split_diskbuffer = NULL;
     char *id_string = NULL;
-    char tok;
+    int tok;
     char *q = NULL;
-    int level, fd, data_port, data_socket, wpid;
+    int level, fd;
+    in_port_t data_port;
+    int data_socket;
+    pid_t wpid;
     char level_str[64];
     struct stat stat_file;
     int tape_started;
     int a;
-    long fallback_splitsize = 0;
+    size_t fallback_splitsize = 0;
     int tmpint;
+    char *c, *c1;
 
     procname = "reader";
     syncpipe_init(rdpipe, wrpipe);
@@ -572,48 +697,92 @@ int rdpipe, wrpipe;
     cmd = getcmd(&cmdargs);
     total_wait = stopclock();
 
-    if(cmd != START_TAPER || cmdargs.argc != 2) {
+    if (cmd != START_TAPER || cmdargs.argc != 2) {
        error("error [file_reader_side cmd %d argc %d]", cmd, cmdargs.argc);
+       /*NOTREACHED*/
     }
 
     /* pass start command on to tape writer */
 
-    taper_datestamp = newstralloc(taper_datestamp, cmdargs.argv[2]);
+    taper_timestamp = newstralloc(taper_timestamp, cmdargs.argv[2]);
 
     tape_started = 0;
-    syncpipe_put('S', 0);
-    syncpipe_putstr(taper_datestamp);
+    if (syncpipe_put('S', 0) == -1) {
+       put_syncpipe_fault_result(NULL);
+    }
+
+    if (syncpipe_putstr(taper_timestamp) == -1) {
+       put_syncpipe_fault_result(NULL);
+    }
 
     /* get result of start command */
 
     tok = syncpipe_get(&tmpint);
     switch(tok) {
+    case -1:
+       put_syncpipe_fault_result(NULL);
+       break;
+
     case 'S':
        putresult(TAPER_OK, "\n");
        tape_started = 1;
        /* start is logged in writer */
        break;
+
     case 'E':
        /* no tape, bail out */
-       result = syncpipe_getstr();
-       q = squotef("[%s]", result ? result : "(null)");
-       putresult(TAPE_ERROR, "%s\n", q);
-       amfree(q);
-       log_add(L_ERROR,"no-tape [%s]", "No writable valid tape found");
-       amfree(result);
-       syncpipe_put('e', 0);                   /* ACK error */
+       if ((result = syncpipe_getstr()) == NULL) {
+           put_syncpipe_fault_result(NULL);
+       } else {
+           q = squotef("[%s]", result);
+           putresult(TAPE_ERROR, "<nohandle> %s\n", q);
+           amfree(q);
+           log_add(L_ERROR,"no-tape [%s]", "No writable valid tape found");
+           c = c1 = result;
+           while (*c != '\0') {
+               if (*c == '\n') {
+                   *c = '\0';
+                   log_add(L_WARNING,"%s", c1);
+                   c1 = c+1;
+               }
+               c++;
+           }
+           if (strlen(c1) > 1 )
+               log_add(L_WARNING,"%s", c1);
+           amfree(result);
+           (void)syncpipe_put('e', 0);                 /* ACK error */
+       }
+       break;
+
+    case 'H': /* Syncpipe I/O error */
+       /* No ACK syncpipe is down just exit */
+        put_syncpipe_fault_result(handle);
        break;
+
+    case 'X':
+       /*
+        * Pipe read error: Communications is severed at least
+        * back to us.  We send a blind 'Q' (quit) and we don't
+        * wait for a response...
+        */
+       syncpipe_put('Q', 0);                   /* ACK error */
+       error("error [communications pipe from writer severed]");
+       /*NOTREACHED*/
+
     default:
-       error("expected 'S' or 'E' for START-TAPER, got '%c'", tok);
+       q = squotef("[syncpipe sequence fault: Expected 'S' or 'E']");
+       putresult(TAPE_ERROR, "<nohandle> %s\n", q);
+       log_add(L_ERROR, "no-tape %s]", q);
+       amfree(q);
     }
 
-    /* process further commands */
-
-    while(1) {
+    /* process further driver commands */
+    while (1) {
        startclock();
        cmd = getcmd(&cmdargs);
-       if(cmd != QUIT && !tape_started) {
+       if (cmd != QUIT && !tape_started) {
            error("error [file_reader_side cmd %d without tape ready]", cmd);
+           /*NOTREACHED*/
        }
        total_wait = timesadd(total_wait, stopclock());
 
@@ -634,67 +803,86 @@ int rdpipe, wrpipe;
            cmdargs.argc++;                     /* true count of args */
            a = 2;
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: handle]");
+               /*NOTREACHED*/
            }
            handle = newstralloc(handle, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: hostname]");
+               /*NOTREACHED*/
            }
            hostname = newstralloc(hostname, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: features]");
+               /*NOTREACHED*/
            }
            am_release_feature_set(their_features);
            their_features = am_string_to_feature(cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: diskname]");
+               /*NOTREACHED*/
            }
-           diskname = newstralloc(diskname, cmdargs.argv[a++]);
+           qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]);
+           if (diskname != NULL)
+               amfree(diskname);
+           diskname = unquote_string(qdiskname);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: level]");
+               /*NOTREACHED*/
            }
            level = atoi(cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: datestamp]");
+               /*NOTREACHED*/
            }
            datestamp = newstralloc(datestamp, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: splitsize]");
+               /*NOTREACHED*/
            }
-           splitsize = atoi(cmdargs.argv[a++]);
+           splitsize = OFF_T_ATOI(cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: split_diskbuffer]");
+               /*NOTREACHED*/
            }
            split_diskbuffer = newstralloc(split_diskbuffer, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper PORT-WRITE: not enough args: fallback_splitsize]");
+               /*NOTREACHED*/
            }
-           fallback_splitsize = atoi(cmdargs.argv[a++]);
+           /* Must fit in memory... */
+           fallback_splitsize = (size_t)atoi(cmdargs.argv[a++]);
 
-           if(a != cmdargs.argc) {
+           if (a != cmdargs.argc) {
                error("error [taper file_reader_side PORT-WRITE: too many args: %d != %d]",
                      cmdargs.argc, a);
+               /*NOTREACHED*/
            }
 
-           snprintf(level_str, sizeof(level_str), "%d", level);
-           id_string = newvstralloc(id_string, hostname, ":", diskname, ".",
+           if (fallback_splitsize < 128 ||
+               fallback_splitsize > 64 * 1024 * 1024) {
+               error("error [bad value for fallback_splitsize]");
+               /*NOTREACHED*/
+           }
+           snprintf(level_str, SIZEOF(level_str), "%d", level);
+           id_string = newvstralloc(id_string, hostname, ":", qdiskname, ".",
                                     level_str, NULL);
 
            create_split_buffer(split_diskbuffer, fallback_splitsize, id_string);
            amfree(id_string);
 
            data_port = 0;
-           data_socket = stream_server(&data_port, -1, STREAM_BUFSIZE);        
-           if(data_socket < 0) {
+           data_socket = stream_server(&data_port, 0, STREAM_BUFSIZE, 0);      
+           if (data_socket < 0) {
                char *m;
 
                m = vstralloc("[port create failure: ",
@@ -709,8 +897,8 @@ int rdpipe, wrpipe;
            }
            putresult(PORT, "%d\n", data_port);
 
-           if((fd = stream_accept(data_socket, CONNECT_TIMEOUT,
-                                  -1, NETWORK_BLOCK_BYTES)) == -1) {
+           if ((fd = stream_accept(data_socket, CONNECT_TIMEOUT,
+                                  0, STREAM_BUFSIZE)) == -1) {
                q = squote("[port connect timeout]");
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
                aclose(data_socket);
@@ -719,10 +907,10 @@ int rdpipe, wrpipe;
            }
            expected_splits = -1;
 
-           while(read_file(fd,handle,hostname,diskname,datestamp,level));
+           while(read_file(fd, handle, hostname, qdiskname, datestamp, level))
+               (void)fd;  /* Quiet lint */
 
            aclose(data_socket);
-           free_split_buffer();
            break;
 
        case FILE_WRITE:
@@ -741,65 +929,80 @@ int rdpipe, wrpipe;
            cmdargs.argc++;                     /* true count of args */
            a = 2;
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: handle]");
+               /*NOTREACHED*/
            }
            handle = newstralloc(handle, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: filename]");
+               /*NOTREACHED*/
            }
-           filename = newstralloc(filename, cmdargs.argv[a++]);
+           qfilename = newstralloc(qfilename, cmdargs.argv[a++]);
+           if (filename != NULL)
+               amfree(filename);
+           filename = unquote_string(qfilename);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: hostname]");
+               /*NOTREACHED*/
            }
            hostname = newstralloc(hostname, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: features]");
+               /*NOTREACHED*/
            }
            am_release_feature_set(their_features);
            their_features = am_string_to_feature(cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: diskname]");
+               /*NOTREACHED*/
            }
-           diskname = newstralloc(diskname, cmdargs.argv[a++]);
+           qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]);
+           if (diskname != NULL)
+               amfree(diskname);
+           diskname = unquote_string(qdiskname);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: level]");
+               /*NOTREACHED*/
            }
            level = atoi(cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: datestamp]");
+               /*NOTREACHED*/
            }
            datestamp = newstralloc(datestamp, cmdargs.argv[a++]);
 
-           if(a >= cmdargs.argc) {
+           if (a >= cmdargs.argc) {
                error("error [taper FILE-WRITE: not enough args: splitsize]");
+               /*NOTREACHED*/
            }
-           splitsize = atoi(cmdargs.argv[a++]);
+           splitsize = OFF_T_ATOI(cmdargs.argv[a++]);
 
-           if(a != cmdargs.argc) {
+           if (a != cmdargs.argc) {
                error("error [taper file_reader_side FILE-WRITE: too many args: %d != %d]",
                      cmdargs.argc, a);
+               /*NOTREACHED*/
            }
-           if(holdfile_name != NULL) {
+           if (holdfile_name != NULL) {
                filename = newstralloc(filename, holdfile_name);
            }
 
-           if((expected_splits = predict_splits(filename)) < 0) {
+           if ((expected_splits = predict_splits(filename)) < 0) {
                break;
            }
-           if(stat(filename, &stat_file)!=0) {
+           if (stat(filename, &stat_file)!=0) {
                q = squotef("[%s]", strerror(errno));
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
                amfree(q);
                break;
            }
-           if((fd = open(filename, O_RDONLY)) == -1) {
+           if ((fd = open(filename, O_RDONLY)) == -1) {
                q = squotef("[%s]", strerror(errno));
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
                amfree(q);
@@ -809,17 +1012,16 @@ int rdpipe, wrpipe;
            holdfile_path_thischunk = stralloc(filename);
            holdfile_offset_thischunk = (off_t)0;
 
-           while(read_file(fd,handle,hostname,diskname,datestamp,level)){
-               if(splitsize > 0 && holdfile_path_thischunk)
+           while (read_file(fd,handle,hostname,qdiskname,datestamp,level)) {
+               if (splitsize > (off_t)0 && holdfile_path_thischunk)
                    filename = newstralloc(filename, holdfile_path_thischunk);
-               if((fd = open(filename, O_RDONLY)) == -1) {
+               if ((fd = open(filename, O_RDONLY)) == -1) {
                    q = squotef("[%s]", strerror(errno));
                    putresult(TAPE_ERROR, "%s %s\n", handle, q);
                    amfree(q);
                    break;
                }
            }
-
            break;
 
        case QUIT:
@@ -827,40 +1029,45 @@ int rdpipe, wrpipe;
            fprintf(stderr,"taper: DONE [idle wait: %s secs]\n",
                    walltime_str(total_wait));
            fflush(stderr);
-           syncpipe_put('Q', 0);       /* tell writer we're exiting gracefully */
+           (void)syncpipe_put('Q', 0); /* tell writer we're exiting gracefully */
            aclose(wrpipe);
 
-           if((wpid = wait(NULL)) != writerpid) {
+           if ((wpid = wait(NULL)) != writerpid) {
+               dbprintf(("taper: writer wait returned %u instead of %u: %s\n",
+                       (unsigned)wpid, (unsigned)writerpid, strerror(errno)));
                fprintf(stderr,
-                       "taper: writer wait returned %d instead of %d: %s\n",
-                       wpid, writerpid, strerror(errno));
+                       "taper: writer wait returned %u instead of %u: %s\n",
+                       (unsigned)wpid, (unsigned)writerpid, strerror(errno));
                fflush(stderr);
            }
 
-           if (datestamp != NULL)
-               amfree(datestamp);
+           free_split_buffer();
+           amfree(datestamp);
+           clear_tapelist();
+           free_server_config();
+           amfree(taper_timestamp);
            amfree(label);
            amfree(errstr);
            amfree(changer_resultstr);
            amfree(tapedev);
-           amfree(conf_tapelist);
            amfree(filename);
+           amfree(conf_tapelist);
            amfree(config_dir);
            amfree(config_name);
-           if(holdfile_name != NULL) amfree(holdfile_name);
+           amfree(holdfile_name);
 
            malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
-           if(malloc_size_1 != malloc_size_2) {
+           if (malloc_size_1 != malloc_size_2) {
                malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
            }
-
            exit(0);
+           /*NOTREACHED*/
 
        default:
-           if(cmdargs.argc >= 1) {
+           if (cmdargs.argc >= 1) {
                q = squote(cmdargs.argv[1]);
-           } else if(cmdargs.argc >= 0) {
+           } else if (cmdargs.argc >= 0) {
                q = squote(cmdargs.argv[0]);
            } else {
                q = stralloc("(no input?)");
@@ -870,42 +1077,52 @@ int rdpipe, wrpipe;
            break;
        }
     }
-    amfree(handle);
-    am_release_feature_set(their_features);
-    amfree(hostname);
-    amfree(diskname);
-    fprintf(stderr, "TAPER AT END OF READER SIDE\n");
+    /* NOTREACHED */
 }
 
-void dumpbufs(str1)
-char *str1;
+void
+dumpbufs(
+    char *str1)
 {
     int i,j;
     long v;
 
     fprintf(stderr, "%s: state", str1);
-    for(i = j = 0; i < conf_tapebufs; i = j+1) {
+    for (i = j = 0; i < conf_tapebufs; i = j+1) {
        v = buftable[i].status;
-       for(j = i; j < conf_tapebufs && buftable[j].status == v; j++);
+       for(j = i; j < conf_tapebufs && buftable[j].status == v; j++)
+           (void)j; /* Quiet lint */
        j--;
-       if(i == j) fprintf(stderr, " %d:", i);
-       else fprintf(stderr, " %d-%d:", i, j);
+       if (i == j) {
+           fprintf(stderr, " %d:", i);
+       } else {
+           fprintf(stderr, " %d-%d:", i, j);
+       }
        switch(v) {
-       case FULL:      fputc('F', stderr); break;
-       case FILLING:   fputc('f', stderr); break;
-       case EMPTY:     fputc('E', stderr); break;
+       case FULL:
+           fputc('F', stderr);
+           break;
+
+       case FILLING:
+           fputc('f', stderr);
+           break;
+
+       case EMPTY:
+           fputc('E', stderr);
+           break;
+
        default:
            fprintf(stderr, "%ld", v);
            break;
        }
-
     }
     fputc('\n', stderr);
     fflush(stderr);
 }
 
-void dumpstatus(bp)
-buffer_t *bp;
+void
+dumpstatus(
+    buffer_t *bp)
 {
     char pn[2];
     char bt[NUM_STR_SIZE];
@@ -914,15 +1131,24 @@ buffer_t *bp;
 
     pn[0] = procname[0];
     pn[1] = '\0';
-    snprintf(bt, sizeof(bt), "%d", (int)(bp-buftable));
+    snprintf(bt, SIZEOF(bt), "%d", (int)(bp-buftable));
 
     switch(bp->status) {
-    case FULL:         snprintf(status, sizeof(status), "F%d", bp->size);
-                       break;
-    case FILLING:      status[0] = 'f'; status[1] = '\0'; break;
-    case EMPTY:                status[0] = 'E'; status[1] = '\0'; break;
+    case FULL:
+       snprintf(status, SIZEOF(status), "F" SIZE_T_FMT,
+               (SIZE_T_FMT_TYPE)bp->size);
+       break;
+
+    case FILLING:
+       snprintf(status, SIZEOF(status), "f");
+       break;
+
+    case EMPTY:
+       snprintf(status, SIZEOF(status), "E");
+       break;
+
     default:
-       snprintf(status, sizeof(status), "%ld", bp->status);
+       snprintf(status, SIZEOF(status), "%ld", bp->status);
        break;
     }
 
@@ -938,109 +1164,126 @@ buffer_t *bp;
   be another global.  What is rc anyway, 'read count?' I keep thinking it
   should be 'return code')
 */
-int get_next_holding_file(fd, bp, strclosing, rc)
-     int fd;
-     buffer_t *bp;
-     char *strclosing;
+ssize_t
+get_next_holding_file(
+    int fd,
+    buffer_t *bp,
+    char **strclosing,
+    size_t rc)
 {
-    int save_fd, rc1;
+    int save_fd;
+    ssize_t rc1;
     struct stat stat_file;
-    int ret = -1;
+    ssize_t ret = -1;
     
     save_fd = fd;
     close(fd);
     
     /* see if we're fresh out of file */
-    if(file.cont_filename[0] == '\0') {
+    if (file.cont_filename[0] == '\0') {
        err = 0;
        ret = 0;
-    } else if(stat(file.cont_filename, &stat_file) != 0) {
+    } else if (stat(file.cont_filename, &stat_file) != 0) {
        err = errno;
        ret = -1;
-       strclosing = newvstralloc(strclosing,"can't stat: ",file.cont_filename,NULL);
-    } else if((fd = open(file.cont_filename,O_RDONLY)) == -1) {
+       *strclosing = newvstralloc(*strclosing, "can't stat: ",
+                                  file.cont_filename, NULL);
+    } else if ((fd = open(file.cont_filename,O_RDONLY)) == -1) {
        err = errno;
        ret = -1;
-       strclosing = newvstralloc(strclosing,"can't open: ",file.cont_filename,NULL);
-    } else if((fd != save_fd) && dup2(fd, save_fd) == -1) {
+       *strclosing = newvstralloc(*strclosing, "can't open: ",
+                                  file.cont_filename, NULL);
+    } else if ((fd != save_fd) && dup2(fd, save_fd) == -1) {
        err = errno;
        ret = -1;
-       strclosing = newvstralloc(strclosing,"can't dup2: ",file.cont_filename,NULL);
+       *strclosing = newvstralloc(*strclosing, "can't dup2: ",
+                                  file.cont_filename, NULL);
     } else {
        buffer_t bp1;
+       char *quoted;
+
        holdfile_path = stralloc(file.cont_filename);
-       
-       fprintf(stderr, "taper: r: switching to next holding chunk '%s'\n", file.cont_filename); 
+       quoted = quote_string(holdfile_path);
+       fprintf(stderr, "taper: r: switching to next holding chunk '%s'\n",
+               quoted); 
+       amfree(quoted);
        num_holdfile_chunks++;
        
        bp1.status = EMPTY;
        bp1.size = DISK_BLOCK_BYTES;
-       bp1.buffer = malloc(DISK_BLOCK_BYTES);
+       bp1.buffer = alloc(DISK_BLOCK_BYTES);
        
-       if(fd != save_fd) {
+       if (fd != save_fd) {
            close(fd);
            fd = save_fd;
        }
        
        rc1 = taper_fill_buffer(fd, &bp1, DISK_BLOCK_BYTES);
-       if(rc1 <= 0) {
+       if (rc1 <= 0) {
            amfree(bp1.buffer);
            err = (rc1 < 0) ? errno : 0;
            ret = -1;
-           strclosing = newvstralloc(strclosing,
-                                     "Can't read header: ",
-                                     file.cont_filename,
-                                     NULL);
+           *strclosing = newvstralloc(*strclosing,
+                                      "Can't read header: ",
+                                      file.cont_filename,
+                                      NULL);
        } else {
-           parse_file_header(bp1.buffer, &file, rc1);
+           parse_file_header(bp1.buffer, &file, (size_t)rc1);
            
            amfree(bp1.buffer);
            bp1.buffer = bp->buffer + rc;
            
-           rc1 = taper_fill_buffer(fd, &bp1, tt_blocksize - rc);
-           if(rc1 <= 0) {
+           rc1 = taper_fill_buffer(fd, &bp1, (size_t)tt_blocksize - rc);
+           if (rc1 <= 0) {
                err = (rc1 < 0) ? errno : 0;
                ret = -1;
-               if(rc1 < 0) {
-                   strclosing = newvstralloc(strclosing,
-                                             "Can't read data: ",
-                                             file.cont_filename,
-                                             NULL);
+               if (rc1 < 0) {
+                   *strclosing = newvstralloc(*strclosing,
+                                              "Can't read data: ",
+                                              file.cont_filename,
+                                              NULL);
                }
-           }
-           else {
+           } else {
                ret = rc1;
                num_holdfiles++;
            }
        }
     }
-    
+
     return(ret);
 }
 
 
-int read_file(fd, handle, hostname, diskname, datestamp, level)
-    int fd, level;
-    char *handle, *hostname, *diskname, *datestamp;
+int
+read_file(
+    int                fd,
+    char *     handle,
+    char *     hostname,
+    char *     qdiskname,
+    char *     datestamp,
+    int                level)
 {
     buffer_t *bp;
-    char tok;
-    int rc, opening, closing, bufnum, need_closing, nexting;
-    long filesize;
+    int tok;
+    ssize_t rc;
+#ifdef ASSERTIONS
+    int opening;
+#endif
+    int closing, bufnum, need_closing, nexting;
+    off_t filesize;
     times_t runtime;
     char *strclosing = NULL;
     char seekerrstr[STR_SIZE];
     char *str;
     int header_written = 0;
-    int buflen;
+    size_t buflen;
     dumpfile_t first_file;
     dumpfile_t cur_holdfile;
-    long kbytesread = 0;
+    off_t kbytesread = (off_t)0;
     int header_read = 0;
     char *cur_filename = NULL;
     int retry_from_splitbuf = 0;
     char *splitbuf_rd_ptr = NULL;
-
     char *q = NULL;
 
 #ifdef HAVE_LIBVTBLC
@@ -1051,117 +1294,168 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
 
 
     /* initialize */
+    memset(&first_file, 0, SIZEOF(first_file));
+    memset(&cur_holdfile, 0, SIZEOF(cur_holdfile));
 
-    filesize = 0;
+    filesize = (off_t)0;
     closing = 0;
     need_closing = 0;
     nexting = 0;
     err = 0;
 
     /* don't break this if we're still on the same file as a previous init */
-    if(cur_span_chunkstart <= 0){
-    fh_init(&file);
-      header_read = 0;
-    }
-    else if(mode == MODE_FILE_WRITE){
-      memcpy(&file, save_holdfile, sizeof(dumpfile_t));
-      memcpy(&cur_holdfile, save_holdfile, sizeof(dumpfile_t));
+    if (cur_span_chunkstart <= (off_t)0) {
+       fh_init(&file);
+       header_read = 0;
+    } else if(mode == MODE_FILE_WRITE){
+       memcpy(&file, save_holdfile, SIZEOF(dumpfile_t));
+       memcpy(&cur_holdfile, save_holdfile, SIZEOF(dumpfile_t));
     }
 
-    if(bufdebug) {
+    if (bufdebug) {
        fprintf(stderr, "taper: r: start file\n");
        fflush(stderr);
     }
 
-    for(bp = buftable; bp < buftable + conf_tapebufs; bp++) {
+    for (bp = buftable; bp < buftable + conf_tapebufs; bp++) {
        bp->status = EMPTY;
     }
 
     bp = buftable;
-    if(interactive || bufdebug) dumpstatus(bp);
+    if (interactive || bufdebug)
+       dumpstatus(bp);
 
-    if(cur_span_chunkstart >= 0 && splitsize > 0){
+    if ((cur_span_chunkstart >= (off_t)0) && (splitsize > (off_t)0)) {
         /* We're supposed to start at some later part of the file, not read the
           whole thing. "Seek" forward to where we want to be. */
-       if(label) putresult(SPLIT_CONTINUE, "%s %s\n", handle, label);
-        if(mode == MODE_FILE_WRITE && cur_span_chunkstart > 0){
+       if (label)
+           putresult(SPLIT_CONTINUE, "%s %s\n", handle, label);
+        if ((mode == MODE_FILE_WRITE) && (cur_span_chunkstart > (off_t)0)) {
+           char *quoted = quote_string(holdfile_path_thischunk);
            fprintf(stderr, "taper: r: seeking %s to " OFF_T_FMT " kb\n",
-                           holdfile_path_thischunk, holdfile_offset_thischunk);
+                           quoted,
+                           (OFF_T_FMT_TYPE)holdfile_offset_thischunk);
            fflush(stderr);
 
-           if(holdfile_offset_thischunk > maxseek){
-             snprintf(seekerrstr, sizeof(seekerrstr), "Can't seek by " OFF_T_FMT " kb (compiled for %d-bit file offsets), recompile with large file support or set holdingdisk chunksize to <%ld Mb", holdfile_offset_thischunk, (int)(sizeof(off_t) * 8), (long)(maxseek/1024));
-             log_add(L_ERROR, "%s", seekerrstr);
-             fprintf(stderr, "taper: r: FATAL: %s\n", seekerrstr);
-             fflush(stderr);
-             syncpipe_put('X', 0);
-             return -1;
+           if (holdfile_offset_thischunk > maxseek) {
+               snprintf(seekerrstr, SIZEOF(seekerrstr), "Can't seek by "
+                       OFF_T_FMT " kb (compiled for %d-bit file offsets), "
+                       "recompile with large file support or "
+                       "set holdingdisk chunksize to <" OFF_T_FMT " Mb",
+                       (OFF_T_FMT_TYPE)holdfile_offset_thischunk,
+                       (int)(sizeof(off_t) * 8),
+                       (OFF_T_FMT_TYPE)(maxseek/(off_t)1024));
+               log_add(L_ERROR, "%s", seekerrstr);
+               fprintf(stderr, "taper: r: FATAL: %s\n", seekerrstr);
+               fflush(stderr);
+               if (syncpipe_put('X', 0) == -1) {
+                       put_syncpipe_fault_result(handle);
+               }
+               amfree(quoted);
+               return -1;
            }
-           if(lseek(fd, holdfile_offset_thischunk*1024, SEEK_SET) == (off_t)-1){
-             fprintf(stderr, "taper: r: FATAL: seek_holdfile lseek error while seeking into %s by " OFF_T_FMT "kb: %s\n", holdfile_path_thischunk, holdfile_offset_thischunk, strerror(errno));
-             fflush(stderr);
-             syncpipe_put('X', 0);
-             return -1;
+           if (lseek(fd, holdfile_offset_thischunk*(off_t)1024, SEEK_SET) == (off_t)-1) {
+               fprintf(stderr, "taper: r: FATAL: seek_holdfile lseek error "
+                       "while seeking into %s by "
+                       OFF_T_FMT "kb: %s\n", quoted,
+                       (OFF_T_FMT_TYPE)holdfile_offset_thischunk,
+                       strerror(errno));
+               fflush(stderr);
+               if (syncpipe_put('X', 0) == -1) {
+                       put_syncpipe_fault_result(handle);
+               }
+               amfree(quoted);
+               return -1;
            }
-        }
-        else if(mode == MODE_PORT_WRITE){
+           amfree(quoted);
+        } else if (mode == MODE_PORT_WRITE) {
            fprintf(stderr, "taper: r: re-reading split dump piece from buffer\n");
            fflush(stderr);
            retry_from_splitbuf = 1;
            splitbuf_rd_ptr = splitbuf;
-           if(splitbuf_rd_ptr >= splitbuf_wr_ptr) retry_from_splitbuf = 0;
+           if (splitbuf_rd_ptr >= splitbuf_wr_ptr)
+               retry_from_splitbuf = 0;
         }
-        if(cur_span_chunkstart > 0) header_read = 1; /* really initialized in prior run */
+        if (cur_span_chunkstart > (off_t)0)
+           header_read = 1; /* really initialized in prior run */
     }
 
     /* tell writer to open tape */
 
+#ifdef ASSERTIONS
     opening = 1;
-    syncpipe_put('O', 0);
-    syncpipe_putstr(datestamp);
-    syncpipe_putstr(hostname);
-    syncpipe_putstr(diskname);
-    syncpipe_putint(level);
+#endif
+
+    if (syncpipe_put('O', 0) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
+    if (syncpipe_putstr(datestamp) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
+    if (syncpipe_putstr(hostname) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
+    if (syncpipe_putstr(qdiskname) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
+    if (syncpipe_putint(level) == -1) {
+       put_syncpipe_fault_result(handle);
+       return -1;
+    }
 
     startclock();
     
     /* read file in loop */
     
-    while(1) {
-       tok = syncpipe_get(&bufnum);
+    while (1) {
+       if ((tok = syncpipe_get(&bufnum)) == -1) {
+           put_syncpipe_fault_result(handle);
+           return -1;
+       }
+
        switch(tok) {
-           
        case 'O':
+#ifdef ASSERTIONS
            assert(opening);
            opening = 0;
+#endif
            err = 0;
            break;
            
        case 'R':
-           if(bufdebug) {
+           if (bufdebug) {
                fprintf(stderr, "taper: r: got R%d\n", bufnum);
                fflush(stderr);
            }
            
-           if(need_closing) {
-               syncpipe_put('C', 0);
+           if (need_closing) {
+               if (syncpipe_put('C', 0) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
                closing = 1;
                need_closing = 0;
                break;
            }
            
-           if(closing) break;  /* ignore extra read tokens */
+           if (closing)
+               break;  /* ignore extra read tokens */
            
+#ifdef ASSERTIONS
            assert(!opening);
-           if(bp->status != EMPTY || bufnum != bp-buftable) {
+#endif
+           if(bp->status != EMPTY || bufnum != (int)(bp - buftable)) {
                /* XXX this SHOULD NOT HAPPEN.  Famous last words. */
-               fprintf(stderr,"taper: panic: buffer mismatch at ofs %ld:\n",
-                       filesize);
-               if(bufnum != bp-buftable) {
+               fprintf(stderr,"taper: panic: buffer mismatch at ofs "
+                       OFF_T_FMT ":\n", (OFF_T_FMT_TYPE)filesize);
+               if(bufnum != (int)(bp - buftable)) {
                    fprintf(stderr, "    my buf %d but writer buf %d\n",
                            (int)(bp-buftable), bufnum);
-               }
-               else {
+               } else {
                    fprintf(stderr,"buf %d state %s (%ld) instead of EMPTY\n",
                            (int)(bp-buftable),
                            bp->status == FILLING? "FILLING" :
@@ -1171,7 +1465,7 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                dumpbufs("taper");
                sleep(1);
                dumpbufs("taper: after 1 sec");
-               if(bp->status == EMPTY)
+               if (bp->status == EMPTY)
                    fprintf(stderr, "taper: result now correct!\n");
                fflush(stderr);
                
@@ -1179,23 +1473,31 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                                     "[fatal buffer mismanagement bug]");
                q = squote(errstr);
                putresult(TRYAGAIN, "%s %s\n", handle, q);
-               cur_span_chunkstart = 0;
+               cur_span_chunkstart = (off_t)0;
                amfree(q);
                log_add(L_INFO, "retrying %s:%s.%d on new tape due to: %s",
-                       hostname, diskname, level, errstr);
+                       hostname, qdiskname, level, errstr);
                closing = 1;
-               syncpipe_put('X', 0);   /* X == buffer snafu, bail */
+               if (syncpipe_put('X', 0) == -1) {/* X == buffer snafu, bail */
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
                do {
-                   tok = syncpipe_get(&bufnum);
-               } while(tok != 'x');
+                   if ((tok = syncpipe_get(&bufnum)) == -1) {
+                       put_syncpipe_fault_result(handle);
+                       return (-1);
+                   }
+               } while (tok != 'x');
                aclose(fd);
                return -1;
-           } /* end 'if (bf->status != EMPTY || bufnum != bp-buftable)' */
+           } /* end 'if (bf->status != EMPTY || bufnum != (int)(bp-buftable))' */
 
            bp->status = FILLING;
-           buflen = header_read ? tt_blocksize : DISK_BLOCK_BYTES;
-           if(interactive || bufdebug) dumpstatus(bp);
-           if(header_written == 0 && (header_read == 1 || cur_span_chunkstart > 0)){
+           buflen = header_read ? (size_t)tt_blocksize : DISK_BLOCK_BYTES;
+           if (interactive || bufdebug)
+               dumpstatus(bp);
+           if (header_written == 0 &&
+                       (header_read == 1 || cur_span_chunkstart > (off_t)0)) {
                /* for split dumpfiles, modify headers for the second - nth
                   pieces that signify that they're continuations of the last
                   normal one */
@@ -1203,182 +1505,224 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                file.type = F_SPLIT_DUMPFILE;
                file.partnum = num_splits + 1;
                file.totalparts = expected_splits;
-                 cont_filename = stralloc(file.cont_filename);
+                cont_filename = stralloc(file.cont_filename);
                file.cont_filename[0] = '\0';
                build_header(bp->buffer, &file, tt_blocksize);
   
-               if(cont_filename[0] != '\0') {
+               if (cont_filename[0] != '\0') {
                  file.type = F_CONT_DUMPFILE;
                    strncpy(file.cont_filename, cont_filename,
-                           sizeof(file.cont_filename));
+                           SIZEOF(file.cont_filename));
                        }
-               memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+               memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
   
-               if(interactive || bufdebug) dumpstatus(bp);
-               bp->size = tt_blocksize;
-               rc = tt_blocksize;
+               if (interactive || bufdebug)
+                   dumpstatus(bp);
+               bp->size = (ssize_t)tt_blocksize;
+               rc = (ssize_t)tt_blocksize;
                header_written = 1;
                amfree(cont_filename);
-                       }
-           else if(retry_from_splitbuf){
+           } else if (retry_from_splitbuf) {
                /* quietly pull dump data from our in-memory cache, and the
                   writer side need never know the wiser */
                memcpy(bp->buffer, splitbuf_rd_ptr, tt_blocksize);
-               bp->size = tt_blocksize;
-               rc = tt_blocksize;
+               bp->size = (ssize_t)tt_blocksize;
+               rc = (ssize_t)tt_blocksize;
  
                splitbuf_rd_ptr += tt_blocksize;
-               if(splitbuf_rd_ptr >= splitbuf_wr_ptr) retry_from_splitbuf = 0;
-           }
-           else if((rc = taper_fill_buffer(fd, bp, buflen)) < 0) {
+               if (splitbuf_rd_ptr >= splitbuf_wr_ptr)
+                   retry_from_splitbuf = 0;
+           } else if ((rc = taper_fill_buffer(fd, bp, buflen)) < 0) {
                err = errno;
                closing = 1;
-               strclosing = newvstralloc(strclosing,"Can't read data: ",NULL);
-               syncpipe_put('C', 0);
+               strclosing = newvstralloc(strclosing,"Can't read data: ",
+                                         NULL);
+               if (syncpipe_put('C', 0) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
            }
   
-           if(!closing) {
-               if(rc < buflen) { /* switch to next holding file */
-                   int ret;
-                   if(file.cont_filename[0] != '\0'){
-                      cur_filename = newvstralloc(cur_filename, file.cont_filename, NULL);
-                               }
-                   ret = get_next_holding_file(fd, bp, strclosing, rc);
-                   if(ret <= 0){
+           if (!closing) {
+               if (rc < (ssize_t)buflen) { /* switch to next holding file */
+                   ssize_t ret;
+
+                   if (file.cont_filename[0] != '\0') {
+                       cur_filename = newvstralloc(cur_filename, file.cont_filename, NULL);
+                   }
+                   ret = get_next_holding_file(fd, bp, &strclosing, (size_t)rc);
+                   if (ret <= 0) {
                        need_closing = 1;
-                           }
-                           else {
-                       memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+                   } else {
+                       memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
                        rc += ret;
-                               bp->size = rc;
-                           }
-                       }
-               if(rc > 0) {
+                       bp->size = rc;
+                   }
+               }
+               if (rc > 0) {
                    bp->status = FULL;
                    /* rebuild the header block, which might have CONT junk */
-                   if(header_read == 0) {
+                   if (header_read == 0) {
                        char *cont_filename;
                        /* write the "real" filename if the holding-file
                           is a partial one */
-                       parse_file_header(bp->buffer, &file, rc);
-                       parse_file_header(bp->buffer, &first_file, rc);
+                       parse_file_header(bp->buffer, &file, (size_t)rc);
+                       parse_file_header(bp->buffer, &first_file, (size_t)rc);
                        cont_filename = stralloc(file.cont_filename);
                        file.cont_filename[0] = '\0';
-                       if(splitsize > 0){
+                       if (splitsize > (off_t)0) {
                            file.type = F_SPLIT_DUMPFILE;
                            file.partnum = 1;
                            file.totalparts = expected_splits;
                        }
                        file.blocksize = tt_blocksize;
                        build_header(bp->buffer, &file, tt_blocksize);
-                       kbytesread += tt_blocksize/1024; /* XXX shady */
+                       kbytesread += (off_t)(tt_blocksize/1024); /* XXX shady */
  
                        file.type = F_CONT_DUMPFILE;
  
                        /* add CONT_FILENAME back to in-memory header */
                        strncpy(file.cont_filename, cont_filename, 
-                               sizeof(file.cont_filename));
-                       if(interactive || bufdebug) dumpstatus(bp);
-                       bp->size = tt_blocksize; /* output a full tape block */
+                               SIZEOF(file.cont_filename));
+                       if (interactive || bufdebug)
+                           dumpstatus(bp);
+                       bp->size = (ssize_t)tt_blocksize; /* output a full tape block */
                        /* save the header, we'll need it if we jump tapes */
-                       memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+                       memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
                        header_read = 1;
                        header_written = 1;
                        amfree(cont_filename);
-                   }
-                   else {
+                   } else {
                        filesize = kbytesread;
                    }
 
-                   if(bufdebug) {
+                   if (bufdebug) {
                        fprintf(stderr,"taper: r: put W%d\n",(int)(bp-buftable));
                        fflush(stderr);
                    }
-                   syncpipe_put('W', bp-buftable);
+                   if (syncpipe_put('W', (int)(bp-buftable)) == -1) {
+                       put_syncpipe_fault_result(handle);
+                       return (-1);
+                   }
                    bp = nextbuf(bp);
                }
 
-               if(kbytesread + DISK_BLOCK_BYTES/1024 >= splitsize && splitsize > 0 && !need_closing){
+               if (((kbytesread + (off_t)(DISK_BLOCK_BYTES/1024)) >= splitsize)
+                       && (splitsize > (off_t)0) && !need_closing) {
 
-                   if(mode == MODE_PORT_WRITE){
+                   if (mode == MODE_PORT_WRITE) {
                        splitbuf_wr_ptr = splitbuf;
                        splitbuf_rd_ptr = splitbuf;
-                       memset(splitbuf, 0, sizeof(splitbuf));
+                       memset(splitbuf, 0, SIZEOF(splitbuf));
                        retry_from_splitbuf = 0;
                    }
 
-                   fprintf(stderr,"taper: r: end %s.%s.%s.%d part %d, splitting chunk that started at %ldkb after %ldkb (next chunk will start at %ldkb)\n", hostname, diskname, datestamp, level, num_splits+1, cur_span_chunkstart, kbytesread, cur_span_chunkstart+kbytesread);
+                   fprintf(stderr,"taper: r: end %s.%s.%s.%d part %d, "
+                               "splitting chunk that started at "
+                               OFF_T_FMT "kb after " OFF_T_FMT
+                               "kb (next chunk will start at "
+                               OFF_T_FMT "kb)\n",
+                               hostname, qdiskname, datestamp, level,
+                               num_splits+1,
+                               (OFF_T_FMT_TYPE)cur_span_chunkstart,
+                               (OFF_T_FMT_TYPE)kbytesread,
+                               (OFF_T_FMT_TYPE)(cur_span_chunkstart+kbytesread));
                    fflush(stderr);
 
                    nexting = 1;
                    need_closing = 1;
                } /* end '(kbytesread >= splitsize && splitsize > 0)' */
-               if(need_closing && rc <= 0) {
-                   syncpipe_put('C', 0);
+               if (need_closing && rc <= 0) {
+                   if (syncpipe_put('C', 0) == -1) {
+                       put_syncpipe_fault_result(handle);
+                       return (-1);
+                   }
                    need_closing = 0;
                    closing = 1;
                }
-                kbytesread += rc/1024;
-           } /* end the 'if(!closing)' (successful buffer fill) */
+                kbytesread += (off_t)(rc / 1024);
+           } /* end the 'if (!closing)' (successful buffer fill) */
            break;
 
        case 'T':
        case 'E':
-           syncpipe_put('e', 0);       /* ACK error */
+       case 'H':
+           if (syncpipe_put('e', 0) == -1) {   /* ACK error */
+               put_syncpipe_fault_result(handle);
+               return (-1);
+           }
 
-           str = syncpipe_getstr();
-           errstr = newvstralloc(errstr, "[", str ? str : "(null)", "]", NULL);
+           if ((str = syncpipe_getstr()) == NULL) {
+               put_syncpipe_fault_result(handle);
+               return (-1);
+           }
+           
+           errstr = newvstralloc(errstr, "[", str, "]", NULL);
            amfree(str);
 
            q = squote(errstr);
-           if(tok == 'T') {
-               if(splitsize > 0){
+           if (tok == 'T') {
+               if (splitsize > (off_t)0) {
                    /* we'll be restarting this chunk on the next tape */
-                   if(mode == MODE_FILE_WRITE){
+                   if (mode == MODE_FILE_WRITE) {
                      aclose(fd);
                    }
 
-                   putresult(SPLIT_NEEDNEXT, "%s %ld\n", handle, cur_span_chunkstart);
-                   log_add(L_INFO, "continuing %s:%s.%d on new tape from %ldkb mark: %s",
-                           hostname, diskname, level, cur_span_chunkstart, errstr);
+                   putresult(SPLIT_NEEDNEXT, "%s " OFF_T_FMT "\n", handle,
+                               (OFF_T_FMT_TYPE)cur_span_chunkstart);
+                   log_add(L_INFO, "continuing %s:%s.%d on new tape from "
+                               OFF_T_FMT "kb mark: %s",
+                               hostname, qdiskname, level,
+                               (OFF_T_FMT_TYPE)cur_span_chunkstart, errstr);
                    return 1;
-               }
-               else{
+               } else {
                    /* restart the entire dump (failure propagates to driver) */
                    aclose(fd);
                    putresult(TRYAGAIN, "%s %s\n", handle, q);
-                   cur_span_chunkstart = 0;
+                   cur_span_chunkstart = (off_t)0;
                    log_add(L_INFO, "retrying %s:%s.%d on new tape due to: %s",
-                           hostname, diskname, level, errstr);
+                           hostname, qdiskname, level, errstr);
                }
            } else {
                aclose(fd);
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
                log_add(L_FAIL, "%s %s %s %d [out of tape]",
-                       hostname, diskname, datestamp, level);
+                       hostname, qdiskname, datestamp, level);
                log_add(L_ERROR,"no-tape [%s]", "No more writable valid tape found");
            }
            amfree(q);
-
            return 0;
 
        case 'C':
+#ifdef ASSERTIONS
            assert(!opening);
+#endif
            assert(closing);
 
-           if(nexting){
+           if (nexting) {
              cur_span_chunkstart += kbytesread; /* XXX possibly wrong */
-             holdfile_name = newvstralloc(holdfile_name, cur_filename, NULL);
-
-             kbytesread = 0;
-             if(cur_filename != NULL) amfree(cur_filename);
+             if (cur_filename)
+               holdfile_name = newvstralloc(holdfile_name, cur_filename,
+                                            NULL);
+             else
+               amfree(holdfile_name);
+
+             kbytesread = (off_t)0;
+             amfree(cur_filename);
            }
 
+           if ((str = syncpipe_getstr()) == NULL) {
+               put_syncpipe_fault_result(handle);
+               return (-1);
+           }
 
-           str = syncpipe_getstr();
            label = newstralloc(label, str ? str : "(null)");
            amfree(str);
-           str = syncpipe_getstr();
+           if ((str = syncpipe_getstr()) == NULL) {
+               put_syncpipe_fault_result(handle);
+               return (-1);
+           }
+
            filenum = atoi(str ? str : "-9876");        /* ??? */
            amfree(str);
            fprintf(stderr, "taper: reader-side: got label %s filenum %d\n",
@@ -1386,20 +1730,20 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
            fflush(stderr);
 
            /* we'll need that file descriptor if we're gonna write more */
-           if(!nexting){
-           aclose(fd);
+           if (!nexting) {
+               aclose(fd);
            }
 
            runtime = stopclock();
-           if(nexting) startclock();
-           if(err) {
-               if(strclosing) {
+           if (nexting)
+               startclock();
+           if (err) {
+               if (strclosing) {
                    errstr = newvstralloc(errstr,
                                          "[input: ", strclosing, ": ",
                                          strerror(err), "]", NULL);
                    amfree(strclosing);
-               }
-               else
+               } else
                    errstr = newvstralloc(errstr,
                                          "[input: ", strerror(err), "]",
                                          NULL);
@@ -1407,15 +1751,17 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                putresult(TAPE_ERROR, "%s %s\n", handle, q);
 
                amfree(q);
-               if(splitsize){
-                 log_add(L_FAIL, "%s %s %s.%d %d %s", hostname, diskname,
-                         datestamp, num_splits, level, errstr);
+               if (splitsize != (off_t)0) {
+                   log_add(L_FAIL, "%s %s %s.%d %d %s", hostname, qdiskname,
+                               datestamp, num_splits, level, errstr);
+               } else {
+                   log_add(L_FAIL, "%s %s %s %d %s",
+                               hostname, qdiskname, datestamp, level, errstr);
                }
-               else{
-               log_add(L_FAIL, "%s %s %s %d %s",
-                       hostname, diskname, datestamp, level, errstr);
+               if ((str = syncpipe_getstr()) == NULL) {        /* reap stats */
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
                }
-               str = syncpipe_getstr();        /* reap stats */
                amfree(str);
                 amfree(errstr);
            } else {
@@ -1423,12 +1769,17 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                char kps_str[NUM_STR_SIZE];
                double rt;
 
-               rt = runtime.r.tv_sec+runtime.r.tv_usec/1000000.0;
+               rt = (double)(runtime.r.tv_sec) +
+                    ((double)(runtime.r.tv_usec) / 1000000.0);
                curdump_rt = timesadd(runtime, curdump_rt);
-               snprintf(kb_str, sizeof(kb_str), "%ld", filesize);
-               snprintf(kps_str, sizeof(kps_str), "%3.1f",
-                                    rt ? filesize / rt : 0.0);
-               str = syncpipe_getstr();
+               snprintf(kb_str, SIZEOF(kb_str), OFF_T_FMT,
+                       (OFF_T_FMT_TYPE)filesize);
+               snprintf(kps_str, SIZEOF(kps_str), "%3.1lf",
+                                 (isnormal(rt) ? (double)filesize / rt : 0.0));
+               if ((str = syncpipe_getstr()) == NULL) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
                errstr = newvstralloc(errstr,
                                      "[sec ", walltime_str(runtime),
                                      " kb ", kb_str,
@@ -1436,38 +1787,41 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                                      " ", str,
                                      "]",
                                      NULL);
-               q = squote(errstr);
-               if (splitsize == 0) { /* Ordinary dump */
-                   if(first_file.is_partial) {
+               if (splitsize == (off_t)0) { /* Ordinary dump */
+                   q = squote(errstr);
+/*@i@*/                    if (first_file.is_partial) {
                        putresult(PARTIAL, "%s %s %d %s\n",
                                  handle, label, filenum, q);
                        log_add(L_PARTIAL, "%s %s %s %d %s",
-                               hostname, diskname, datestamp, level, errstr);
-                   }
-                   else {
+                               hostname, qdiskname, datestamp, level, errstr);
+                   } else {
                        putresult(DONE, "%s %s %d %s\n",
                                  handle, label, filenum, q);
                        log_add(L_SUCCESS, "%s %s %s %d %s",
-                               hostname, diskname, datestamp, level, errstr);
+                               hostname, qdiskname, datestamp, level, errstr);
                    }
+                   amfree(q);
                } else { /* Chunked dump */
                    num_splits++;
-                   if(mode == MODE_FILE_WRITE){
+                   if (mode == MODE_FILE_WRITE) {
                        holdfile_path_thischunk = stralloc(holdfile_path);
-                       holdfile_offset_thischunk = (lseek(fd, (off_t)0, SEEK_CUR))/1024;
+                       holdfile_offset_thischunk = (lseek(fd, (off_t)0, SEEK_CUR))/(off_t)1024;
                        if(!save_holdfile){
-                           save_holdfile = alloc(sizeof(dumpfile_t));
+                           save_holdfile = alloc(SIZEOF(dumpfile_t));
                        }
-                       memcpy(save_holdfile, &cur_holdfile,sizeof(dumpfile_t));
+                       memcpy(save_holdfile, &cur_holdfile,SIZEOF(dumpfile_t));
                    }
-                   log_add(L_CHUNK, "%s %s %s %d %d %s", hostname, diskname,
+                   log_add(L_CHUNK, "%s %s %s %d %d %s", hostname, qdiskname,
                            datestamp, num_splits, level, errstr);
-                   if(!nexting){ /* split dump complete */
-                       rt =curdump_rt.r.tv_sec+curdump_rt.r.tv_usec/1000000.0;
-                       snprintf(kb_str, sizeof(kb_str), "%ld",
-                                   filesize+cur_span_chunkstart);
-                       snprintf(kps_str, sizeof(kps_str), "%3.1f",
-                                   rt ? (filesize+cur_span_chunkstart) / rt : 0.0);
+                   if (!nexting) { /* split dump complete */
+                       rt = (double)(curdump_rt.r.tv_sec) +
+                            ((double)(curdump_rt.r.tv_usec) / 1000000.0);
+                       snprintf(kb_str, SIZEOF(kb_str), OFF_T_FMT,
+                               (OFF_T_FMT_TYPE)(filesize + cur_span_chunkstart));
+                       snprintf(kps_str, SIZEOF(kps_str), "%3.1lf",
+                           isnormal(rt) ?
+                           ((double)(filesize+cur_span_chunkstart)) / rt :
+                           0.0);
                         amfree(errstr);
                        errstr = newvstralloc(errstr,
                                              "[sec ", walltime_str(curdump_rt),
@@ -1480,23 +1834,22 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                        putresult(DONE, "%s %s %d %s\n", handle, label,
                                  filenum, q);
                        log_add(L_CHUNKSUCCESS, "%s %s %s %d %s",
-                               hostname, diskname, datestamp, level, errstr);
+                               hostname, qdiskname, datestamp, level, errstr);
                        amfree(save_holdfile);
                        amfree(holdfile_path_thischunk);
                         amfree(q);
-                    }
+                   }
                }
                amfree(str);
 
-               if(!nexting){
+               if (!nexting) {
                    num_splits = 0;
                    expected_splits = 0;
                    amfree(holdfile_name);
                    num_holdfiles = 0;
-                   cur_span_chunkstart = 0;
+                   cur_span_chunkstart = (off_t)0;
                    curdump_rt = times_zero;
                }
-               
                amfree(errstr);
                
 #ifdef HAVE_LIBVTBLC
@@ -1514,19 +1867,17 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                if ((len = strlen(hostname)) <= 20) {
                    memset(desc + len, ' ', 1);
                    offset = len + 1;
-               }
-               else{
+               } else {
                    memset(desc + 20, ' ', 1);
                    offset = 21;
                }
 
-               strncpy(desc + offset, diskname, 20);
+               strncpy(desc + offset, qdiskname, 20);
 
-               if ((len = strlen(diskname)) <= 20) {
+               if ((len = strlen(qdiskname)) <= 20) {
                    memset(desc + offset + len, ' ', 1);
                    offset = offset + len + 1;
-               }
-               else{
+               } else {
                    memset(desc + offset + 20, ' ', 1);
                    offset = offset + 21;
                }
@@ -1539,8 +1890,14 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                fflush(stderr);
 
                /* pass label string on to tape writer */
-               syncpipe_put('L', filenum);
-               syncpipe_putstr(vol_label);             
+               if (syncpipe_put('L', filenum) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
+               if (syncpipe_putstr(vol_label) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
 
                /* 
                 * reformat datestamp for later use with set_date from vtblc 
@@ -1553,106 +1910,160 @@ int read_file(fd, handle, hostname, diskname, datestamp, level)
                        vol_date);
 
                /* pass date string on to tape writer */                
-               syncpipe_put('D', filenum);
-               syncpipe_putstr(vol_date);
+               if (syncpipe_put('D', filenum) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
+               if (syncpipe_putstr(vol_date) == -1) {
+                   put_syncpipe_fault_result(handle);
+                   return (-1);
+               }
 
 #endif /* HAVE_LIBVTBLC */
            }
            /* reset stuff that assumes we're on a new file */
 
-           if(nexting){
-               opening = 1;
-               nexting = 0;
-               closing = 0;
-               filesize = 0;
-               syncpipe_put('O', 0);
-               syncpipe_putstr(datestamp);
-               syncpipe_putstr(hostname);
-               syncpipe_putstr(diskname);
-               syncpipe_putint(level);
-               for(bp = buftable; bp < buftable + conf_tapebufs; bp++) {
-                   bp->status = EMPTY;
-               }
-               bp = buftable;
-               header_written = 0;
-               break;
+           if (!nexting)
+               return 0;
+
+#ifdef ASSERTIONS
+           opening = 1;
+#endif
+           nexting = 0;
+           closing = 0;
+           filesize = (off_t)0;
+           if (syncpipe_put('O', 0) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
+           }
+           if (syncpipe_putstr(datestamp) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
+           }
+           if (syncpipe_putstr(hostname) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
+           }
+           if (syncpipe_putstr(qdiskname) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
            }
-           else return 0;
+           if (syncpipe_putint(level) == -1) {
+               put_syncpipe_fault_result(handle);
+               return -1;
+           }
+           for (bp = buftable; bp < buftable + conf_tapebufs; bp++) {
+               bp->status = EMPTY;
+           }
+           bp = buftable;
+           header_written = 0;
+           break;
+
+       case 'X':
+           /*
+            * Pipe read error: Communications is severed at least
+            * back to us.  We send a blind 'Q' (quit) and we don't
+            * wait for a response...
+            */
+           syncpipe_put('Q', 0);                       /* ACK error */
+           fprintf(stderr, "taper: communications pipe from reader severed\n");
+           return -1;
 
        default:
-           assert(0);
+           q = squotef("[Taper syncpipe protocol error]");
+           putresult(TAPE_ERROR, "%s %s\n", handle, q);
+           log_add(L_ERROR, "tape-error %s %s", handle, q);
+           amfree(q);
+           return -1;
        }
     }
-
     return 0;
 }
 
-int taper_fill_buffer(fd, bp, buflen)
-int fd;
-buffer_t *bp;
-int buflen;
+ssize_t
+taper_fill_buffer(
+    int fd,
+    buffer_t *bp,
+    size_t buflen)
 {
     char *curptr;
-    int spaceleft, cnt;
+    ssize_t cnt;
 
     curptr = bp->buffer;
-    bp->size = 0;
-    spaceleft = buflen;
 
-    cnt = fullread(fd, curptr, spaceleft);
+    cnt = fullread(fd, curptr, buflen);
     switch(cnt) {
     case 0:    /* eof */
-       if(interactive) fputs("r0", stderr);
-       return bp->size;
+       if (interactive)
+           fputs("r0", stderr);
+       bp->size = 0;
+       return (ssize_t)0;
+       /*NOTREACHED*/
+
     case -1:   /* error on read, punt */
-       if(interactive) fputs("rE", stderr);
+       if (interactive)
+           fputs("rE", stderr);
+       bp->size = 0;
        return -1;
+       /*NOTREACHED*/
+
     default:
-       if(mode == MODE_PORT_WRITE && splitsize > 0){
+       if ((mode == MODE_PORT_WRITE) && (splitsize > (off_t)0)) {
            memcpy(splitbuf_wr_ptr, curptr, (size_t)cnt);
            splitbuf_wr_ptr += cnt;
        }
-       spaceleft -= cnt;
-       curptr += cnt;
-       bp->size += cnt;
+       bp->size = cnt;
+       break;
     }
 
-    if(interactive) fputs("R", stderr);
-    return bp->size;
+    if (interactive)
+       fputs("R", stderr);
+    return ((ssize_t)bp->size);
 }
 
 /* Given a dumpfile in holding, determine its size and figure out how many
  * times we'd have to split it.
  */
-int predict_splits(filename)
-char *filename;
+int
+predict_splits(
+    char *filename)
 {
     int splits = 0;
-    long total_kb = 0;
-    long adj_splitsize = splitsize - DISK_BLOCK_BYTES/1024;
+    off_t total_kb = (off_t)0;
+    off_t adj_splitsize = splitsize - (off_t)(DISK_BLOCK_BYTES / 1024);
 
-    if(splitsize <= 0) return(0);
+    if (splitsize <= (off_t)0)
+       return(0);
 
-    if(adj_splitsize <= 0){
-      error("Split size must be > %ldk", DISK_BLOCK_BYTES/1024);
+    if (adj_splitsize <= (off_t)0) {
+      error("Split size must be > " OFF_T_FMT "k",
+       (OFF_T_FMT_TYPE)(DISK_BLOCK_BYTES/1024));
+      /*NOTREACHED*/
     }
 
     /* should only calculuate this once, not on retries etc */
-    if(expected_splits != 0) return(expected_splits);
+    if (expected_splits != 0)
+       return(expected_splits);
 
     total_kb = size_holding_files(filename, 1);
     
-    if(total_kb <= 0){
-      fprintf(stderr, "taper: r: %ld kb holding file makes no sense, not precalculating splits\n", total_kb);
+    if (total_kb <= (off_t)0) {
+      fprintf(stderr, "taper: r: " OFF_T_FMT
+               " kb holding file makes no sense, not precalculating splits\n",
+               (OFF_T_FMT_TYPE)total_kb);
       fflush(stderr);
       return(0);
     }
 
-    fprintf(stderr, "taper: r: Total dump size should be %ldkb, chunk size is %ldkb\n", total_kb, splitsize);
+    fprintf(stderr, "taper: r: Total dump size should be " OFF_T_FMT
+               "kb, chunk size is " OFF_T_FMT "kb\n",
+               (OFF_T_FMT_TYPE)total_kb,
+               (OFF_T_FMT_TYPE)splitsize);
     fflush(stderr);
 
-    splits = total_kb/adj_splitsize;
-    if(total_kb % adj_splitsize) splits++;
+    splits = (int)(total_kb / adj_splitsize);
+    if ((splits == 0) || (total_kb % adj_splitsize))
+       splits++;
 
 
     fprintf(stderr, "taper: r: Expecting to split into %d parts \n", splits);
@@ -1667,17 +2078,19 @@ char *filename;
  *
  */
 times_t idlewait, rdwait, wrwait, fmwait;
-long total_writes;
-double total_tape_used;
+unsigned long total_writes;
+off_t total_tape_used;
 int total_tape_fm;
 
-void write_file P((void));
-int write_buffer P((buffer_t *bp));
+void write_file(void);
+int write_buffer(buffer_t *bp);
 
-void tape_writer_side(getp, putp)
-int getp, putp;
+void
+tape_writer_side(
+    int getp,
+    int putp)
 {
-    char tok;
+    int tok;
     int tape_started;
     char *str;
     char *hostname;
@@ -1693,57 +2106,96 @@ int getp, putp;
 
     procname = "writer";
     syncpipe_init(getp, putp);
-
     tape_started = 0;
     idlewait = times_zero;
 
-    while(1) {
+    while (1) {
        startclock();
-       tok = syncpipe_get(&tmpint);
+       if ((tok = syncpipe_get(&tmpint)) == -1) {
+           error("writer: Syncpipe failure before start");
+           /*NOTREACHED*/
+       }
+
        idlewait = timesadd(idlewait, stopclock());
-       if(tok != 'S' && tok != 'Q' && !tape_started) {
+       if (tok != 'S' && tok != 'Q' && !tape_started) {
            error("writer: token '%c' before start", tok);
+           /*NOTREACHED*/
        }
 
        switch(tok) {
+       case 'H':               /* Reader read pipe side is down */
+           dbprintf(("writer: Communications with reader is down"));
+           error("writer: Communications with reader is down");
+           /*NOTREACHED*/
+           
        case 'S':               /* start-tape */
-           if(tape_started) {
+           if (tape_started) {
                error("writer: multiple start requests");
+               /*NOTREACHED*/
+           }
+           if ((str = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure");
+               /*NOTREACHED*/
            }
-           str = syncpipe_getstr();
-           if(!first_tape(str ? str : "bad-datestamp")) {
-               if(tape_fd >= 0) {
+           if (!first_tape(str ? str : "bad-datestamp")) {
+               if (tape_fd >= 0) {
                    tapefd_close(tape_fd);
                    tape_fd = -1;
                }
-               syncpipe_put('E', 0);
-               syncpipe_putstr(errstr);
+               if (syncpipe_put('E', 0) == -1) {
+                   error("writer: Syncpipe failure passing exit code");
+                   /*NOTREACHED*/
+               }
+               if (syncpipe_putstr(errstr) == -1) {
+                   error("writer: Syncpipe failure passing exit string");
+                   /*NOTREACHED*/
+               }
                /* wait for reader to acknowledge error */
                do {
-                   tok = syncpipe_get(&tmpint);
-                   if(tok != 'e') {
+                   if ((tok = syncpipe_get(&tmpint)) == -1) {
+                       error("writer: Syncpipe failure waiting for error ack");
+                       /*NOTREACHED*/
+                   }
+                   if (tok != 'e') {
                        error("writer: got '%c' unexpectedly after error", tok);
+                       /*NOTREACHED*/
                    }
-               } while(tok != 'e');
+               } while (tok != 'e');
            } else {
-               syncpipe_put('S', 0);
+               if (syncpipe_put('S', 0) == -1) {
+                   error("writer: syncpipe failure while starting tape");
+                   /*NOTREACHED*/
+               }
                tape_started = 1;
            }
            amfree(str);
-
            break;
 
        case 'O':               /* open-output */
-           datestamp = syncpipe_getstr();
+           if ((datestamp = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure during open");
+               /*NOTREACHED*/
+           }
            tapefd_setinfo_datestamp(tape_fd, datestamp);
            amfree(datestamp);
-           hostname = syncpipe_getstr();
+
+           if ((hostname = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure fetching hostname");
+               /*NOTREACHED*/
+           }
            tapefd_setinfo_host(tape_fd, hostname);
            amfree(hostname);
-           diskname = syncpipe_getstr();
+
+           if ((diskname = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure fetching diskname");
+               /*NOTREACHED*/
+           }
            tapefd_setinfo_disk(tape_fd, diskname);
            amfree(diskname);
-           level = syncpipe_getint();
+           if ((level = syncpipe_getint()) == -1) {
+               error("writer: Syncpipe failure fetching level");
+               /*NOTREACHED*/
+           }
            tapefd_setinfo_level(tape_fd, level);
            write_file();
            break;
@@ -1751,7 +2203,10 @@ int getp, putp;
 #ifdef HAVE_LIBVTBLC
        case 'L':               /* read vtbl label */
            vtbl_no = tmpint;
-           vol_label = syncpipe_getstr();
+           if ((vol_label = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure fetching vrbl label");
+               /*NOTREACHED*/
+           }
            fprintf(stderr, "taper: read label string \"%s\" from pipe\n", 
                    vol_label);
            strncpy(vtbl_entry[vtbl_no].label, vol_label, 45);
@@ -1759,7 +2214,10 @@ int getp, putp;
 
        case 'D':               /* read vtbl date */
            vtbl_no = tmpint;
-           vol_date = syncpipe_getstr();
+           if ((vol_date = syncpipe_getstr()) == NULL) {
+               error("writer: Syncpipe failure fetching vrbl date");
+               /*NOTREACHED*/
+           }
            fprintf(stderr, "taper: read date string \"%s\" from pipe\n", 
                    vol_date);
            strncpy(vtbl_entry[vtbl_no].date, vol_date, 20);
@@ -1769,7 +2227,8 @@ int getp, putp;
        case 'Q':
            end_tape(0);        /* XXX check results of end tape ?? */
            clear_tapelist();
-           amfree(taper_datestamp);
+           free_server_config();
+           amfree(taper_timestamp);
            amfree(label);
            amfree(errstr);
            amfree(changer_resultstr);
@@ -1780,11 +2239,11 @@ int getp, putp;
 
            malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
-           if(malloc_size_1 != malloc_size_2) {
+           if (malloc_size_1 != malloc_size_2) {
                malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
            }
-
            exit(0);
+           /*NOTREACHED*/
 
        default:
            assert(0);
@@ -1792,11 +2251,12 @@ int getp, putp;
     }
 }
 
-void write_file()
+void
+write_file(void)
 {
     buffer_t *bp;
     int full_buffers, i, bufnum;
-    char tok;
+    int tok;
     char number[NUM_STR_SIZE];
     char *rdwait_str, *wrwait_str, *fmwait_str;
     int tmpint;
@@ -1808,7 +2268,7 @@ void write_file()
     full_buffers = 0;
     tok = '?';
 
-    if(bufdebug) {
+    if (bufdebug) {
        fprintf(stderr, "taper: w: start file\n");
        fflush(stderr);
     }
@@ -1816,13 +2276,19 @@ void write_file()
     /*
      * Tell the reader that the tape is open, and give it all the buffers.
      */
-    syncpipe_put('O', 0);
-    for(i = 0; i < conf_tapebufs; i++) {
-       if(bufdebug) {
+    if (syncpipe_put('O', 0) == -1) {
+       error("writer: Syncpipe failure starting write sequence");
+       /*NOTREACHED*/
+    }
+    for (i = 0; i < conf_tapebufs; i++) {
+       if (bufdebug) {
            fprintf(stderr, "taper: w: put R%d\n", i);
            fflush(stderr);
        }
-       syncpipe_put('R', i);
+       if (syncpipe_put('R', i) == -1) {
+           error("writer: Syncpipe failure readying write buffers");
+           /*NOTREACHED*/
+       }
     }
 
     /*
@@ -1832,7 +2298,7 @@ void write_file()
      */
 
     startclock();
-    if(!write_filemark())
+    if (!write_filemark())
        goto tape_error;
     fmwait = stopclock();
 
@@ -1850,12 +2316,17 @@ void write_file()
         * of starts/stops, which in turn saves tape and time.
         */
 
-       if(interactive) fputs("[WS]", stderr);
+       if (interactive)
+           fputs("[WS]", stderr);
        startclock();
-       while(full_buffers < conf_tapebufs - THRESHOLD) {
-           tok = syncpipe_get(&bufnum);
-           if(tok != 'W') break;
-           if(bufdebug) {
+       while (full_buffers < conf_tapebufs - THRESHOLD) {
+           if ((tok = syncpipe_get(&bufnum)) == -1) {
+               error("writer: Syncpipe failure during buffer advance");
+               /*NOTREACHED*/
+           }
+           if (tok != 'W')
+               break;
+           if (bufdebug) {
                fprintf(stderr,"taper: w: got W%d\n",bufnum);
                fflush(stderr);
            }
@@ -1872,12 +2343,13 @@ void write_file()
         * in, then we will be STREAMING.
         */
 
-       while(full_buffers) {
-           if(tt_file_pad && bp->size < tt_blocksize) {
+       while (full_buffers) {
+           if (tt_file_pad && bp->size < (ssize_t)tt_blocksize) {
                memset(bp->buffer+bp->size, 0, tt_blocksize - bp->size);
-               bp->size = tt_blocksize;
+               bp->size = (ssize_t)tt_blocksize;
            }
-           if(!write_buffer(bp)) goto tape_error;
+           if (!write_buffer(bp))
+               goto tape_error;
            full_buffers--;
            bp = nextbuf(bp);
        }
@@ -1895,53 +2367,74 @@ void write_file()
         * to wait for buffers to fill, we are then STOPPED again.
         */
 
-       while(tok == 'W' && bp->status == FULL) {
-           tok = syncpipe_get(&bufnum);
-           if(tok == 'W') {
-               if(bufdebug) {
+       while (tok == 'W' && bp->status == FULL) {
+           if ((tok = syncpipe_get(&bufnum)) == -1) {
+               error("writer: Syncpipe failure advancing buffer");
+               /*NOTREACHED*/
+           }
+
+           if (tok == 'W') {
+               if (bufdebug) {
                    fprintf(stderr,"taper: w: got W%d\n",bufnum);
                    fflush(stderr);
                }
-               if(bufnum != bp-buftable) {
+               if(bufnum != (int)(bp - buftable)) {
                    fprintf(stderr,
                            "taper: tape-writer: my buf %d reader buf %d\n",
                            (int)(bp-buftable), bufnum);
                    fflush(stderr);
-                   syncpipe_put('E', 0);
-                   syncpipe_putstr("writer-side buffer mismatch");
+                   if (syncpipe_put('E', 0) == -1) { 
+                       error("writer: Syncpipe failure putting error token");
+                       /*NOTREACHED*/
+                   }
+                   if (syncpipe_putstr("writer-side buffer mismatch") == -1) {
+                       error("writer: Syncpipe failure putting error messgae");
+                       /*NOTREACHED*/
+                   }
                    goto error_ack;
                }
-               if(tt_file_pad && bp->size < tt_blocksize) {
+               if (tt_file_pad && bp->size < (ssize_t)tt_blocksize) {
                    memset(bp->buffer+bp->size, 0, tt_blocksize - bp->size);
-                   bp->size = tt_blocksize;
+                   bp->size = (ssize_t)tt_blocksize;
                }
-               if(!write_buffer(bp)) goto tape_error;
+               if (!write_buffer(bp))
+                   goto tape_error;
                bp = nextbuf(bp);
-           }
-           else if(tok == 'Q')
+           } else if (tok == 'Q') {
                return;
-           else if(tok == 'X')
+           } else if (tok == 'X') {
                goto reader_buffer_snafu;
-           else
+           } else {
                error("writer-side not expecting token: %c", tok);
+               /*NOTREACHED*/
+           }
        }
-    } while(tok == 'W');
+    } while (tok == 'W');
 
     /* got close signal from reader, acknowledge it */
 
-    if(tok == 'X')
+    if (tok == 'X')
        goto reader_buffer_snafu;
 
     assert(tok == 'C');
-    syncpipe_put('C', 0);
+    if (syncpipe_put('C', 0) == -1) {
+       error("writer: Syncpipe failure putting close");
+       /*NOTREACHED*/
+    }
 
     /* tell reader the tape and file number */
 
-    syncpipe_putstr(label);
-    snprintf(number, sizeof(number), "%d", filenum);
-    syncpipe_putstr(number);
+    if (syncpipe_putstr(label) == -1) {
+       error("writer: Syncpipe failure putting label");
+       /*NOTREACHED*/
+    }
+    snprintf(number, SIZEOF(number), "%d", filenum);
+    if (syncpipe_putstr(number) == -1) {
+       error("writer: Syncpipe failure putting filenum");
+       /*NOTREACHED*/
+    }
 
-    snprintf(number, sizeof(number), "%ld", total_writes);
+    snprintf(number, SIZEOF(number), "%lu", total_writes);
     rdwait_str = stralloc(walltime_str(rdwait));
     wrwait_str = stralloc(walltime_str(wrwait));
     fmwait_str = stralloc(walltime_str(fmwait));
@@ -1956,7 +2449,10 @@ void write_file()
     amfree(rdwait_str);
     amfree(wrwait_str);
     amfree(fmwait_str);
-    syncpipe_putstr(errstr);
+    if (syncpipe_putstr(errstr) == -1) {
+       error("writer: Syncpipe failure putting '%s'", errstr);
+       /*NOTREACHED*/
+    }
 
     /* XXX go to next tape if past tape size? */
 
@@ -1964,34 +2460,56 @@ void write_file()
 
  tape_error:
     /* got tape error */
-    if(next_tape(1)) syncpipe_put('T', 0);     /* next tape in place, try again */
-    else syncpipe_put('E', 0);         /* no more tapes, fail */
-    syncpipe_putstr(errstr);
+    if (next_tape(1)) {
+       if (syncpipe_put('T', 0) == -1) {   /* next tape in place, try again */
+           error("writer: Syncpipe failure during tape advance");
+           /*NOTREACHED*/
+       }
+    } else {
+       if (syncpipe_put('E', 0) == -1) {   /* no more tapes, fail */
+           error("writer: Syncpipe failure during tape error");
+           /*NOTREACHED*/
+       }
+    }
+    if (syncpipe_putstr(errstr) == -1) {
+       error("writer: Syncpipe failure putting '%s'", errstr);
+       /*NOTREACHED*/
+    }
 
  error_ack:
     /* wait for reader to acknowledge error */
     do {
-       tok = syncpipe_get(&tmpint);
-       if(tok != 'W' && tok != 'C' && tok != 'e')
+       if ((tok = syncpipe_get(&tmpint)) == -1) {
+           error("writer: syncpipe failure waiting for error ack");
+           /*NOTREACHED*/
+       }
+
+       if (tok != 'W' && tok != 'C' && tok != 'e') {
            error("writer: got '%c' unexpectedly after error", tok);
-    } while(tok != 'e');
+           /*NOTREACHED*/
+       }
+    } while (tok != 'e');
     return;
 
  reader_buffer_snafu:
-    syncpipe_put('x', 0);
+    if (syncpipe_put('x', 0) == -1) {
+       error("writer: syncpipe failure putting buffer snafu");
+       /*NOTREACHED*/
+    }
     return;
 }
 
-int write_buffer(bp)
-buffer_t *bp;
+int
+write_buffer(
+    buffer_t *bp)
 {
-    int rc;
+    ssize_t rc;
 
     assert(bp->status == FULL);
 
     startclock();
-    rc = tapefd_write(tape_fd, bp->buffer, bp->size);
-    if(rc == bp->size) {
+    rc = tapefd_write(tape_fd, bp->buffer, (size_t)bp->size);
+    if (rc == (ssize_t)bp->size) {
 #if defined(NEED_RESETOFS)
        static double tape_used_modulus_2gb = 0;
 
@@ -2001,23 +2519,28 @@ buffer_t *bp;
         * go silly on us.
         */
        tape_used_modulus_2gb += (double)rc;
-       if(tape_used_modulus_2gb + (double)rc > (double)0x7fffffff) {
+       if (tape_used_modulus_2gb + (double)rc > (double)0x7fffffff) {
            tape_used_modulus_2gb = 0;
            tapefd_resetofs(tape_fd);
        }
 #endif
        wrwait = timesadd(wrwait, stopclock());
        total_writes += 1;
-       total_tape_used += (double)rc;
+       total_tape_used += (off_t)rc;
        bp->status = EMPTY;
-       if(interactive || bufdebug) dumpstatus(bp);
-       if(interactive) fputs("W", stderr);
+       if (interactive || bufdebug)
+           dumpstatus(bp);
+       if (interactive)
+           fputs("W", stderr);
 
-       if(bufdebug) {
+       if (bufdebug) {
            fprintf(stderr, "taper: w: put R%d\n", (int)(bp-buftable));
            fflush(stderr);
        }
-       syncpipe_put('R', bp-buftable);
+       if (syncpipe_put('R', (int)(bp-buftable)) == -1) {
+           error("writer: Syncpipe failure during advancing write bufffer");
+           /*NOTREACHED*/
+       }
        return 1;
     } else {
        errstr = newvstralloc(errstr,
@@ -2025,7 +2548,8 @@ buffer_t *bp;
                              (rc != -1) ? "short write" : strerror(errno),
                              NULL);
        wrwait = timesadd(wrwait, stopclock());
-       if(interactive) fputs("[WE]", stderr);
+       if (interactive)
+           fputs("[WE]", stderr);
        return 0;
     }
 }
@@ -2042,7 +2566,8 @@ cleanup(void)
  * Cleanup shared memory segments 
  */
 static void 
-signal_handler(int signum)
+signal_handler(
+    int signum)
 {
     log_add(L_INFO, "Received signal %d", signum);
 
@@ -2056,7 +2581,7 @@ signal_handler(int signum)
  * segments
  */
 static void
-install_signal_handlers(void) 
+install_signal_handlers(void)
 {
     struct sigaction act;
 
@@ -2068,26 +2593,32 @@ install_signal_handlers(void)
 
     if (sigaction(SIGINT, &act, NULL) != 0) {
        error("taper: couldn't install SIGINT handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (sigaction(SIGHUP, &act, NULL) != 0) {
        error("taper: couldn't install SIGHUP handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
    
     if (sigaction(SIGTERM, &act, NULL) != 0) {
        error("taper: couldn't install SIGTERM handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (sigaction(SIGUSR1, &act, NULL) != 0) {
        error("taper: couldn't install SIGUSR1 handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (sigaction(SIGUSR2, &act, NULL) != 0) {
        error("taper: couldn't install SIGUSR2 handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (sigaction(SIGALRM, &act, NULL) != 0) {
        error("taper: couldn't install SIGALRM handler [%s]", strerror(errno));
+       /*NOTREACHED*/
     }
 }
 
@@ -2102,44 +2633,51 @@ install_signal_handlers(void)
 
 int shmid = -1;
 
-char *attach_buffers(size)
-    unsigned int size;
+char *
+attach_buffers(
+    size_t size)
 {
     char *result;
 
     shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0700);
-    if(shmid == -1) {
+    if (shmid == -1) {
        return NULL;
     }
 
     result = (char *)shmat(shmid, (SHM_ARG_TYPE *)NULL, 0);
 
-    if(result == (char *)-1) {
+    if (result == (char *)-1) {
        int save_errno = errno;
 
        destroy_buffers();
        errno = save_errno;
        error("shmat: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 
     return result;
 }
 
 
-void detach_buffers(bufp)
-    char *bufp;
+void
+detach_buffers(
+    char *bufp)
 {
     if ((bufp != NULL) &&
         (shmdt((SHM_ARG_TYPE *)bufp) == -1)) {
        error("shmdt: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 }
 
-void destroy_buffers()
+void
+destroy_buffers(void)
 {
-    if(shmid == -1) return;    /* nothing to destroy */
-    if(shmctl(shmid, IPC_RMID, NULL) == -1) {
+    if (shmid == -1)
+       return; /* nothing to destroy */
+    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        error("shmctl: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 }
 
@@ -2160,19 +2698,21 @@ void destroy_buffers()
 #endif
 
 int shmfd = -1;
-unsigned int saved_size;
+size_t saved_size;
 
-char *attach_buffers(size)
-    unsigned int size;
+char *
+attach_buffers(
+    size_t size)
 {
     char *shmbuf;
 
 #ifdef ZERO_FILE
     shmfd = open(ZERO_FILE, O_RDWR);
-    if(shmfd == -1) {
+    if (shmfd == -1) {
        error("attach_buffers: could not open %s: %s",
              ZERO_FILE,
              strerror(errno));
+        /*NOTREACHED*/
     }
 #endif
 
@@ -2186,19 +2726,22 @@ char *attach_buffers(size)
     return shmbuf;
 }
 
-void detach_buffers(bufp)
-char *bufp;
+void
+detach_buffers(
+    char *bufp)
 {
     if ((bufp != NULL) && 
        (munmap((void *)bufp, saved_size) == -1)) {
        error("detach_buffers: munmap: %s", strerror(errno));
+       /*NOTREACHED*/
     }
 
     if (shmfd != -1)
        aclose(shmfd);
 }
 
-void destroy_buffers()
+void
+destroy_buffers(void)
 {
 }
 
@@ -2217,140 +2760,244 @@ void destroy_buffers()
 
 int getpipe, putpipe;
 
-void syncpipe_init(rd, wr)
-int rd, wr;
+void
+syncpipe_init(
+    int rd,
+    int wr)
 {
     getpipe = rd;
     putpipe = wr;
 }
 
-char syncpipe_get(intp)
-int *intp;
+void
+syncpipe_read_error(
+    ssize_t    rc,
+    ssize_t    expected)
 {
-    int rc;
     char buf[sizeof(char) + sizeof(int)];
 
-    rc = fullread(getpipe, buf, sizeof(buf));
-    if(rc == 0)                /* EOF */
-       error("syncpipe_get: %c: unexpected EOF", *procname);
-    else if(rc < 0)
-       error("syncpipe_get: %c: %s", *procname, strerror(errno));
-    else if(rc != sizeof(buf))
-       error("syncpipe_get: %s", "short read");
+    if (rc == 0) {
+       dbprintf(("syncpipe_get %s halting: Unexpected read EOF\n", procname));
+       fprintf(stderr, "syncpipe_get %s halting: Unexpected read EOF\n", procname);
+    } else if (rc < 0) {
+       dbprintf(("syncpipe_get %s halting: Read error - %s\n",
+                       procname, strerror(errno)));
+       fprintf(stderr, "syncpipe_get %s halting: Read error - %s\n",
+                       procname, strerror(errno));
+    } else {
+       dbprintf(("syncpipe_get %s halting: Read "
+               SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+               procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+               (SSIZE_T_FMT_TYPE)expected));
+       fprintf(stderr, "syncpipe_get %s halting: Read "
+               SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+               procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+               (SSIZE_T_FMT_TYPE)expected);
+    }
+    /* Halt the other side if it's still alive */
+    buf[0] = 'H';
+    memset(&buf[1], 0, SIZEOF(int));
+    if (write(putpipe, buf, SIZEOF(buf)))
+       return;
+}
+
+void
+syncpipe_write_error(
+    ssize_t    rc,
+    ssize_t    expected)
+{
+    char buf[sizeof(char) + sizeof(int)];
+
+    if (rc == 0) {             /* EOF */
+       dbprintf(("syncpipe %s halting: Write EOF\n", procname));
+       fprintf(stderr, "syncpipe %s halting: Write EOF\n", procname);
+    } else if (rc < 0) {
+       dbprintf(("syncpipe %s halting: Write error - %s\n",
+                       procname, strerror(errno)));
+       fprintf(stderr, "syncpipe %s halting: Write error - %s\n",
+                       procname, strerror(errno));
+    } else {
+       dbprintf(("syncpipe %s halting: Write "
+                       SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+                       procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+                       (SSIZE_T_FMT_TYPE)expected));
+       fprintf(stderr, "syncpipe %s halting: Write "
+                       SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+                       procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+                       (SSIZE_T_FMT_TYPE)expected);
+    }
+    /* Halt the other side if it's still alive */
+    buf[0] = 'H';
+    memset(&buf[1], 0, SIZEOF(int));
+    if (write(putpipe, buf, SIZEOF(buf)))
+       return;
+}
+
+int
+syncpipe_get(
+    int *intp)
+{
+    ssize_t rc;
+    char buf[SIZEOF(char) + SIZEOF(int)];
 
-    if(bufdebug && *buf != 'R' && *buf != 'W') {
-       fprintf(stderr,"taper: %c: getc %c\n",*procname,*buf);
+    memset(buf, 0, sizeof(buf));
+    rc = fullread(getpipe, buf, SIZEOF(buf));
+    if (rc != (ssize_t)sizeof(buf)) {
+       syncpipe_read_error(rc, (ssize_t)sizeof(buf));
+       return (-1);
+    }
+
+    if (bufdebug && *buf != 'R' && *buf != 'W') {
+       fprintf(stderr,"taper: %c: getc %c\n", *procname, *buf);
        fflush(stderr);
     }
 
-    memcpy(intp, &buf[1], sizeof(int));
-    return buf[0];
+    memcpy(intp, &buf[1], SIZEOF(int));
+    return (int)buf[0];
 }
 
-int syncpipe_getint()
+int
+syncpipe_getint(void)
 {
-    int rc, i;
+    ssize_t rc;
+    int i = 0;
 
-    if ((rc = fullread(getpipe, &i, sizeof(i))) != sizeof(i))
-       error("syncpipe_getint: %s", rc < 0 ? strerror(errno) : "short read");
+    rc = fullread(getpipe, &i, SIZEOF(i));
+    if (rc != (ssize_t)sizeof(i)) {
+       syncpipe_read_error(rc, (ssize_t)sizeof(i));
+       return (-1);
+    }
 
     return (i);
 }
 
 
-char *syncpipe_getstr()
+char *
+syncpipe_getstr(void)
 {
-    int rc, len;
+    ssize_t rc;
+    int len;
     char *str;
 
-    if((len = syncpipe_getint()) <= 0) {
-       error("syncpipe_getstr: Protocol error - Invalid length (%d)", len);
-       /* NOTREACHED */
+    if ((len = syncpipe_getint()) <= 0) {
+       fprintf(stderr, "syncpipe %s halting: Protocol error - "
+                       "Invalid string length (%d)\n", procname, len);
+       syncpipe_put('H', 0); /* Halt the other side */
+       exit(1);
+       /*NOTREACHED*/
     }
 
-    str = alloc(len);
+    str = alloc((size_t)len);
 
-    if ((rc = fullread(getpipe, str, len)) != len) {
-       error("syncpipe_getstr: %s", rc < 0 ? strerror(errno) : "short read");
-       /* NOTREACHED */
+    rc = fullread(getpipe, str, (size_t)len);
+    if (rc != (ssize_t)len) {
+       syncpipe_read_error(rc, (ssize_t)len);
+       return (NULL);
     }
-
     return (str);
 }
 
 
-void syncpipe_put(chi, intval)
-int chi;
-int intval;
+int
+syncpipe_put(
+    int chi,
+    int intval)
 {
     char buf[sizeof(char) + sizeof(int)];
+    ssize_t    rc;
 
     buf[0] = (char)chi;
-    memcpy(&buf[1], &intval, sizeof(int));
-    if(bufdebug && buf[0] != 'R' && buf[0] != 'W') {
+    memcpy(&buf[1], &intval, SIZEOF(int));
+    if (bufdebug && buf[0] != 'R' && buf[0] != 'W') {
        fprintf(stderr,"taper: %c: putc %c\n",*procname,buf[0]);
        fflush(stderr);
     }
 
-    if (fullwrite(putpipe, buf, sizeof(buf)) < 0)
-       error("syncpipe_put: %s", strerror(errno));
+    rc = fullwrite(putpipe, buf, SIZEOF(buf));
+    if (rc != (ssize_t)sizeof(buf)) {
+       syncpipe_write_error(rc, (ssize_t)sizeof(buf));
+       return (-1);
+    }
+    return (0);
 }
 
-void syncpipe_putint(i)
-int i;
+int
+syncpipe_putint(
+    int i)
 {
+    ssize_t    rc;
 
-    if (fullwrite(putpipe, &i, sizeof(i)) < 0)
-       error("syncpipe_putint: %s", strerror(errno));
+    rc = fullwrite(putpipe, &i, SIZEOF(i));
+    if (rc != (ssize_t)sizeof(i)) {
+       syncpipe_write_error(rc, (ssize_t)sizeof(i));
+       return (-1);
+       /* NOTREACHED */
+    }
+    return (0);
 }
 
-void syncpipe_putstr(str)
-const char *str;
+int
+syncpipe_putstr(
+    const char *str)
 {
-    int n;
+    ssize_t n, rc;
 
-    n = strlen(str)+1;                         /* send '\0' as well */
-    syncpipe_putint(n);
-    if (fullwrite(putpipe, str, n) < 0)
-       error("syncpipe_putstr: %s", strerror(errno));
-}
+    if(!str)
+       str = "UNKNOWN syncpipe_putstr STRING";
 
+    n = (ssize_t)strlen(str) + 1;                      /* send '\0' as well */
+    syncpipe_putint((int)n);
+
+    rc = fullwrite(putpipe, str, (size_t)n);
+    if (rc != n) {
+       syncpipe_write_error(rc, n);
+       return (-1);
+    }
+    return (0);
+}
 \f
 /*
  * ========================================================================
  * TAPE MANIPULATION SUBSYSTEM
  *
  */
+int label_tape(void);
 
 /* local functions */
-int label_tape P((void));
 
-int label_tape()
+/* return 0 on success              */
+/* return 1 on error and set errstr */
+int
+label_tape(void)
 {  
     char *conf_tapelist_old = NULL;
     char *result;
     static int first_call = 1;
     char *timestamp;
-    char *error_msg;
+    char *error_msg = NULL;
     char *s, *r;
     int slot = -1;
 
-    if (taper_scan(NULL, &label, &timestamp, &error_msg, &tapedev) < 0) {
-        fprintf(stderr, "%s\n", error_msg);
-       errstr = newstralloc(errstr, error_msg);
-        amfree(error_msg);
-        amfree(timestamp);
+    amfree(label);
+    amfree(tapedev);
+    if (taper_scan(NULL, &label, &timestamp, &tapedev, CHAR_taperscan_output_callback, &error_msg) < 0) {
+       fprintf(stderr, "%s\n", error_msg);
+       errstr = error_msg;
+       error_msg = NULL;
+       amfree(timestamp);
        return 0;
     }
+    amfree(timestamp);
     if(error_msg) {
        s = error_msg; r = NULL;
        while((s=strstr(s,"slot "))) { s += 5; r=s; };
        if(r) {
            slot = atoi(r);
        }
+       amfree(error_msg);
     }
-    if((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) {
-       if(errno == EACCES) {
+    if ((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) {
+       if (errno == EACCES) {
            errstr = newstralloc(errstr,
                                 "writing label: tape is write protected");
        } else {
@@ -2360,23 +3007,23 @@ int label_tape()
        return 0;
     }
 
-    tapefd_setinfo_length(tape_fd, tt->length);
+    tapefd_setinfo_length(tape_fd, tapetype_get_length(tt));
 
-    tapefd_setinfo_datestamp(tape_fd, taper_datestamp);
+    tapefd_setinfo_datestamp(tape_fd, taper_timestamp);
     tapefd_setinfo_disk(tape_fd, label);
-    result = tapefd_wrlabel(tape_fd, taper_datestamp, label, tt_blocksize);
-    if(result != NULL) {
+    result = tapefd_wrlabel(tape_fd, taper_timestamp, label, tt_blocksize);
+    if (result != NULL) {
        errstr = newstralloc(errstr, result);
        return 0;
     }
 
     if(slot > -1) {
        fprintf(stderr, "taper: slot: %d wrote label `%s' date `%s'\n", slot,
-               label, taper_datestamp);
+               label, taper_timestamp);
     }
     else {
        fprintf(stderr, "taper: wrote label `%s' date `%s'\n", label,
-               taper_datestamp);
+               taper_timestamp);
     }
     fflush(stderr);
 
@@ -2390,67 +3037,74 @@ int label_tape()
 #endif /* HAVE_LIBVTBLC */
 
     if (strcmp(label, FAKE_LABEL) != 0) {
-
-       if(cur_tape == 0) {
+       if (cur_tape == 0) {
            conf_tapelist_old = stralloc2(conf_tapelist, ".yesterday");
        } else {
            char cur_str[NUM_STR_SIZE];
 
-           snprintf(cur_str, sizeof(cur_str), "%d", cur_tape - 1);
+           snprintf(cur_str, SIZEOF(cur_str), "%d", cur_tape - 1);
            conf_tapelist_old = vstralloc(conf_tapelist,
                                          ".today.", cur_str, NULL);
        }
-       if(write_tapelist(conf_tapelist_old)) {
+
+       if (write_tapelist(conf_tapelist_old)) {
            error("could not write tapelist: %s", strerror(errno));
+           /*NOTREACHED*/
        }
        amfree(conf_tapelist_old);
 
        remove_tapelabel(label);
-       add_tapelabel(atoi(taper_datestamp), label);
-       if(write_tapelist(conf_tapelist)) {
+       add_tapelabel(taper_timestamp, label);
+       if (write_tapelist(conf_tapelist)) {
            error("could not write tapelist: %s", strerror(errno));
+           /*NOTREACHED*/
        }
     }
 
     log_add(L_START, "datestamp %s label %s tape %d",
-           taper_datestamp, label, cur_tape);
+           taper_timestamp, label, cur_tape);
     if (first_call && strcmp(label, FAKE_LABEL) == 0) {
        first_call = 0;
        log_add(L_WARNING, "tapedev is %s, dumps will be thrown away", tapedev);
     }
 
-    total_tape_used=0.0;
+    total_tape_used=(off_t)0;
     total_tape_fm = 0;
 
     return 1;
 }
 
-int first_tape(new_datestamp)
-char *new_datestamp;
+/* return 0 on error and set errstr */
+/* return 1 on success              */
+int
+first_tape(
+    char *new_datestamp)
 {
-    if((have_changer = changer_init()) < 0) {
+    if ((have_changer = changer_init()) < 0) {
        error("changer initialization failed: %s", strerror(errno));
+       /*NOTREACHED*/
     }
     changer_debug = 1;
 
-    taper_datestamp = newstralloc(taper_datestamp, new_datestamp);
+    taper_timestamp = newstralloc(taper_timestamp, new_datestamp);
 
-    if(!label_tape())
+    if (!label_tape())
        return 0;
 
     filenum = 0;
     return 1;
 }
 
-int next_tape(writerror)
-int writerror;
+int
+next_tape(
+    int writerror)
 {
     end_tape(writerror);
 
-    if(++cur_tape >= runtapes)
+    if (++cur_tape >= runtapes)
        return 0;
 
-    if(!label_tape()) {
+    if (!label_tape()) {
        return 0;
     }
 
@@ -2459,33 +3113,34 @@ int writerror;
 }
 
 
-int end_tape(writerror)
-int writerror;
+int
+end_tape(
+    int writerror)
 {
     char *result;
     int rc = 0;
 
-    if(tape_fd >= 0) {
-       log_add(L_INFO, "tape %s kb %ld fm %d %s", 
+    if (tape_fd >= 0) {
+       log_add(L_INFO, "tape %s kb " OFF_T_FMT " fm %d %s", 
                label,
-               (long) ((total_tape_used+1023.0) / 1024.0),
+               (OFF_T_FMT_TYPE)((total_tape_used+(off_t)1023) / (off_t)1024),
                total_tape_fm,
                writerror? errstr : "[OK]");
 
-       fprintf(stderr, "taper: writing end marker. [%s %s kb %ld fm %d]\n",
-               label,
+       fprintf(stderr, "taper: writing end marker. [%s %s kb "
+               OFF_T_FMT " fm %d]\n", label,
                writerror? "ERR" : "OK",
-               (long) ((total_tape_used+1023.0) / 1024.0),
+               (OFF_T_FMT_TYPE)((total_tape_used+(off_t)1023) / (off_t)1024),
                total_tape_fm);
        fflush(stderr);
-       if(! writerror) {
-           if(! write_filemark()) {
+       if (! writerror) {
+           if (! write_filemark()) {
                rc = 1;
                goto common_exit;
            }
 
-           result = tapefd_wrendmark(tape_fd, taper_datestamp, tt_blocksize);
-           if(result != NULL) {
+           result = tapefd_wrendmark(tape_fd, taper_timestamp, tt_blocksize);
+           if (result != NULL) {
                errstr = newstralloc(errstr, result);
                rc = 1;
                goto common_exit;
@@ -2497,14 +3152,14 @@ int writerror;
     if (tape_fd >= 0 && is_zftape(tapedev) == 1) {
        /* rewind the tape */
 
-       if(tapefd_rewind(tape_fd) == -1 ) {
+       if (tapefd_rewind(tape_fd) == -1 ) {
            errstr = newstralloc2(errstr, "rewinding tape: ", strerror(errno));
            rc = 1;
            goto common_exit;
        }
        /* close the tape */
 
-       if(tapefd_close(tape_fd) == -1) {
+       if (tapefd_close(tape_fd) == -1) {
            errstr = newstralloc2(errstr, "closing tape: ", strerror(errno));
            rc = 1;
            goto common_exit;
@@ -2517,7 +3172,7 @@ int writerror;
        fflush(stderr);
     
        if ((tape_fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
-           if(errno == EACCES) {
+           if (errno == EACCES) {
                errstr = newstralloc(errstr,
                                     "updating volume table: tape is write protected");
            } else {
@@ -2539,7 +3194,7 @@ int writerror;
        }
        /* set volume label and date for first entry */
        vtbl_no = 0;
-       if(set_label(label, volumes, num_volumes, vtbl_no)){
+       if (set_label(label, volumes, num_volumes, vtbl_no)) {
            errstr = newstralloc2(errstr,
                                  "setting label for entry 1: ",
                                  strerror(errno));
@@ -2547,7 +3202,7 @@ int writerror;
            goto common_exit;
        }
        /* date of start writing this tape */
-       if (set_date(start_datestr, volumes, num_volumes, vtbl_no)){
+       if (set_date(start_datestr, volumes, num_volumes, vtbl_no)) {
            errstr = newstralloc2(errstr,
                                  "setting date for entry 1: ", 
                                  strerror(errno));
@@ -2555,22 +3210,22 @@ int writerror;
            goto common_exit;
        }
        /* set volume labels and dates for backup files */
-       for (vtbl_no = 1; vtbl_no <= num_volumes - 2; vtbl_no++){ 
+       for (vtbl_no = 1; vtbl_no <= num_volumes - 2; vtbl_no++) 
            fprintf(stderr,"taper: label %i: %s, date %s\n", 
                    vtbl_no,
                    vtbl_entry[vtbl_no].label,
                    vtbl_entry[vtbl_no].date);
            fflush(stderr);
-           if(set_label(vtbl_entry[vtbl_no].label, 
-                        volumes, num_volumes, vtbl_no)){
+           if (set_label(vtbl_entry[vtbl_no].label, 
+                        volumes, num_volumes, vtbl_no)) {
                errstr = newstralloc2(errstr,
                                      "setting label for entry i: ", 
                                      strerror(errno));
                rc = 1;
                goto common_exit;
            }
-           if(set_date(vtbl_entry[vtbl_no].date, 
-                       volumes, num_volumes, vtbl_no)){
+           if (set_date(vtbl_entry[vtbl_no].date, 
+                       volumes, num_volumes, vtbl_no)) {
                errstr = newstralloc2(errstr,
                                      "setting date for entry i: ",
                                      strerror(errno));
@@ -2580,7 +3235,7 @@ int writerror;
        }
        /* set volume label and date for last entry */
        vtbl_no = num_volumes - 1;
-       if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
+       if (set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)) {
            errstr = newstralloc2(errstr,
                                  "setting label for last entry: ", 
                                  strerror(errno));
@@ -2588,7 +3243,7 @@ int writerror;
            goto common_exit;
        }
        datestr = NULL; /* take current time */ 
-       if (set_date(datestr, volumes, num_volumes, vtbl_no)){
+       if (set_date(datestr, volumes, num_volumes, vtbl_no)) {
            errstr = newstralloc2(errstr,
                                  "setting date for last entry 1: ", 
                                  strerror(errno));
@@ -2615,7 +3270,7 @@ int writerror;
 
 common_exit:
 
-    if(tape_fd >= 0 && tapefd_close(tape_fd) == -1 && ! writerror) {
+    if (tape_fd >= 0 && tapefd_close(tape_fd) == -1 && ! writerror) {
        errstr = newstralloc2(errstr, "closing tape: ", strerror(errno));
        rc = 1;
     }
@@ -2626,14 +3281,13 @@ common_exit:
 }
 
 
-int write_filemark()
+int
+write_filemark(void)
 {
-    if(tapefd_weof(tape_fd, 1) == -1) {
+    if (tapefd_weof(tape_fd, (off_t)1) == -1) {
        errstr = newstralloc2(errstr, "writing filemark: ", strerror(errno));
        return 0;
     }
     total_tape_fm++;
     return 1;
 }
-
-
index 3b5ba5518876f19fcc303d40290c0ab6964b6f59..b39302cad5119fdbb23f004bfc8fc0f9c3d21e00 100644 (file)
  */
 
 /*
- * $Id: taperscan.c,v 1.9 2006/03/10 14:29:22 martinea Exp $
+ * $Id: taperscan.c,v 1.17 2006/07/12 12:28:19 martinea Exp $
  *
  * This contains the implementation of the taper-scan algorithm, as it is
  * used by taper, amcheck, and amtape. See the header file taperscan.h for
  * interface information. */
 
-#include <amanda.h>
-#include <tapeio.h>
-#include <conffile.h>
+#include "amanda.h"
+#include "tapeio.h"
+#include "conffile.h"
 #include "changer.h"
 #include "tapefile.h"
 
-int scan_read_label P((char *dev, char *wantlabel,
+int scan_read_label (char *dev, char *wantlabel,
                        char** label, char** timestamp,
-                       char**error_message));
-int changer_taper_scan P((char *wantlabel, char** gotlabel, char**timestamp,
-                          char**error_message, char **tapedev));
-char *find_brand_new_tape_label();
+                       char**error_message);
+int changer_taper_scan (char *wantlabel, char** gotlabel, char** timestamp,
+                        char **tapedev, void (*)(void *data, char *msg),
+                       void *data);
+int scan_slot (void *data, int rc, char *slotstr, char *device);
+int taper_scan (char* wantlabel, char** gotlabel, char** timestamp,
+               char** tapedev,
+               void taperscan_output_callback(void *data, char *msg),
+               void *data);
+char *find_brand_new_tape_label (void);
+void FILE_taperscan_output_callback (void *data, char *msg);
+void CHAR_taperscan_output_callback (void *data, char *msg);
 
 /* NO GLOBALS PLEASE! */
 
@@ -57,10 +65,14 @@ char *find_brand_new_tape_label();
  * the same interface as taper_scan. 
  * Return value is the same as taper_scan.
  */
-int scan_read_label(char *dev, char *desired_label,
-                    char** label, char** timestamp, char** error_message) {
+int scan_read_label(
+    char *dev,
+    char *desired_label,
+    char** label,
+    char** timestamp,
+    char** error_message)
+{
     char *result = NULL;
-    char *errstr = NULL;
 
     *label = *timestamp = NULL;
     result = tape_rdlabel(dev, timestamp, label);
@@ -106,7 +118,7 @@ int scan_read_label(char *dev, char *desired_label,
         char *labelstr;
         labelstr = getconf_str(CNF_LABELSTR);
        if(!match(labelstr, *label)) {
-            vstrextend(&errstr, "label ", *label,
+            vstrextend(error_message, "label ", *label,
                        " doesn\'t match labelstr \"",
                        labelstr, "\"\n", NULL);
             return -1;
@@ -120,12 +132,12 @@ int scan_read_label(char *dev, char *desired_label,
             tp = lookup_tapelabel(*label);
          
             if(tp == NULL) {
-                vstrextend(&errstr, "label ", *label,
+                vstrextend(error_message, "label ", *label,
                      " match labelstr but it not listed in the tapelist file.\n",
                            NULL);
                 return -1;
             } else if(tp != NULL && !reusable_tape(tp)) {
-                vstrextend(&errstr, "cannot overwrite active tape ", *label,
+                vstrextend(error_message, "cannot overwrite active tape ", *label,
                            "\n", NULL);
                 return -1;
             }
@@ -147,64 +159,111 @@ typedef struct {
     char *first_labelstr_slot;
     int backwards;
     int tape_status;
+    void (*taperscan_output_callback)(void *data, char *msg);
+    void *data;
 } changertrack_t;
 
-int scan_slot(void *data, int rc, char *slotstr, char *device) {
+int
+scan_slot(
+     void *data,
+     int rc,
+     char *slotstr,
+     char *device)
+{
     int label_result;
     changertrack_t *ct = ((changertrack_t*)data);
+    int result;
 
     switch (rc) {
     default:
-        newvstralloc(*(ct->error_message), *(ct->error_message),
-                     "fatal changer error ", slotstr, ": ",
-                     changer_resultstr, NULL);
-        return 1;
+       vstrextend(ct->error_message,
+                  "fatal changer error: slot ", slotstr, ": ",
+                  changer_resultstr, "\n", NULL);
+        result = 1;
+       break;
+
     case 1:
-        newvstralloc(*(ct->error_message), *(ct->error_message),
-                     "changer error ", slotstr, ": ", changer_resultstr, NULL);
-        return 0;
+       vstrextend(ct->error_message,
+                  "changer error: slot ", slotstr, ": ", changer_resultstr,
+                  "\n", NULL);
+        result = 0;
+       break;
+
     case 0:
-       vstrextend(ct->error_message, "slot ", slotstr, ": ", NULL);
+       *(ct->error_message) = newvstralloc(*(ct->error_message), "slot ",
+                                           slotstr, ": ", NULL);
+       amfree(*ct->gotlabel);
+       amfree(*ct->timestamp);
         label_result = scan_read_label(device, ct->wantlabel, ct->gotlabel,
                                        ct->timestamp, ct->error_message);
         if (label_result == 1 || label_result == 3 ||
             (label_result == 2 && !ct->backwards)) {
             *(ct->tapedev) = stralloc(device);
             ct->tape_status = label_result;
-            return 1;
-        } else if (label_result == 2) {
-            if (ct->first_labelstr_slot == NULL)
-                ct->first_labelstr_slot = stralloc(slotstr);
-            return 0;
+            result = 1;
         } else {
-            return 0;
-        }
+           if ((label_result == 2) && (ct->first_labelstr_slot == NULL))
+               ct->first_labelstr_slot = stralloc(slotstr);
+           result = 0;
+       }
+       break;
     }
-    /* NOTREACHED */
-    return 1;
+    ct->taperscan_output_callback(ct->data, *(ct->error_message));
+    amfree(*(ct->error_message));
+    return result;
 }
 
 static int 
-scan_init(void *data, int rc, int nslots, int backwards, int searchable) {
+scan_init(
+    void *data,
+    int rc,
+    int nslots,
+    int backwards,
+    int searchable)
+{
     changertrack_t *ct = ((changertrack_t*)data);
     
+    (void)nslots;      /* Quiet unused parameter warning */
+    (void)searchable;  /* Quiet unused parameter warning */
+
     if (rc) {
-        newvstralloc(*(ct->error_message), *(ct->error_message),
-                     "could not get changer info: ", changer_resultstr, NULL);
+       vstrextend(ct->error_message,
+                  "could not get changer info: ", changer_resultstr, "\n",
+                  NULL);
+       ct->taperscan_output_callback(ct->data, *(ct->error_message));
+       amfree(*(ct->error_message));
     }
 
     ct->backwards = backwards;
     return 0;
 }
 
-int changer_taper_scan(char* wantlabel,
-                       char** gotlabel, char** timestamp,
-                       char** error_message, char **tapedev) {
-    changertrack_t local_data = {wantlabel, gotlabel, timestamp,
-                                 error_message, tapedev, NULL, 0, 0};
+int
+changer_taper_scan(
+    char *wantlabel,
+    char **gotlabel,
+    char **timestamp,
+    char **tapedev,
+    void (*taperscan_output_callback)(void *data, char *msg),
+    void *data)
+{
+    char *error_message = NULL;
+    changertrack_t local_data;
+    char *outslotstr = NULL;
+    int result;
 
     *gotlabel = *timestamp = *tapedev = NULL;
-    
+    local_data.wantlabel = wantlabel;
+    local_data.gotlabel  = gotlabel;
+    local_data.timestamp = timestamp;
+    local_data.error_message = &error_message;
+    local_data.tapedev = tapedev;
+    local_data.first_labelstr_slot = NULL;
+    local_data.backwards = 0;
+    local_data.tape_status = 0;
+    local_data.taperscan_output_callback  = taperscan_output_callback;
+    local_data.data = data;
+
     changer_find(&local_data, scan_init, scan_slot, wantlabel);
     
     if (*(local_data.tapedev)) {
@@ -212,24 +271,33 @@ int changer_taper_scan(char* wantlabel,
         return local_data.tape_status;
     } else if (local_data.first_labelstr_slot) {
         /* Use plan B. */
-        if (changer_loadslot(local_data.first_labelstr_slot,
-                             NULL, tapedev) == 0) {
-            return scan_read_label(*tapedev, NULL, gotlabel, timestamp,
-                                   error_message);
+       result = changer_loadslot(local_data.first_labelstr_slot,
+                                 &outslotstr, tapedev);
+       amfree(outslotstr);
+        if (result == 0) {
+            result = scan_read_label(*tapedev, NULL, gotlabel, timestamp,
+                                    &error_message);
+           taperscan_output_callback(data, error_message);
+           amfree(error_message);
+           return result;
         }
     }
 
     /* Didn't find a tape. :-( */
     assert(local_data.tape_status <= 0);
+    taperscan_output_callback(data, "changer problem: ");
+    taperscan_output_callback(data, changer_resultstr);
     return -1;
 }
 
 int taper_scan(char* wantlabel,
-               char** gotlabel, char** timestamp, char** error_message,
-               char** tapedev) {
+               char** gotlabel, char** timestamp, char** tapedev,
+              void (*taperscan_output_callback)(void *data, char *msg),
+              void *data) {
 
-    *gotlabel = *timestamp = *error_message = NULL;
-    *tapedev = getconf_str(CNF_TAPEDEV);
+    char *error_message = NULL;
+    int result;
+    *gotlabel = *timestamp = NULL;
 
     if (wantlabel == NULL) {
         tape_t *tmp;
@@ -240,29 +308,38 @@ int taper_scan(char* wantlabel,
     }
 
     if (changer_init()) {
-        return changer_taper_scan(wantlabel, gotlabel, timestamp,
-                                    error_message, tapedev);
+        result =  changer_taper_scan(wantlabel, gotlabel, timestamp,
+                                    tapedev,
+                                    taperscan_output_callback, data);
+    }
+    else {
+       *tapedev = stralloc(getconf_str(CNF_TAPEDEV));
+       result =  scan_read_label(*tapedev, wantlabel,
+                                 gotlabel, timestamp, &error_message);
+       taperscan_output_callback(data, error_message);
+       amfree(error_message);
     }
 
-    return scan_read_label(*tapedev, wantlabel,
-                           gotlabel, timestamp, error_message);
+    return result;
 }
 
 #define AUTO_LABEL_MAX_LEN 1024
-char* find_brand_new_tape_label() {
+char *
+find_brand_new_tape_label(void)
+{
     char *format;
     char newlabel[AUTO_LABEL_MAX_LEN];
-    char tmpnum[12];
+    char tmpnum[30]; /* 64-bit integers can be 21 digists... */
     char tmpfmt[16];
     char *auto_pos = NULL;
-    int i, format_len, label_len, auto_len;
+    int i;
+    ssize_t label_len, auto_len;
     tape_t *tp;
 
     if (!getconf_seen(CNF_LABEL_NEW_TAPES)) {
         return NULL;
     }
     format = getconf_str(CNF_LABEL_NEW_TAPES);
-    format_len = strlen(format);
 
     memset(newlabel, 0, AUTO_LABEL_MAX_LEN);
     label_len = 0;
@@ -302,16 +379,17 @@ char* find_brand_new_tape_label() {
         return NULL;
     }
 
-    sprintf(tmpfmt, "%%0%dd", auto_len);
+    snprintf(tmpfmt, SIZEOF(tmpfmt), "%%0" SIZE_T_FMT "d",
+            (SIZE_T_FMT_TYPE)auto_len);
 
     for (i = 1; i < INT_MAX; i ++) {
-        sprintf(tmpnum, tmpfmt, i);
-        if (strlen(tmpnum) != auto_len) {
+        snprintf(tmpnum, SIZEOF(tmpnum), tmpfmt, i);
+        if (strlen(tmpnum) != (size_t)auto_len) {
             fprintf(stderr, "All possible auto-labels used.\n");
             return NULL;
         }
 
-        strncpy(auto_pos, tmpnum, auto_len);
+        strncpy(auto_pos, tmpnum, (size_t)auto_len);
 
         tp = lookup_tapelabel(newlabel);
         if (tp == NULL) {
@@ -325,7 +403,37 @@ char* find_brand_new_tape_label() {
         }
     }
 
-    /* NOTREACHED. Unless you have over two billion tapes. */
+    /* Should not get here unless you have over two billion tapes. */
     fprintf(stderr, "Taper internal error in find_brand_new_tape_label.");
     return 0;
 }
+
+void
+FILE_taperscan_output_callback(
+    void *data,
+    char *msg)
+{
+    if(!msg) return;
+    if(strlen(msg) == 0) return;
+
+    if(data)
+       fprintf((FILE *)data, "%s", msg);
+    else
+       printf("%s", msg);
+}
+
+void
+CHAR_taperscan_output_callback(
+    /*@keep@*/ void *data,
+               char *msg)
+{
+    char **s = (char **)data;
+
+    if(!msg) return;
+    if(strlen(msg) == 0) return;
+
+    if(*s)
+       strappend(*s, msg);
+    else
+       *s = stralloc(msg);
+}
index 39190fb56beeb18593587a5eaeb2d2bf040ec7b6..fc0f7ca1124dc991f8d0b59032c19ae8bfea448a 100644 (file)
  */
 
 /*
- * $Id: taperscan.h,v 1.1 2005/12/21 19:07:51 paddy_s Exp $
+ * $Id: taperscan.h,v 1.3 2006/05/25 01:47:20 johnfranks Exp $
  *
  * This contains the interface to the tape-scan algorithm implementation.
  * The interface is rather simple: Calling programs (taper, amcheck,
  * amtape) call the function below with a desired tape label, and get back
  * all the relevant label information, along with any other error messages.
  */
+#ifndef TAPERSCAN_H
+#define TAPERSCAN_H
+
 
 /* taper_scan(): Scans the changer to find a tape to use. Reads the tape
  *               label, or invents a new one if label_new_tapes is in use.
  *
  * All returned strings are newly-allocated. */
 
-int taper_scan P((char* wantlabel,
-                  char** gotlabel, char** timestamp, char** error_message,
-                  char **tapedev));
+int taper_scan (char* wantlabel,
+                  char** gotlabel, char** timestamp,
+                  char **tapedev,
+                 void taperscan_output_callback(void *data, char *msg),
+                 void *data);
+void FILE_taperscan_output_callback(void *data, char *msg);
+void CHAR_taperscan_output_callback(void *data, char *msg);
+
+#endif /* !TAPERSCAN_H */
index e2cfcf78f4daa89d66bb458ddb3135d19f7461ff..2bfce44903b866fd5bc830656d1ffb3b1aabb1d0 100644 (file)
@@ -3,6 +3,9 @@
 INCLUDES =     -I$(top_builddir)/common-src \
                -I$(top_srcdir)/common-src
 
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
 lib_LTLIBRARIES =      libamtape.la
 LIB_EXTENSION = la
 
@@ -77,3 +80,29 @@ amtapeio.test.c: $(srcdir)/tapeio.c
 
 tapetype:
        @echo "Use amtapetype instead"
+
+lint:
+       @ for p in $(sbin_PROGRAMS); do                                         \
+               if [ $$p = "amtapetype" ]; then                                 \
+                       s="$(amtapetype_SOURCES)";                              \
+               else                                                            \
+                       s=$$p.c;                                                \
+               fi;                                                             \
+               f="$$s $(libamandad_la_SOURCES)";                               \
+               f="$$f "`(cd ../common-src; make listlibsrc 2>&1 > /dev/null)`; \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+
+listlibsrc:
+       @ for p in $(libamtape_la_SOURCES); do  \
+               listlibsrcs="$$listlibsrcs `pwd`/$$p";          \
+       done;                                                   \
+       echo $$listlibsrcs > listlibsrc.output
index 9de9544645ba04b689ee1fa4420ee6722db59831..72449cccc3c10e312d69982803d9666286becf07 100644 (file)
@@ -119,11 +119,14 @@ AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
 AMANDA_TMPDIR = @AMANDA_TMPDIR@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
 AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
 AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
 AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
 AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
 AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
 AR = @AR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -131,6 +134,8 @@ AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
 AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
 BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
 CAT = @CAT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
@@ -314,6 +319,8 @@ target_vendor = @target_vendor@
 INCLUDES = -I$(top_builddir)/common-src \
                -I$(top_srcdir)/common-src
 
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
 lib_LTLIBRARIES = libamtape.la
 LIB_EXTENSION = la
 libamtape_la_SOURCES = output-file.c \
@@ -705,6 +712,32 @@ amtapeio.test.c: $(srcdir)/tapeio.c
 
 tapetype:
        @echo "Use amtapetype instead"
+
+lint:
+       @ for p in $(sbin_PROGRAMS); do                                         \
+               if [ $$p = "amtapetype" ]; then                                 \
+                       s="$(amtapetype_SOURCES)";                              \
+               else                                                            \
+                       s=$$p.c;                                                \
+               fi;                                                             \
+               f="$$s $(libamandad_la_SOURCES)";                               \
+               f="$$f "`(cd ../common-src; make listlibsrc 2>&1 > /dev/null)`; \
+               (cd ../common-src; make listlibsrc);                            \
+               f="$$f "`cat ../common-src/listlibsrc.output`;                  \
+               echo $(LINT) $$f;                                               \
+               $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config        \
+                   $(INCLUDES) $$f;                                            \
+               if [ $$? -ne 0 ]; then                                          \
+                   exit 1;                                                     \
+               fi;                                                             \
+       done;                                                                   \
+        exit 0
+
+listlibsrc:
+       @ for p in $(libamtape_la_SOURCES); do  \
+               listlibsrcs="$$listlibsrcs `pwd`/$$p";          \
+       done;                                                   \
+       echo $$listlibsrcs > listlibsrc.output
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
index 3f21b1198283718f983c2e86a7ba8dcde8ed3ff9..4c7ba6020a874be7c7418650dd8ecc48bddec4e4 100644 (file)
@@ -25,8 +25,10 @@ extern int optind;
 static int debug_amdd = 0;
 static char *pgm = NULL;
 
+static void usage(void);
+
 static void
-usage()
+usage(void)
 {
     fprintf(stderr, "usage: %s ", pgm);
     fprintf(stderr, " [-d]");
@@ -40,25 +42,29 @@ usage()
     exit(1);
 }
 
+static ssize_t (*read_func)(int, void *, size_t);
+static ssize_t (*write_func)(int, const void *, size_t);
+
 int
-main(int argc, char **argv) {
+main(
+    int                argc,
+    char **    argv)
+{
     int infd = 0;                              /* stdin */
     int outfd = 1;                             /* stdout */
-    int blocksize = 512;
-    int skip=0;
-    int len;
+    size_t blocksize = 512;
+    off_t skip = (off_t)0;
+    ssize_t len;
     int pread, fread, pwrite, fwrite;
     int res = 0;
     char *buf;
-    int count = 0;
+    off_t count = (off_t)0;
     int have_count = 0;
     int save_errno;
     int ch;
     char *eq;
-    int length = 0;
+    off_t length = (off_t)0;
     int have_length = 0;
-    ssize_t (*read_func)(int, void *, size_t);
-    ssize_t (*write_func)(int, const void *, size_t);
 
     if((pgm = strrchr(argv[0], '/')) != NULL) {
        pgm++;
@@ -71,38 +77,43 @@ main(int argc, char **argv) {
            debug_amdd = 1;
            fprintf(stderr, "debug mode!\n");
            break;
+
+#ifndef __lint
        case 'l':
            have_length = 1;
-           length = atoi(optarg);
-           len = strlen(optarg);
+           length = OFF_T_ATOI(optarg);
+           len = (ssize_t)strlen(optarg);
            if(len > 0) {
                switch(optarg[len-1] ) {
                case 'k':                               break;
-               case 'b': length /= 2;                  break;
-               case 'M': length *= 1024;               break;
-               default:  length /= 1024;               break;
+               case 'b': length /= (off_t)2;           break;
+               case 'M': length *= (off_t)1024;        break;
+               default:  length /= (off_t)1024;        break;
                }
            } else {
-               length /= 1024;
+               length /= (off_t)1024;
            }
            break;
+#endif
        case 'h':
        default:
            usage();
-           /* NOTREACHED */
+           /*NOTREACHED*/
        }
     }
 
+    /*@ignore@*/
     read_func = read;
     write_func = write;
+    /*@end@*/
     for( ; optind < argc; optind++) {
        if(0 == (eq = strchr(argv[optind], '='))) {
            usage();
-           /* NOTREACHED */
+           /*NOTREACHED*/
        }
-       len = eq - argv[optind];
-       if(0 == strncmp("if", argv[optind], len)) {
-           if((infd = tape_open(eq + 1, O_RDONLY)) < 0) {
+       len = (ssize_t)(eq - argv[optind]);
+       if(0 == strncmp("if", argv[optind], (size_t)len)) {
+           if((infd = tape_open(eq + 1, O_RDONLY, 0)) < 0) {
                save_errno = errno;
                fprintf(stderr, "%s: %s: ", pgm, eq + 1);
                errno = save_errno;
@@ -114,7 +125,7 @@ main(int argc, char **argv) {
                fprintf(stderr, "input opened \"%s\", got fd %d\n",
                                eq + 1, infd);
            }
-       } else if(0 == strncmp("of", argv[optind], len)) {
+       } else if(0 == strncmp("of", argv[optind], (size_t)len)) {
            if((outfd = tape_open(eq + 1, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) {
                save_errno = errno;
                fprintf(stderr, "%s: %s: ", pgm, eq + 1);
@@ -129,13 +140,14 @@ main(int argc, char **argv) {
            }
            if(have_length) {
                if(debug_amdd) {
-                   fprintf(stderr, "length set to %d\n", length);
+                   fprintf(stderr, "length set to " OFF_T_FMT "\n",
+                       (OFF_T_FMT_TYPE)length);
                }
                tapefd_setinfo_length(outfd, length);
            }
-       } else if(0 == strncmp("bs", argv[optind], len)) {
-           blocksize = atoi(eq + 1);
-           len = strlen(argv[optind]);
+       } else if(0 == strncmp("bs", argv[optind], (size_t)len)) {
+           blocksize = SIZE_T_ATOI(eq + 1);
+           len = (ssize_t)strlen(argv[optind]);
            if(len > 0) {
                switch(argv[optind][len-1] ) {
                case 'k': blocksize *= 1024;            break;
@@ -144,18 +156,21 @@ main(int argc, char **argv) {
                }
            }
            if(debug_amdd) {
-               fprintf(stderr, "blocksize set to %d\n", blocksize);
+               fprintf(stderr, "blocksize set to " SIZE_T_FMT "\n",
+                       (SIZE_T_FMT_TYPE)blocksize);
            }
-       } else if(0 == strncmp("count", argv[optind], len)) {
-           count = atoi(eq + 1);
+       } else if(0 == strncmp("count", argv[optind], (size_t)len)) {
+           count = OFF_T_ATOI(eq + 1);
            have_count = 1;
            if(debug_amdd) {
-               fprintf(stderr, "count set to %d\n", count);
+               fprintf(stderr, "count set to " OFF_T_FMT "\n",
+                       (OFF_T_FMT_TYPE)count);
            }
-       } else if(0 == strncmp("skip", argv[optind], len)) {
-           skip = atoi(eq + 1);
+       } else if(0 == strncmp("skip", argv[optind], (size_t)len)) {
+           skip = OFF_T_ATOI(eq + 1);
            if(debug_amdd) {
-               fprintf(stderr, "skip set to %d\n", skip);
+               fprintf(stderr, "skip set to " OFF_T_FMT "\n",
+                       (OFF_T_FMT_TYPE)skip);
            }
        } else {
            fprintf(stderr, "%s: bad argument: \"%s\"\n", pgm, argv[optind]);
@@ -174,25 +189,25 @@ main(int argc, char **argv) {
     eq = "read error";
     pread = fread = pwrite = fwrite = 0;
     while(0 < (len = (*read_func)(infd, buf, blocksize))) {
-       if(skip-- > 0) {
+       if((skip -= (off_t)1) > (off_t)0) {
            continue;
        }
-       if(len == blocksize) {
+       if((size_t)len == blocksize) {
            fread++;
        } else if(len > 0) {
            pread++;
        }
-       len = (*write_func)(outfd, buf, len);
+       len = (*write_func)(outfd, buf, (size_t)len);
        if(len < 0) {
            eq = "write error";
            break;
-       } else if(len == blocksize) {
+       } else if((size_t)len == blocksize) {
            fwrite++;
        } else if(len > 0) {
            pwrite++;
        }
        if(have_count) {
-           if(--count <= 0) {
+           if((count -= (off_t)1) <= (off_t)0) {
                len = 0;
                break;
            }
index 692b525eef8a0871b74e65890a9bdfe7536c7f63..6f85ebc5ca3df9011fcf7c4bb56a21c6cf1cce07 100644 (file)
@@ -29,27 +29,31 @@ extern char *getenv();
 
 extern int optind;
 
-static int do_asf();
-static int do_bsf();
-static int do_status();
+static int do_asf(int fd, off_t count);
+static int do_bsf(int fd, off_t count);
+static int do_status(int fd, off_t count);
+static void usage(void);
 
 struct cmd {
     char *name;
-    int min_chars;
+    size_t min_chars;
     int count;
-    int (*func)();
+    int (*func)(int, off_t);
     int flags;
 } cmd[] = {
-    { "eof",           0,      1,      tapefd_weof, O_RDWR },
-    { "weof",          0,      1,      tapefd_weof, O_RDWR },
-    { "fsf",           0,      1,      tapefd_fsf, O_RDONLY },
-    { "asf",           0,      0,      do_asf, O_RDONLY },
-    { "bsf",           0,      1,      do_bsf, O_RDONLY },
-    { "rewind",                0,      0,      tapefd_rewind, O_RDONLY },
-    { "offline",       0,      0,      tapefd_unload, O_RDONLY },
-    { "rewoffl",       0,      0,      tapefd_unload, O_RDONLY },
-    { "status",                0,      0,      do_status, O_RDONLY },
-    { NULL,            0,      0,      NULL }
+    { "eof",           0,      1,      tapefd_weof,    O_RDWR },
+    { "weof",          0,      1,      tapefd_weof,    O_RDWR },
+    { "fsf",           0,      1,      tapefd_fsf,     O_RDONLY },
+    { "asf",           0,      0,      do_asf,         O_RDONLY },
+    { "bsf",           0,      1,      do_bsf,         O_RDONLY },
+    { "rewind",                0,      0,      (int (*)(int, off_t))tapefd_rewind,
+                                                       O_RDONLY },
+    { "offline",       0,      0,      (int (*)(int, off_t))tapefd_unload,
+                                                       O_RDONLY },
+    { "rewoffl",       0,      0,      (int (*)(int, off_t))tapefd_unload,
+                                                       O_RDONLY },
+    { "status",                0,      0,      do_status,      O_RDONLY },
+    { NULL,            0,      0,      NULL,           0 }
 };
 
 static char *pgm;
@@ -58,9 +62,9 @@ static int debug_ammt = 0;
 static char *tapename;
 
 static int
-do_asf(fd, count)
-    int fd;
-    int count;
+do_asf(
+    int                fd,
+    off_t      count)
 {
     int r;
 
@@ -71,30 +75,34 @@ do_asf(fd, count)
        return r;
     }
     if(debug_ammt) {
-       fprintf(stderr, "calling tapefd_fsf(%d)\n", count);
+       fprintf(stderr, "calling tapefd_fsf(" OFF_T_FMT ")\n",
+               (OFF_T_FMT_TYPE)count);
     }
     return tapefd_fsf(fd, count);
 }
 
 static int
-do_bsf(fd, count)
-    int fd;
-    int count;
+do_bsf(
+    int                fd,
+    off_t      count)
 {
     if(debug_ammt) {
-       fprintf(stderr, "calling tapefd_fsf(%d)\n", -count);
+       fprintf(stderr, "calling tapefd_fsf(" OFF_T_FMT ")\n", 
+               (OFF_T_FMT_TYPE)-count);
     }
     return tapefd_fsf(fd, -count);
 }
 
 static int
-do_status(fd, count)
-    int fd;
-    int count;
+do_status(
+    int                fd,
+    off_t      count)
 {
     int ret;
     struct am_mt_status stat;
 
+    (void)count;       /* Quiet unused parameter warning */
+
     if(debug_ammt) {
        fprintf(stderr, "calling tapefd_status()\n");
     }
@@ -140,18 +148,21 @@ do_status(fd, count)
 }
 
 static void
-usage()
+usage(void)
 {
     fprintf(stderr, "usage: %s [-d] [-f|-t device] command [count]\n", pgm);
     exit(1);
 }
 
 int
-main(int argc, char **argv) {
+main(
+    int                argc,
+    char **    argv)
+{
     int ch;
-    int count;
-    int i;
-    int j;
+    off_t count;
+    size_t i;
+    size_t j;
     int fd;
     int save_errno;
     char *s;
@@ -177,25 +188,26 @@ main(int argc, char **argv) {
            break;
        default:
            usage();
-           /* NOTREACHED */
+           /*NOTREACHED*/
        }
     }
     if(optind >= argc) {
        usage();
-       /* NOTREACHED */
+       /*NOTREACHED*/
     }
 
     /*
      * Compute the minimum abbreviation for each command.
      */
     for(i = 0; cmd[i].name; i++) {
-       cmd[i].min_chars = 1;
+       cmd[i].min_chars = (size_t)1;
        while (1) {
            for(j = 0; cmd[j].name; j++) {
                if(i == j) {
                    continue;
                }
-               if(0 == strncmp(cmd[i].name, cmd[j].name, cmd[i].min_chars)) {
+               if(0 == strncmp(cmd[i].name, cmd[j].name,
+                               cmd[i].min_chars)) {
                    break;
                }
            }
@@ -207,8 +219,8 @@ main(int argc, char **argv) {
        if(debug_ammt) {
            fprintf(stderr, "syntax: %-20s -> %*.*s\n",
                            cmd[i].name,
-                           cmd[i].min_chars,
-                           cmd[i].min_chars,
+                           (int)cmd[i].min_chars,
+                           (int)cmd[i].min_chars,
                            cmd[i].name);
        }
     }
@@ -239,20 +251,21 @@ main(int argc, char **argv) {
        fprintf(stderr, "tapename is \"%s\"\n", tapename);
     }
 
-    count = 1;
+    count = (off_t)1;
     if(optind < argc && cmd[i].count) {
-       count = atoi(argv[optind]);
+       count = OFF_T_ATOI(argv[optind]);
     }
 
     if(debug_ammt) {
        fprintf(stderr, "calling tape_open(\"%s\",%d)\n", tapename, cmd[i].flags);
     }
-    if((fd = tape_open(tapename, cmd[i].flags)) < 0) {
+    if((fd = tape_open(tapename, cmd[i].flags, 0)) < 0) {
        goto report_error;
     }
 
     if(debug_ammt) {
-       fprintf(stderr, "processing %s(%d)\n", cmd[i].name, count);
+       fprintf(stderr, "processing %s(" OFF_T_FMT ")\n",
+               cmd[i].name, (OFF_T_FMT_TYPE)count);
     }
     if(0 != (*cmd[i].func)(fd, count)) {
        goto report_error;
@@ -267,9 +280,9 @@ report_error:
     save_errno = errno;
     fprintf(stderr, "%s %s", tapename, cmd[i].name);
     if(cmd[i].count) {
-       fprintf(stderr, " %d", count);
+       fprintf(stderr, " " OFF_T_FMT, (OFF_T_FMT_TYPE)count);
     }
     errno = save_errno;
     perror(" failed");
-    exit(1);
+    return (1); /* exit */
 }
index 54517f1c4ecf392f8f7da3a18aabb42f05b9d2a3..63e00d9d771a168026c76950dce6dc42ebf64aa9 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 /*
- * $Id: output-file.c,v 1.10 2006/01/14 04:37:20 paddy_s Exp $
+ * $Id: output-file.c,v 1.14 2006/07/06 15:04:18 martinea Exp $
  *
  * tapeio.c virtual tape interface for a file device.
  *
@@ -61,36 +61,43 @@ static
 struct volume_info {
     char *basename;                    /* filename from open */
     struct file_info *fi;              /* file info array */
-    int fi_limit;                      /* length of file info array */
+    size_t fi_limit;                   /* length of file info array */
     int flags;                         /* open flags */
-    int mask;                          /* open mask */
-    int file_count;                    /* number of files */
-    int file_current;                  /* current file position */
-    int record_current;                        /* current record position */
+    mode_t mask;                       /* open mask */
+    off_t file_count;                  /* number of files */
+    off_t file_current;                        /* current file position */
+    off_t record_current;              /* current record position */
     int fd;                            /* data file descriptor */
     int is_online;                     /* true if "tape" is "online" */
     int at_bof;                                /* true if at begining of file */
     int at_eof;                                /* true if at end of file */
     int at_eom;                                /* true if at end of medium */
     int last_operation_write;          /* true if last op was a write */
-    long amount_written;               /* KBytes written since open/rewind */
+    off_t amount_written;              /* KBytes written since open/rewind */
 } *volume_info = NULL;
 
 struct file_info {
     char *name;                                /* file name (tapefd_getinfo_...) */
     struct record_info *ri;            /* record info array */
-    int ri_count;                      /* number of record info entries */
-    int ri_limit;                      /* length of record info array */
+    size_t ri_count;                   /* number of record info entries */
+    size_t ri_limit;                   /* length of record info array */
     int ri_altered;                    /* true if record info altered */
 };
 
 struct record_info {
-    int record_size;                   /* record size */
-    int start_record;                  /* first record in range */ 
-    int end_record;                    /* last record in range */ 
+    size_t record_size;                        /* record size */
+    off_t start_record;                        /* first record in range */ 
+    off_t end_record;                  /* last record in range */ 
 };
 
-static int open_count = 0;
+static size_t open_count = 0;
+
+static int check_online(int fd);
+static int file_open(int fd);
+static void file_close(int fd);
+static void file_release(int fd);
+static size_t get_record_size(struct file_info *fi, off_t record);
+static void put_record_size(struct file_info *fi, off_t record, size_t size);
 
 /*
  * "Open" the tape by scanning the "data" directory.  "Tape files"
@@ -113,17 +120,19 @@ static int open_count = 0;
  */
 
 static int
-check_online(fd)
-    int fd;
+check_online(
+    int        fd)
 {
     char *token[MAX_TOKENS];
     DIR *tapedir;
     struct dirent *entry;
     struct file_info *fi;
+    struct file_info **fi_p;
     char *line;
     int f;
-    int pos;
+    off_t pos;
     int rc = 0;
+    char *qname = quote_string(volume_info[fd].basename);
 
     /*
      * If we are already online, there is nothing else to do.
@@ -142,7 +151,7 @@ check_online(fd)
         */
 
        rc = (errno != ENOENT);
-       fprintf(stderr,"ERROR: %s: %s\n", volume_info[fd].basename, strerror(errno));
+       fprintf(stderr,"ERROR: %s (%s)\n", qname, strerror(errno));
        goto common_exit;
     }
     while ((entry = readdir(tapedir)) != NULL) {
@@ -159,11 +168,13 @@ check_online(fd)
            /*
             * This is a "tape file".
             */
-           pos = atoi(entry->d_name);
-           amtable_alloc((void **)&volume_info[fd].fi,
+           pos = OFF_T_ATOI(entry->d_name);
+           assert((pos + 1) <= (off_t)SSIZE_MAX);
+            fi_p = &volume_info[fd].fi;
+           amtable_alloc((void **)fi_p,
                          &volume_info[fd].fi_limit,
-                         sizeof(*volume_info[fd].fi),
-                         pos + 1,
+                         SIZEOF(*volume_info[fd].fi),
+                         (size_t)(pos + 1),
                          10,
                          NULL);
            fi = &volume_info[fd].fi[pos];
@@ -175,8 +186,8 @@ check_online(fd)
                fi->ri_count = 0;
            }
            fi->name = stralloc(&entry->d_name[6]);
-           if (pos + 1 > volume_info[fd].file_count) {
-               volume_info[fd].file_count = pos + 1;
+           if ((pos + 1) > volume_info[fd].file_count) {
+               volume_info[fd].file_count = (pos + 1);
            }
        }
     }
@@ -188,10 +199,10 @@ check_online(fd)
      * opened.
      */
     for (; (line = areads(fd)) != NULL; free(line)) {
-       f = split(line, token, sizeof(token) / sizeof(token[0]), " ");
+       f = split(line, token, (int)(sizeof(token) / sizeof(token[0])), " ");
        if (f == 2 && strcmp(token[1], "position") == 0) {
-           volume_info[fd].file_current = atoi(token[2]);
-           volume_info[fd].record_current = 0;
+           volume_info[fd].file_current = OFF_T_ATOI(token[2]);
+           volume_info[fd].record_current = (off_t)0;
        }
     }
 
@@ -203,13 +214,14 @@ check_online(fd)
     }
     if (volume_info[fd].file_current < 0) {
        volume_info[fd].file_current = 0;
-       volume_info[fd].record_current = 0;
+       volume_info[fd].record_current = (off_t)0;
     }
 
     volume_info[fd].is_online = 1;
 
 common_exit:
 
+    amfree(qname);
     return rc;
 }
 
@@ -221,14 +233,15 @@ common_exit:
  */
 
 static int
-file_open(fd)
-    int fd;
+file_open(
+    int fd)
 {
     struct file_info *fi;
+    struct file_info **fi_p;
     char *datafilename = NULL;
     char *recordfilename = NULL;
     char *f = NULL;
-    int pos;
+    off_t pos;
     char *host;
     char *disk;
     int level;
@@ -236,19 +249,22 @@ file_open(fd)
     int flags;
     int rfd;
     int n;
-    char *line = NULL;
+    char *line;
     struct record_info *ri;
-    int start_record;
-    int end_record;
-    int record_size;
+    struct record_info **ri_p;
+    off_t start_record;
+    off_t end_record;
+    size_t record_size = 0;
 
     if (volume_info[fd].fd < 0) {
        flags = volume_info[fd].flags;
        pos = volume_info[fd].file_current;
-       amtable_alloc((void **)&volume_info[fd].fi,
+       assert((pos + 1) < (off_t)SSIZE_MAX);
+       fi_p = &volume_info[fd].fi;
+       amtable_alloc((void **)fi_p,
                      &volume_info[fd].fi_limit,
-                     sizeof(*volume_info[fd].fi),
-                     pos + 1,
+                     SIZEOF(*volume_info[fd].fi),
+                     (size_t)(pos + 1),
                      10,
                      NULL);
        fi = &volume_info[fd].fi[pos];
@@ -276,7 +292,7 @@ file_open(fd)
                host = tapefd_getinfo_host(fd);
                disk = tapefd_getinfo_disk(fd);
                level = tapefd_getinfo_level(fd);
-               snprintf(number, sizeof(number), "%d", level);
+               snprintf(number, SIZEOF(number), "%d", level);
                if (host != NULL) {
                    f = stralloc(host);
                }
@@ -285,7 +301,7 @@ file_open(fd)
                    if (f == NULL) {
                        f = stralloc(disk);
                    } else {
-                       f = newvstralloc(f, f, ".", disk, NULL);
+                       vstrextend(&f, ".", disk, NULL);
                    }
                    amfree(disk);
                }
@@ -293,7 +309,7 @@ file_open(fd)
                    if (f == NULL) {
                        f = stralloc(number);
                    } else {
-                       f = newvstralloc(f, f, ".", number, NULL);
+                       vstrextend(&f, ".", number, NULL);
                    }
                }
                if (f == NULL) {
@@ -313,7 +329,8 @@ file_open(fd)
            }
        }
        if (datafilename == NULL) {
-           snprintf(number, sizeof(number), "%05d", pos);
+           snprintf(number, SIZEOF(number),
+                   "%05" OFF_T_RFMT, (OFF_T_FMT_TYPE)pos);
            datafilename = vstralloc(volume_info[fd].basename,
                                     number,
                                     DATA_INDICATOR,
@@ -335,20 +352,20 @@ file_open(fd)
        /*
         * Load the record information.
         */
-       if (volume_info[fd].fd >= 0
-           && fi->ri_count == 0
-           && (rfd = open(recordfilename, O_RDONLY)) >= 0) {
+       if (volume_info[fd].fd >= 0 && fi->ri_count == 0 &&
+               (rfd = open(recordfilename, O_RDONLY)) >= 0) {
            for (; (line = areads(rfd)) != NULL; free(line)) {
                n = sscanf(line,
-                          "%d %d %d",
-                          &start_record,
-                          &end_record,
-                          &record_size);
+                          OFF_T_FMT " "  OFF_T_FMT " " SIZE_T_FMT,
+                          (OFF_T_FMT_TYPE *)&start_record,
+                          (OFF_T_FMT_TYPE *)&end_record,
+                          (SIZE_T_FMT_TYPE *)&record_size);
                if (n == 3) {
-                   amtable_alloc((void **)&fi->ri,
+                    ri_p = &fi->ri;
+                   amtable_alloc((void **)ri_p,
                                  &fi->ri_limit,
-                                 sizeof(*fi->ri),
-                                 fi->ri_count + 1,
+                                 SIZEOF(*fi->ri),
+                                 (size_t)fi->ri_count + 1,
                                  10,
                                  NULL);
                    ri = &fi->ri[fi->ri_count];
@@ -371,27 +388,31 @@ file_open(fd)
  */
 
 static void
-file_close(fd)
-    int fd;
+file_close(
+    int fd)
 {
     struct file_info *fi;
-    int pos;
+    struct file_info **fi_p;
+    off_t pos;
     char number[NUM_STR_SIZE];
     char *filename = NULL;
-    int r;
+    size_t r;
     FILE *f;
 
     aclose(volume_info[fd].fd);
     pos = volume_info[fd].file_current;
-    amtable_alloc((void **)&volume_info[fd].fi,
+    assert((pos + 1) < (off_t)SSIZE_MAX);
+    fi_p = &volume_info[fd].fi;
+    amtable_alloc((void **)fi_p,
                  &volume_info[fd].fi_limit,
-                 sizeof(*volume_info[fd].fi),
-                 pos + 1,
+                 SIZEOF(*volume_info[fd].fi),
+                 (size_t)(pos + 1),
                  10,
                  NULL);
     fi = &volume_info[fd].fi[pos];
     if (fi->ri_altered) {
-       snprintf(number, sizeof(number), "%05d", pos);
+       snprintf(number, SIZEOF(number),
+                "%05" OFF_T_RFMT, (OFF_T_FMT_TYPE)pos);
        filename = vstralloc(volume_info[fd].basename,
                             number,
                             RECORD_INDICATOR,
@@ -401,11 +422,10 @@ file_close(fd)
            goto common_exit;
        }
        for (r = 0; r < fi->ri_count; r++) {
-           fprintf(f,
-                   "%d %d %d\n",
-                   fi->ri[r].start_record,
-                   fi->ri[r].end_record,
-                   fi->ri[r].record_size);
+           fprintf(f, OFF_T_FMT " " OFF_T_FMT " " SIZE_T_FMT "\n",
+                   (OFF_T_FMT_TYPE)fi->ri[r].start_record,
+                   (OFF_T_FMT_TYPE)fi->ri[r].end_record,
+                   (SIZE_T_FMT_TYPE)fi->ri[r].record_size);
        }
        afclose(f);
        fi->ri_altered = 0;
@@ -422,13 +442,14 @@ common_exit:
  */
 
 static void
-file_release(fd)
-    int fd;
+file_release(
+    int fd)
 {
-    int position;
+    off_t position;
     char *filename;
-    int pos;
+    off_t pos;
     char number[NUM_STR_SIZE];
+    struct file_info **fi_p;
 
     /*
      * If the current file is open, release everything beyond it.
@@ -440,14 +461,17 @@ file_release(fd)
        position = volume_info[fd].file_current;
     }
     for (pos = position; pos < volume_info[fd].file_count; pos++) {
-       amtable_alloc((void **)&volume_info[fd].fi,
+       assert(pos < (off_t)SSIZE_MAX);
+        fi_p = &volume_info[fd].fi;
+       amtable_alloc((void **)fi_p,
                      &volume_info[fd].fi_limit,
-                     sizeof(*volume_info[fd].fi),
-                     pos + 1,
+                     SIZEOF(*volume_info[fd].fi),
+                     (size_t)(pos + 1),
                      10,
                      NULL);
        if (volume_info[fd].fi[pos].name != NULL) {
-           snprintf(number, sizeof(number), "%05d", pos);
+           snprintf(number, SIZEOF(number),
+                    "%05" OFF_T_RFMT, (OFF_T_FMT_TYPE)pos);
            filename = vstralloc(volume_info[fd].basename,
                                 number,
                                 DATA_INDICATOR,
@@ -474,12 +498,12 @@ file_release(fd)
  * sorted, does not overlap and does not have gaps.
  */
 
-static int
-get_record_size(fi, record)
-    struct file_info *fi;
-    int record;
+static size_t
+get_record_size(
+    struct file_info * fi,
+    off_t              record)
 {
-    int r;
+    size_t r;
     struct record_info *ri;
 
     for(r = 0; r < fi->ri_count; r++) {
@@ -503,21 +527,22 @@ get_record_size(fi, record)
  */
 
 static void
-put_record_size(fi, record, size)
-    struct file_info *fi;
-    int record;
-    int size;
+put_record_size(
+    struct file_info * fi,
+    off_t              record,
+    size_t             size)
 {
-    int r;
+    size_t r;
     struct record_info *ri;
+    struct record_info **ri_p;
 
     fi->ri_altered = 1;
-    if (record == 0) {
+    if (record == (off_t)0) {
        fi->ri_count = 0;                       /* start over */
     }
     for(r = 0; r < fi->ri_count; r++) {
        ri = &fi->ri[r];
-       if (record - 1 <= ri->end_record) {
+       if ((record - (off_t)1) <= ri->end_record) {
            /*
             * If this record is the same size as the rest of the records
             * in this entry, or it would replace the entire entry,
@@ -533,7 +558,7 @@ put_record_size(fi, record, size)
            /*
             * This record needs a new entry right after the current one.
             */
-           ri->end_record = record - 1;
+           ri->end_record = record - (off_t)1;
            fi->ri_count = r + 1;
            break;
        }
@@ -541,10 +566,11 @@ put_record_size(fi, record, size)
     /*
      * Add a new entry.
      */
-    amtable_alloc((void **)&fi->ri,
+    ri_p = &fi->ri;
+    amtable_alloc((void **)ri_p,
                  &fi->ri_limit,
-                 sizeof(*fi->ri),
-                 fi->ri_count + 1,
+                 SIZEOF(*fi->ri),
+                 (size_t)fi->ri_count + 1,
                  10,
                  NULL);
     ri = &fi->ri[fi->ri_count];
@@ -559,14 +585,15 @@ put_record_size(fi, record, size)
  */
 
 int
-file_tape_open(filename, flags, mask)
-    char *filename;
-    int flags;
-    int mask;
+file_tape_open(
+    char *     filename,
+    int                flags,
+    mode_t     mask)
 {
-    int fd = -1;
+    int fd;
     int save_errno;
-    char *info_file = NULL;
+    char *info_file;
+    struct volume_info **volume_info_p =  &volume_info;
 
     /*
      * Use only O_RDONLY and O_RDWR.
@@ -597,24 +624,24 @@ file_tape_open(filename, flags, mask)
     /*
      * Create the internal info structure for this "tape".
      */
-    amtable_alloc((void **)&volume_info,
+    amtable_alloc((void **)volume_info_p,
                  &open_count,
-                 sizeof(*volume_info),
-                 fd + 1,
+                 SIZEOF(*volume_info),
+                 (size_t)fd + 1,
                  10,
                  NULL);
     volume_info[fd].flags = flags;
     volume_info[fd].mask = mask;
     volume_info[fd].file_count = 0;
     volume_info[fd].file_current = 0;
-    volume_info[fd].record_current = 0;
+    volume_info[fd].record_current = (off_t)0;
     volume_info[fd].fd = -1;
     volume_info[fd].is_online = 0;             /* true when .../data found */
     volume_info[fd].at_bof = 1;                        /* by definition */
     volume_info[fd].at_eof = 0;                        /* do not know yet */
     volume_info[fd].at_eom = 0;                        /* may get reset below */
     volume_info[fd].last_operation_write = 0;
-    volume_info[fd].amount_written = 0;
+    volume_info[fd].amount_written = (off_t)0;
 
     /*
      * Save the base directory name and see if we are "online".
@@ -641,22 +668,22 @@ common_exit:
 }
 
 ssize_t
-file_tapefd_read(fd, buffer, count)
-    int fd;
-    void *buffer;
-    size_t count;
+file_tapefd_read(
+    int                fd,
+    void *     buffer,
+    size_t     count)
 {
-    int result;
+    ssize_t result;
     int file_fd;
-    int pos;
-    int record_size;
-    int read_size;
+    off_t pos;
+    size_t record_size;
+    size_t read_size;
 
     /*
      * Make sure we are online.
      */
-    if ((result = check_online(fd)) != 0) {
-       return result;
+    if (check_online(fd) != 0) {
+       return -1;
     }
     if (! volume_info[fd].is_online) {
        errno = EIO;
@@ -683,7 +710,7 @@ file_tapefd_read(fd, buffer, count)
      * Open the file, if needed.
      */
     if ((file_fd = file_open(fd)) < 0) {
-       return file_fd;
+       return -1;
     }
 
     /*
@@ -705,10 +732,13 @@ file_tapefd_read(fd, buffer, count)
     result = read(file_fd, buffer, read_size);
     if (result > 0) {
        volume_info[fd].at_bof = 0;
-       if (result < record_size) {
-           (void)lseek(file_fd, record_size - result, SEEK_CUR);
+       if ((size_t)result < record_size) {
+           if (lseek(file_fd, (off_t)(record_size-result), SEEK_CUR) == (off_t)-1) {
+               dbprintf(("file_tapefd_read: lseek failed: <%s>\n",
+                         strerror(errno)));
+           }
        }
-       volume_info[fd].record_current++;
+       volume_info[fd].record_current += (off_t)1;
     } else if (result == 0) {
        volume_info[fd].at_eof = 1;
     }
@@ -716,23 +746,23 @@ file_tapefd_read(fd, buffer, count)
 }
 
 ssize_t
-file_tapefd_write(fd, buffer, count)
-    int fd;
-    const void *buffer;
-    size_t count;
+file_tapefd_write(
+    int                fd,
+    const void *buffer,
+    size_t     count)
 {
     int file_fd;
-    int write_count = count;
-    long length;
-    long kbytes_left;
-    int result;
-    int pos;
+    ssize_t write_count = (ssize_t)count;
+    off_t length;
+    off_t kbytes_left;
+    ssize_t result;
+    off_t pos;
 
     /*
      * Make sure we are online.
      */
-    if ((result = check_online(fd)) != 0) {
-       return result;
+    if (check_online(fd) != 0) {
+       return -1;
     }
     if (! volume_info[fd].is_online) {
        errno = EIO;
@@ -785,20 +815,20 @@ file_tapefd_write(fd, buffer, count)
     if((file_fd = volume_info[fd].fd) < 0) {
        file_release(fd);
        if ((file_fd = file_open(fd)) < 0) {
-           return file_fd;
+           return -1;
        }
     }
 
     /*
      * Truncate the write if requested and return a simulated ENOSPC.
      */
-    if ((length = tapefd_getinfo_length(fd)) > 0) {
+    if ((length = tapefd_getinfo_length(fd)) > (off_t)0) {
        kbytes_left = length - volume_info[fd].amount_written;
-       if (write_count / 1024 > kbytes_left) {
-           write_count = kbytes_left * 1024;
+       if ((off_t)(write_count / 1024) > kbytes_left) {
+           write_count = (ssize_t)kbytes_left * 1024;
        }
     }
-    volume_info[fd].amount_written += (write_count + 1023) / 1024;
+    volume_info[fd].amount_written += (off_t)((write_count + 1023) / 1024);
     if (write_count <= 0) {
        volume_info[fd].at_bof = 0;
        volume_info[fd].at_eom = 1;
@@ -812,40 +842,53 @@ file_tapefd_write(fd, buffer, count)
      * once.
      */
     if (! volume_info[fd].last_operation_write) {
-       (void)ftruncate(file_fd, lseek(file_fd, 0, SEEK_CUR));
+       off_t curpos;
+
+       if ((curpos = lseek(file_fd, (off_t)0, SEEK_CUR)) < 0) {
+           dbprintf((": Can not determine current file position <%s>",
+               strerror(errno)));
+           return -1;
+       }
+       if (ftruncate(file_fd, curpos) != 0) {
+           dbprintf(("ftruncate failed; Can not trim output file <%s>",
+               strerror(errno)));
+           return -1;
+       }
        volume_info[fd].at_bof = 0;
        volume_info[fd].at_eom = 1;
     }
-    result = fullwrite(file_fd, buffer, write_count);
+    result = fullwrite(file_fd, buffer, (size_t)write_count);
     if (result >= 0) {
        volume_info[fd].last_operation_write = 1;
        pos = volume_info[fd].file_current;
        put_record_size(&volume_info[fd].fi[pos],
                        volume_info[fd].record_current,
-                       result);
-       volume_info[fd].record_current++;
+                       (size_t)result);
+       volume_info[fd].record_current += (off_t)1;
     }
 
     return result;
 }
 
 int
-file_tapefd_close(fd)
-    int fd;
+file_tapefd_close(
+    int        fd)
 {
-    int pos;
+    off_t pos;
     int save_errno;
     char *line;
-    int len;
+    size_t len;
     char number[NUM_STR_SIZE];
-    int result;
+    ssize_t result;
+    struct file_info **fi_p;
+    struct record_info **ri_p;
 
     /*
      * If our last operation was a write, write a tapemark.
      */
     if (volume_info[fd].last_operation_write) {
-       if ((result = file_tapefd_weof(fd, 1)) != 0) {
-           return result;
+       if ((result = (ssize_t)file_tapefd_weof(fd, (off_t)1)) != 0) {
+           return (int)result;
        }
     }
 
@@ -854,8 +897,8 @@ file_tapefd_close(fd)
      * are already at end of tape.
      */
     if (! volume_info[fd].at_bof && ! volume_info[fd].at_eom) {
-       if ((result = file_tapefd_fsf(fd, 1)) != 0) {
-           return result;
+       if ((result = (ssize_t)file_tapefd_fsf(fd, (off_t)1)) != 0) {
+           return (int)result;
        }
     }
 
@@ -867,13 +910,15 @@ file_tapefd_close(fd)
     /*
      * Release the info structure areas.
      */
-    for (pos = 0; pos < volume_info[fd].fi_limit; pos++) {
+    for (pos = 0; pos < (off_t)volume_info[fd].fi_limit; pos++) {
        amfree(volume_info[fd].fi[pos].name);
-       amtable_free((void **)&volume_info[fd].fi[pos].ri,
+        ri_p = &volume_info[fd].fi[pos].ri;
+       amtable_free((void **)ri_p,
                     &volume_info[fd].fi[pos].ri_limit);
        volume_info[fd].fi[pos].ri_count = 0;
     }
-    amtable_free((void **)&volume_info[fd].fi, &volume_info[fd].fi_limit);
+    fi_p = &volume_info[fd].fi;
+    amtable_free((void **)fi_p, &volume_info[fd].fi_limit);
     volume_info[fd].file_count = 0;
     amfree(volume_info[fd].basename);
 
@@ -881,25 +926,25 @@ file_tapefd_close(fd)
      * Update the status file if we were online.
      */
     if (volume_info[fd].is_online) {
-       if (lseek(fd, 0, SEEK_SET) != 0) {
+       if (lseek(fd, (off_t)0, SEEK_SET) != (off_t)0) {
            save_errno = errno;
            aclose(fd);
            errno = save_errno;
            return -1;
        }
-       if (ftruncate(fd, 0) != 0) {
+       if (ftruncate(fd, (off_t)0) != 0) {
            save_errno = errno;
            aclose(fd);
            errno = save_errno;
            return -1;
        }
-       snprintf(number, sizeof(number),
-                "%d", volume_info[fd].file_current);
+       snprintf(number, SIZEOF(number), "%05" OFF_T_RFMT,
+                (OFF_T_FMT_TYPE)volume_info[fd].file_current);
        line = vstralloc("position ", number, "\n", NULL);
        len = strlen(line);
        result = write(fd, line, len);
        amfree(line);
-       if (result != len) {
+       if (result != (ssize_t)len) {
            if (result >= 0) {
                errno = ENOSPC;
            }
@@ -915,15 +960,16 @@ file_tapefd_close(fd)
 }
 
 void
-file_tapefd_resetofs(fd)
-    int fd;
+file_tapefd_resetofs(
+    int        fd)
 {
+    (void)fd;  /* Quiet unused parameter warning */
 }
 
 int
-file_tapefd_status(fd, stat)
-    int fd;
-    struct am_mt_status *stat;
+file_tapefd_status(
+    int                         fd,
+    struct am_mt_status *stat)
 {
     int result;
 
@@ -933,33 +979,33 @@ file_tapefd_status(fd, stat)
     if ((result = check_online(fd)) != 0) {
        return result;
     }
-    memset((void *)stat, 0, sizeof(*stat));
+    memset((void *)stat, 0, SIZEOF(*stat));
     stat->online_valid = 1;
-    stat->online = volume_info[fd].is_online;
+    stat->online = (char)volume_info[fd].is_online;
     return 0;
 }
 
 int
-file_tape_stat(filename, buf)
-     char *filename;
-     struct stat *buf;
+file_tape_stat(
+     char *            filename,
+     struct stat *     buf)
 {
      return stat(filename, buf);
 }
 
 int
-file_tape_access(filename, mode)
-     char *filename;
-     int mode;
+file_tape_access(
+     char *    filename,
+     int       mode)
 {
      return access(filename, mode);
 }
 
 int
-file_tapefd_rewind(fd)
-    int fd;
+file_tapefd_rewind(
+    int fd)
 {
-    int result = 0;
+    int result;
 
     /*
      * Make sure we are online.
@@ -976,7 +1022,7 @@ file_tapefd_rewind(fd)
      * If our last operation was a write, write a tapemark.
      */
     if (volume_info[fd].last_operation_write) {
-       if ((result = file_tapefd_weof(fd, 1)) != 0) {
+       if ((result = file_tapefd_weof(fd, (off_t)1)) != 0) {
            return result;
        }
     }
@@ -990,21 +1036,21 @@ file_tapefd_rewind(fd)
      * Adjust the position and reset the flags.
      */
     volume_info[fd].file_current = 0;
-    volume_info[fd].record_current = 0;
+    volume_info[fd].record_current = (off_t)0;
 
     volume_info[fd].at_bof = 1;
     volume_info[fd].at_eof = 0;
     volume_info[fd].at_eom
       = (volume_info[fd].file_current >= volume_info[fd].file_count);
     volume_info[fd].last_operation_write = 0;
-    volume_info[fd].amount_written = 0;
+    volume_info[fd].amount_written = (off_t)0;
 
     return result;
 }
 
 int
-file_tapefd_unload(fd)
-    int fd;
+file_tapefd_unload(
+    int        fd)
 {
     int result;
 
@@ -1019,15 +1065,16 @@ file_tapefd_unload(fd)
        return -1;
     }
 
-    file_tapefd_rewind(fd);
+    (void)file_tapefd_rewind(fd);
     return 0;
 }
 
 int
-file_tapefd_fsf(fd, count)
-    int fd, count;
+file_tapefd_fsf(
+    int                fd,
+    off_t      count)
 {
-    int result = 0;
+    int result;
 
     /*
      * Make sure we are online.
@@ -1045,7 +1092,7 @@ file_tapefd_fsf(fd, count)
      * backward, write a tapemark.
      */
     if (volume_info[fd].last_operation_write && count < 0) {
-       if ((result = file_tapefd_weof(fd, 1)) != 0) {
+       if ((result = file_tapefd_weof(fd, (off_t)1)) != 0) {
            errno = EIO;
            return -1;
        }
@@ -1078,7 +1125,7 @@ file_tapefd_fsf(fd, count)
        errno = EIO;
        result = -1;
     }
-    volume_info[fd].record_current = 0;
+    volume_info[fd].record_current = (off_t)0;
 
     /*
      * Set BOF to true so we can write.  Set to EOF to false if the
@@ -1097,18 +1144,19 @@ file_tapefd_fsf(fd, count)
       = (volume_info[fd].file_current >= volume_info[fd].file_count);
     volume_info[fd].last_operation_write = 0;
     if (volume_info[fd].file_current == 0) {
-       volume_info[fd].amount_written = 0;
+       volume_info[fd].amount_written = (off_t)0;
     }
 
     return result;
 }
 
 int
-file_tapefd_weof(fd, count)
-    int fd, count;
+file_tapefd_weof(
+    int                fd,
+    off_t      count)
 {
     int file_fd;
-    int result = 0;
+    int result;
     char *save_host;
     char *save_disk;
     int save_level;
@@ -1152,10 +1200,28 @@ file_tapefd_weof(fd, count)
      * Close out the current file if open.
      */
     if ((file_fd = volume_info[fd].fd) >= 0) {
-       (void)ftruncate(file_fd, lseek(file_fd, 0, SEEK_CUR));
+       off_t curpos;
+
+       if ((curpos = lseek(file_fd, (off_t)0, SEEK_CUR)) < 0) {
+           save_errno = errno;
+           dbprintf((": Can not determine current file position <%s>",
+               strerror(errno)));
+           file_close(fd);
+           errno = save_errno;
+           return -1;
+       }
+       if (ftruncate(file_fd, curpos) != 0) {
+           save_errno = errno;
+           dbprintf(("ftruncate failed; Can not trim output file <%s>",
+               strerror(errno)));
+           file_close(fd);
+           errno = save_errno;
+           return -1;
+       }
+       
        file_close(fd);
        volume_info[fd].file_current++;
-       volume_info[fd].record_current = 0;
+       volume_info[fd].record_current = (off_t)0;
        volume_info[fd].at_bof = 1;
        volume_info[fd].at_eof = 0;
        volume_info[fd].at_eom = 1;
@@ -1189,7 +1255,7 @@ file_tapefd_weof(fd, count)
        file_close(fd);
        volume_info[fd].file_current++;
        volume_info[fd].file_count = volume_info[fd].file_current;
-       volume_info[fd].record_current = 0;
+       volume_info[fd].record_current = (off_t)0;
        volume_info[fd].at_bof = 1;
        volume_info[fd].at_eof = 0;
        volume_info[fd].at_eom = 1;
@@ -1219,8 +1285,9 @@ file_tapefd_weof(fd, count)
 }
 
 int
-file_tapefd_can_fork(fd)
-    int fd;
+file_tapefd_can_fork(
+    int        fd)
 {
+    (void)fd;  /* Quiet unused parameter warning */
     return 0;
 }
index a0dfd6064969de0ef7ae04ba3f57f435fa4151da..62525802e2b1938c975528120c92c74ead54c0ed 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 /*
- * $Id: output-file.h,v 1.5 2003/03/06 21:43:57 martinea Exp $
+ * $Id: output-file.h,v 1.6 2006/05/25 01:47:27 johnfranks Exp $
  *
  * tapeio.c virtual tape interface for a file device.
  */
 
 #include "amanda.h"
 
-extern int file_tape_access P((char *, int));
-extern int file_tape_open ();
-extern int file_tape_stat P((char *, struct stat *));
-extern int file_tapefd_close P((int));
-extern int file_tapefd_fsf P((int, int));
-extern ssize_t file_tapefd_read P((int, void *, size_t));
-extern int file_tapefd_rewind P((int));
-extern void file_tapefd_resetofs P((int));
-extern int file_tapefd_unload P((int));
-extern int file_tapefd_status P((int, struct am_mt_status *));
-extern int file_tapefd_weof P((int, int));
-extern ssize_t file_tapefd_write P((int, const void *, size_t));
-extern int file_tapefd_can_fork P((int));
+int file_tape_access(char *, int);
+int file_tape_open(char *, int, mode_t);
+int file_tape_stat(char *, struct stat *);
+int file_tapefd_close(int);
+int file_tapefd_fsf(int, off_t);
+ssize_t file_tapefd_read(int, void *, size_t);
+int file_tapefd_rewind(int);
+void file_tapefd_resetofs(int);
+int file_tapefd_unload(int);
+int file_tapefd_status(int, struct am_mt_status *);
+int file_tapefd_weof(int, off_t);
+ssize_t file_tapefd_write(int, const void *, size_t);
+int file_tapefd_can_fork(int);
 
 #endif /* OUTPUT_FILE_H */
index 1a56faea732afa5c041b3e48bcf7b5d6a014e15e..45cdad774f907429d3e74fb56ec7deb140028647 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 /*
- * $Id: output-null.c,v 1.7 2003/03/06 21:43:57 martinea Exp $
+ * $Id: output-null.c,v 1.9 2006/06/02 00:56:06 paddy_s Exp $
  *
  * tapeio.c virtual tape interface for a null device.
  */
 #define W_OK 2
 #endif
 
-static long *amount_written = NULL;
-static int open_count = 0;
+static off_t *amount_written = NULL;
+static size_t open_count = 0;
 
 int
-null_tape_open(filename, flags, mask)
-    char *filename;
-    int flags;
-    int mask;
+null_tape_open(
+    char *     filename,
+    int                flags,
+    mode_t     mask)
 {
     int fd;
+    off_t **amount_written_p = &amount_written;
+
+    (void)filename;    /* Quiet unused parameter warning */
 
     if ((flags & 3) != O_RDONLY) {
        flags &= ~3;
@@ -58,131 +61,148 @@ null_tape_open(filename, flags, mask)
     }
     if ((fd = open("/dev/null", flags, mask)) >= 0) {
        tapefd_setinfo_fake_label(fd, 1);
-       amtable_alloc((void **)&amount_written,
+       amtable_alloc((void **)amount_written_p,
                      &open_count,
-                     sizeof(*amount_written),
-                     fd + 1,
+                     SIZEOF(*amount_written),
+                     (size_t)(fd + 1),
                      10,
                      NULL);
-       amount_written[fd] = 0;
+       amount_written[fd] = (off_t)0;
     }
     return fd;
 }
 
 ssize_t
-null_tapefd_read(fd, buffer, count)
-    int fd;
-    void *buffer;
-    size_t count;
+null_tapefd_read(
+    int                fd,
+    void *     buffer,
+    size_t     count)
 {
     return read(fd, buffer, count);
 }
 
 ssize_t
-null_tapefd_write(fd, buffer, count)
-    int fd;
-    const void *buffer;
-    size_t count;
+null_tapefd_write(
+    int                fd,
+    const void *buffer,
+    size_t     count)
 {
-    int write_count = count;
-    long length;
-    long kbytes_left;
-    int r;
+    ssize_t write_count = (ssize_t)count;
+    off_t length;
+    off_t kbytes_left;
+    ssize_t r;
 
     if (write_count <= 0) {
        return 0;                               /* special case */
     }
 
-    if ((length = tapefd_getinfo_length(fd)) > 0) {
+    if ((length = tapefd_getinfo_length(fd)) > (off_t)0) {
        kbytes_left = length - amount_written[fd];
-       if (write_count / 1024 > kbytes_left) {
-           write_count = kbytes_left * 1024;
+       if ((off_t)(write_count / 1024) > kbytes_left) {
+           write_count = (ssize_t)kbytes_left * 1024;
        }
     }
-    amount_written[fd] += (write_count + 1023) / 1024;
+    amount_written[fd] += (off_t)((write_count + 1023) / 1024);
     if (write_count <= 0) {
        errno = ENOSPC;
        r = -1;
     } else {
-       r = write(fd, buffer, write_count);
+       r = write(fd, buffer, (size_t)write_count);
     }
     return r;
 }
 
 int
-null_tapefd_close(fd)
-    int fd;
+null_tapefd_close(
+    int        fd)
 {
     return close(fd);
 }
 
 void
-null_tapefd_resetofs(fd)
-    int fd;
+null_tapefd_resetofs(
+    int        fd)
 {
+    (void)fd;  /* Quiet unused parameter warning */
 }
 
 int
-null_tapefd_status(fd, stat)
-    int fd;
-    struct am_mt_status *stat;
+null_tapefd_status(
+    int                         fd,
+    struct am_mt_status *stat)
 {
-    memset((void *)stat, 0, sizeof(*stat));
+    (void)fd;  /* Quiet unused parameter warning */
+
+    memset((void *)stat, 0, SIZEOF(*stat));
     stat->online_valid = 1;
     stat->online = 1;
     return 0;
 }
 
 int
-null_tape_stat(filename, buf)
-     char *filename;
-     struct stat *buf;
+null_tape_stat(
+     char *      filename,
+     struct stat *buf)
 {
+    (void)filename;    /* Quiet unused parameter warning */
+
      return stat("/dev/null", buf);
 }
 
 int
-null_tape_access(filename, mode)
-     char *filename;
-     int mode;
+null_tape_access(
+     char *    filename,
+     int       mode)
 {
+    (void)filename;    /* Quiet unused parameter warning */
+
      return access("/dev/null", mode);
 }
 
 int
-null_tapefd_rewind(fd)
-    int fd;
+null_tapefd_rewind(
+    int        fd)
 {
-    amount_written[fd] = 0;
+    amount_written[fd] = (off_t)0;
     return 0;
 }
 
 int
-null_tapefd_unload(fd)
-    int fd;
+null_tapefd_unload(
+    int        fd)
 {
-    amount_written[fd] = 0;
+    amount_written[fd] = (off_t)0;
     return 0;
 }
 
 int
-null_tapefd_fsf(fd, count)
-    int fd, count;
+null_tapefd_fsf(
+    int                fd,
+    off_t      count)
 {
+    (void)fd;          /* Quiet unused parameter warning */
+    (void)count;       /* Quiet unused parameter warning */
+
     return 0;
 }
 
 int
-null_tapefd_weof(fd, count)
-    int fd, count;
+null_tapefd_weof(
+    int                fd,
+    off_t      count)
 {
+    (void)fd;          /* Quiet unused parameter warning */
+    (void)count;       /* Quiet unused parameter warning */
+
     return 0;
 }
 
 int 
-null_tapefd_can_fork(fd)
-    int fd;
+null_tapefd_can_fork(
+    int        fd)
 {
+    (void)fd;          /* Quiet unused parameter warning */
+
     return 0;
 }
 
index d092fa2eaed517be16c75ac58058c5560288b8f1..dd987be9b6f5562ccff68e7a7005a2280e68771c 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 /*
- * $Id: output-null.h,v 1.5 2003/03/06 21:43:57 martinea Exp $
+ * $Id: output-null.h,v 1.6 2006/05/25 01:47:27 johnfranks Exp $
  *
  * tapeio.c virtual tape interface for a null device.
  */
 
 #include "amanda.h"
 
-extern int null_tape_access P((char *, int));
-extern int null_tape_open ();
-extern int null_tape_stat P((char *, struct stat *));
-extern int null_tapefd_close P((int));
-extern int null_tapefd_fsf P((int, int));
-extern ssize_t null_tapefd_read P((int, void *, size_t));
-extern int null_tapefd_rewind P((int));
-extern void null_tapefd_resetofs P((int));
-extern int null_tapefd_unload P((int));
-extern int null_tapefd_status P((int, struct am_mt_status *));
-extern int null_tapefd_weof P((int, int));
-extern ssize_t null_tapefd_write P((int, const void *, size_t));
-extern int null_tapefd_can_fork P((int));
+int null_tape_access(char *, int);
+int null_tape_open(char *, int, mode_t);
+int null_tape_stat(char *, struct stat *);
+int null_tapefd_close(int);
+int null_tapefd_fsf(int, off_t);
+ssize_t null_tapefd_read(int, void *, size_t);
+int null_tapefd_rewind(int);
+void null_tapefd_resetofs(int);
+int null_tapefd_unload(int);
+int null_tapefd_status(int, struct am_mt_status *);
+int null_tapefd_weof(int, off_t);
+ssize_t null_tapefd_write(int, const void *, size_t);
+int null_tapefd_can_fork(int);
 
 #endif /* OUTPUT_NULL_H */
index 3c40f1f6f0728fef14df0ce72b68a834af4cbff6..e094a59febf57a7cbe1290d22aff15836ce60057 100644 (file)
 
 #ifdef NO_AMANDA
 #define        amfree(x)       do {                                            \
-       int save_errno = errno;                                         \
-       free(x);                                                        \
-       (x) = 0;                                                        \
-       errno = save_errno;                                             \
+       if (x) {                                                        \
+           int save_errno = errno;                                     \
+           free(x);                                                    \
+           (x) = NULL;                                                 \
+           errno = save_errno;                                         \
+       }
 } while(0)
 #define        tape_open       open
 #define tapefd_read    read
@@ -57,11 +59,11 @@ char *tapeio_next_devname (char * dev_left,
   rait.c..................................................1
        MAX_RAITS.........................................2
         rait_table........................................2
-       rait_open(char *dev, int flags, int mode).........2
+       rait_open(char *dev, int flags, mode_t mode)......2
        rait_close(int fd)................................3
        rait_lseek(int fd, long pos, int whence)..........4
-       rait_write(int fd, const char *buf, int len) .....5
-       rait_read(int fd, char *buf, int len).............6
+       rait_write(int fd, const char *buf, size_t len) ..5
+       rait_read(int fd, char *buf, size_t len)..........6
        rait_ioctl(int fd, int op, void *p)...............8
        rait_access(devname, R_OK|W_OK)...................8
        rait_stat(devname, struct statbuf*)...............8
@@ -74,8 +76,6 @@ char *tapeio_next_devname (char * dev_left,
            rait_tapefd_status(rait_tapefd, stat)........10
            rait_tapefd_weof(rait_tapefd, count).........10
 
-       
-
    rait.h.................................................1
         typedef RAIT......................................1
         ifdef RAIT_REDIRECT...............................1
@@ -116,7 +116,7 @@ char *tapeio_next_devname (char * dev_left,
 #endif
 
 static RAIT *rait_table = 0;           /* table to keep track of RAITS */
-static int rait_table_count;
+static size_t rait_table_count;
 
 #ifdef NO_AMANDA
 /*
@@ -132,22 +132,20 @@ static int rait_table_count;
  */
 
 static int
-amtable_alloc(void **table,
-             int *current,
-             size_t elsize,
-             int count,
-             int bump,
-             void *dummy) {
+amtable_alloc(
+    void **    table,
+    int *      current,
+    size_t     elsize,
+    int                count,
+    int                bump,
+    void *     dummy)
+{
     void *table_new;
     int table_count_new;
 
     if (count >= *current) {
        table_count_new = ((count + bump) / bump) * bump;
-       table_new = malloc(table_count_new * elsize);
-       if (0 == table_new) {
-           errno = ENOMEM;
-           return -1;
-       }
+       table_new = alloc(table_count_new * elsize);
        if (0 != *table) {
            memcpy(table_new, *table, *current * elsize);
            amfree(*table);
@@ -171,24 +169,28 @@ amtable_alloc(void **table,
  */
 
 void
-amtable_free(table, current)
-    void **table;
-    int *current;
+amtable_free(
+    void **    table,
+    int *      current)
 {
     amfree(*table);
     *current = 0;
 }
 #endif
 
-#define rait_table_alloc(fd)   amtable_alloc((void **)&rait_table,     \
-                                             &rait_table_count,        \
-                                             sizeof(*rait_table),      \
-                                             (fd),                     \
-                                             10,                       \
+#define rait_table_alloc(fd)   amtable_alloc((void **)rait_table_p,         \
+                                             &rait_table_count,             \
+                                             SIZEOF(*rait_table),   \
+                                             (size_t)(fd),                  \
+                                             10,                            \
                                              NULL)
 
 int
-rait_open(char *dev, int flags, int mask) {
+rait_open(
+    char *     dev,
+    int                flags,
+    mode_t     mask)
+{
     int fd;                    /* the file descriptor number to return */
     RAIT *res;                 /* resulting RAIT structure */
     char *dev_left;            /* string before { */
@@ -198,6 +200,8 @@ rait_open(char *dev, int flags, int mask) {
     int rait_flag;             /* true if RAIT syntax in dev */
     int save_errno;
     int r;
+    RAIT **rait_table_p = &rait_table;
+    int **fds_p;
 
     rait_debug((stderr,"rait_open( %s, %d, %d )\n", dev, flags, mask));
 
@@ -237,7 +241,7 @@ rait_open(char *dev, int flags, int mask) {
 
     res = &rait_table[fd];
 
-    memset(res, 0, sizeof(*res));
+    memset(res, 0, SIZEOF(*res));
     res->nopen = 1;
 
     res->fd_count = 0;
@@ -259,10 +263,11 @@ rait_open(char *dev, int flags, int mask) {
         }
 
        while (0 != (dev_real = tapeio_next_devname(dev_left, dev_right, &dev_next))) {
-           r = amtable_alloc((void **)&res->fds,
+            fds_p = &(res->fds);
+           r = amtable_alloc((void **)fds_p,
                            &res->fd_count,
-                           sizeof(*res->fds),
-                           res->nfds + 1,
+                           SIZEOF(*res->fds),
+                           (size_t)res->nfds + 1,
                            10,
                            NULL);
            if (0 != r) {
@@ -298,15 +303,16 @@ rait_open(char *dev, int flags, int mask) {
        */
 
        res->nfds = 0;
-       r = amtable_alloc((void **)&res->fds,
+        fds_p = &(res->fds);
+       r = amtable_alloc((void **)fds_p,
                          &res->fd_count,
-                         sizeof(*res->fds),
-                         res->nfds + 1,
+                         SIZEOF(*res->fds),
+                         (size_t)res->nfds + 1,
                          1,
                          NULL);
        if (0 != r) {
            (void)tapefd_close(fd);
-           memset(res, 0, sizeof(*res));
+           memset(res, 0, SIZEOF(*res));
            errno = ENOMEM;
            fd = -1;
        } else {
@@ -316,14 +322,8 @@ rait_open(char *dev, int flags, int mask) {
     }
 
     if (fd >= 0 && res->nfds > 0) {
-       res->readres = (int *) malloc(res->nfds * sizeof(*res->readres));
-       if (0 == res->readres) {
-           (void)rait_close(fd);
-           errno = ENOMEM;
-           fd = -1;
-       } else {
-           memset(res->readres, 0, res->nfds * sizeof(*res->readres));
-       }
+       res->readres = alloc(res->nfds * SIZEOF(*res->readres));
+       memset(res->readres, 0, res->nfds * SIZEOF(*res->readres));
     }
 
     rait_debug((stderr, "rait_open:returning %d%s%s\n",
@@ -336,10 +336,12 @@ rait_open(char *dev, int flags, int mask) {
 
 #ifdef NO_AMANDA
 int
-tapeio_init_devname(char * dev,
-                   char **dev_left,
-                   char **dev_right,
-                   char **dev_next) {
+tapeio_init_devname(
+    char *     dev,
+    char **    dev_left,
+    char **    dev_right,
+    char **    dev_next)
+{
     /*
     ** find the first { and then the first } that follows it
     */
@@ -359,9 +361,11 @@ tapeio_init_devname(char * dev,
 }
 
 char *
-tapeio_next_devname(char * dev_left,
-                   char * dev_right,
-                   char **dev_next) {
+tapeio_next_devname(
+    char *     dev_left,
+    char *     dev_right,
+    char **    dev_next)
+{
     char *dev_real = 0;
     char *next;
     int len;
@@ -369,19 +373,18 @@ tapeio_next_devname(char * dev_left,
     next = *dev_next;
     if (0 != (*dev_next = strchr(next, ','))
        || 0 != (*dev_next = strchr(next, '}'))){
-    
+
        **dev_next = 0;                         /* zap the terminator */
        (*dev_next)++;
 
-       /* 
+       /*
        ** we have one string picked out, build it into the buffer
        */
        len = strlen(dev_left) + strlen(next) + strlen(dev_right) + 1;
-       if ( 0 != (dev_real = malloc(len)) ) {
-           strcpy(dev_real, dev_left);         /* safe */
-           strcat(dev_real, next);             /* safe */
-           strcat(dev_real, dev_right);        /* safe */
-       }
+       dev_real = alloc(len);
+       strcpy(dev_real, dev_left);             /* safe */
+       strcat(dev_real, next);         /* safe */
+       strcat(dev_real, dev_right);    /* safe */
     }
     return dev_real;
 }
@@ -390,18 +393,21 @@ tapeio_next_devname(char * dev_left,
 /*
 ** close everything we opened and free our memory.
 */
-int 
-rait_close(int fd) {
+int
+rait_close(
+    int fd)
+{
     int i;                     /* index into RAIT drives */
     int j;                     /* individual tapefd_close result */
     int res;                   /* result from close */
     RAIT *pr;                  /* RAIT entry from table */
     int save_errno = errno;
-    int kid;
+    pid_t kid;
+    int **fds_p;
 
     rait_debug((stderr,"rait_close( %d )\n", fd));
 
-    if (fd < 0 || fd >= rait_table_count) {
+    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
        errno = EBADF;
        rait_debug((stderr, "rait_close:returning %d: %s\n",
                            -1,
@@ -419,19 +425,12 @@ rait_close(int fd) {
     }
 
     if (0 == pr->readres && 0 < pr->nfds) {
-       pr->readres = (int *) malloc(pr->nfds * sizeof(*pr->readres));
-       if (0 == pr->readres) {
-           errno = ENOMEM;
-           rait_debug((stderr, "rait_close:returning %d: %s\n",
-                               -1,
-                               strerror(errno)));
-           return -1;
-       }
-       memset(pr->readres, 0, pr->nfds * sizeof(*pr->readres));
+       pr->readres = alloc(pr->nfds * SIZEOF(*pr->readres));
+       memset(pr->readres, 0, pr->nfds * SIZEOF(*pr->readres));
     }
 
     res = 0;
-    /* 
+    /*
     ** this looks strange, but we start kids who are going to close the
     ** drives in parallel just after the parent has closed their copy of
     ** the descriptor. ('cause closing tape devices usually causes slow
@@ -446,7 +445,7 @@ rait_close(int fd) {
                exit(j);
             } else {
                /* remember who the child is or that an error happened */
-               pr->readres[i] = kid;
+               pr->readres[i] = (ssize_t)kid;
             }
        }
        else {
@@ -466,10 +465,10 @@ rait_close(int fd) {
     for( i = 0; i < pr->nfds; i++ ) {
         int stat;
        if(pr->readres[i] != -1) {
-           waitpid( pr->readres[i], &stat, 0);
+           waitpid((pid_t)pr->readres[i], &stat, 0);
            if( WEXITSTATUS(stat) != 0 ) {
                res = WEXITSTATUS(stat);
-               if( res == 255 ) 
+               if( res == 255 )
                    res = -1;
            }
         }
@@ -478,7 +477,8 @@ rait_close(int fd) {
        (void)close(fd);        /* close the dummy /dev/null descriptor */
     }
     if (0 != pr->fds) {
-       amtable_free((void **)&pr->fds, &pr->fd_count);
+        fds_p = &pr->fds;
+       amtable_free((void **)fds_p, &pr->fd_count);
     }
     if (0 != pr->readres) {
        amfree(pr->readres);
@@ -501,21 +501,26 @@ rait_close(int fd) {
 ** seek out to the nth byte on the RAIT set.
 ** this is assumed to be evenly divided across all the stripes
 */
-int 
-rait_lseek(int fd, long pos, int whence) {
+off_t
+rait_lseek(
+    int                fd,
+    off_t      pos,
+    int                whence)
+{
     int i;                     /* drive number in RAIT */
-    long res,                  /* result of lseeks */
+    off_t res,                         /* result of lseeks */
         total;                 /* total of results */
     RAIT *pr;                  /* RAIT slot in table */
 
-    rait_debug((stderr, "rait_lseek(%d,%ld,%d)\n",fd,pos,whence));
+    rait_debug((stderr, "rait_lseek(%d," OFF_T_FMT ",%d)\n",
+               fd, (OFF_T_FMT_TYPE)pos, whence));
 
-    if (fd < 0 || fd >= rait_table_count) {
+    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
        errno = EBADF;
        rait_debug((stderr, "rait_lseek:returning %d: %s\n",
                            -1,
                            strerror(errno)));
-       return -1;
+       return (off_t)-1;
     }
 
     pr = &rait_table[fd];
@@ -524,17 +529,17 @@ rait_lseek(int fd, long pos, int whence) {
        rait_debug((stderr, "rait_lseek:returning %d: %s\n",
                            -1,
                            strerror(errno)));
-       return -1;
+       return (off_t)-1;
     }
 
-    if (pr->nfds > 1 && (pos % (pr->nfds-1)) != 0) {
+    if ((pr->nfds > 1) && ((pos % (off_t)(pr->nfds-1)) != (off_t)0)) {
        errno = EDOM;
-       total = -1;
+       total = (off_t)-1;
     } else {
-       total = 0;
-       pos = pos / pr->nfds;
+       total = (off_t)0;
+       pos = pos / (off_t)pr->nfds;
        for( i = 0; i < pr->nfds; i++ ) {
-           if (0 >= (res = lseek(pr->fds[i], pos, whence))) {
+           if ((off_t)0 >= (res = lseek(pr->fds[i], pos, whence))) {
                total = res;
                break;
            }
@@ -551,21 +556,27 @@ rait_lseek(int fd, long pos, int whence) {
 /*\f*/
 
 /*
-** if we only have one stream, just do a write, 
+** if we only have one stream, just do a write,
 ** otherwise compute an xor sum, and do several
 ** writes...
 */
-ssize_t 
-rait_write(int fd, const void *bufptr, size_t len) {
+ssize_t
+rait_write(
+    int                fd,
+    const void *bufptr,
+    size_t     len)
+{
     const char *buf = bufptr;
-    int i = 0, j;      /* drive number, byte offset */
-    RAIT *pr;          /* RAIT structure for this RAIT */
-    int res, total = 0;
+    int i;     /* drive number */
+    size_t j;  /* byte offset */
+    RAIT *pr;  /* RAIT structure for this RAIT */
+    ssize_t res;
+    ssize_t total = 0;
     int data_fds;      /* number of data stream file descriptors */
 
     rait_debug((stderr, "rait_write(%d,%lx,%d)\n",fd,(unsigned long)buf,len));
 
-    if (fd < 0 || fd >= rait_table_count) {
+    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
        errno = EBADF;
        rait_debug((stderr, "rait_write:returning %d: %s\n",
                            -1,
@@ -596,18 +607,11 @@ rait_write(int fd, const void *bufptr, size_t len) {
        len = len / data_fds;
 
        /* make sure we have enough buffer space */
-       if (len > pr->xorbuflen) {
+       if (len > (size_t)pr->xorbuflen) {
            if (0 != pr->xorbuf) {
                amfree(pr->xorbuf);
            }
-           pr->xorbuf = malloc(len);
-           if (0 == pr->xorbuf) {
-               errno = ENOMEM;
-               rait_debug((stderr, "rait_write:returning %d: %s\n",
-                                   -1,
-                                   strerror(errno)));
-               return -1;
-           }
+           pr->xorbuf = alloc(len);
            pr->xorbuflen = len;
        }
 
@@ -623,22 +627,20 @@ rait_write(int fd, const void *bufptr, size_t len) {
     }
 
     /* write the chunks in the main buffer */
-    if (total >= 0) {
-       for( i = 0; i < data_fds; i++ ) {
-           res = tapefd_write(pr->fds[i], buf + len*i , len);
-           rait_debug((stderr, "rait_write: write(%d,%lx,%d) returns %d%s%s\n",
+    for( i = 0; i < data_fds; i++ ) {
+       res = tapefd_write(pr->fds[i], buf + len*i , len);
+       rait_debug((stderr, "rait_write: write(%d,%lx,%d) returns %d%s%s\n",
                        pr->fds[i],
                        (unsigned long)(buf + len*i),
                        len,
                        res,
                        (res < 0) ? ": " : "",
                        (res < 0) ? strerror(errno) : ""));
-           if (res < 0) {
-               total = res;
-               break;
-           }
-           total += res;
+       if (res < 0) {
+           total = res;
+           break;
        }
+       total += res;
     }
     if (total >= 0 && pr->nfds > 1) {
         /* write the sum, don't include it in the total bytes written */
@@ -671,26 +673,29 @@ rait_write(int fd, const void *bufptr, size_t len) {
 ** the missing block from the other three, then return the data.
 ** there's some silliness here for reading tape with bigger buffers
 ** than we wrote with, (thus the extra bcopys down below).  On disk if
-** you read with a bigger buffer size than you wrote with, you just 
+** you read with a bigger buffer size than you wrote with, you just
 ** garble the data...
 */
-ssize_t 
-rait_read(int fd, void *bufptr, size_t len) {
+ssize_t
+rait_read(
+    int                fd,
+    void *     bufptr,
+    size_t     len)
+{
     char *buf = bufptr;
-    int nerrors, 
-        neofs, 
-        total, 
-        errorblock;
-    int i,j;
+    int nerrors, neofs, errorblock;
+    ssize_t    total;
+    int i;
+    size_t j;
     RAIT *pr;
     int data_fds;
     int save_errno = errno;
-    int maxreadres = 0;
+    ssize_t maxreadres = 0;
     int sum_mismatch = 0;
 
     rait_debug((stderr, "rait_read(%d,%lx,%d)\n",fd,(unsigned long)buf,len));
 
-    if (fd < 0 || fd >= rait_table_count) {
+    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
        errno = EBADF;
        rait_debug((stderr, "rait_read:returning %d: %s\n",
                            -1,
@@ -709,7 +714,6 @@ rait_read(int fd, void *bufptr, size_t len) {
 
     nerrors = 0;
     neofs = 0;
-    total = 0;
     errorblock = -1;
     /* once again , we slice it evenly... */
     if (pr->nfds > 1) {
@@ -751,18 +755,11 @@ rait_read(int fd, void *bufptr, size_t len) {
     }
     if (pr->nfds > 1) {
        /* make sure we have enough buffer space */
-       if (len > pr->xorbuflen) {
+       if (len > (size_t)pr->xorbuflen) {
            if (0 != pr->xorbuf) {
                amfree(pr->xorbuf);
            }
-           pr->xorbuf = malloc(len);
-           if (0 == pr->xorbuf) {
-               errno = ENOMEM;
-               rait_debug((stderr, "rait_write:returning %d: %s\n",
-                                   -1,
-                                   strerror(errno)));
-               return -1;
-           }
+           pr->xorbuf = alloc(len);
            pr->xorbuflen = len;
        }
        pr->readres[i] = tapefd_read(pr->fds[i], pr->xorbuf , len);
@@ -776,10 +773,10 @@ rait_read(int fd, void *bufptr, size_t len) {
     /*
      * Make sure all the reads were the same length
      */
-    for (j = 0; j < pr->nfds; j++) {
+    for (j = 0; j < (size_t)pr->nfds; j++) {
        if (pr->readres[j] != maxreadres) {
            nerrors++;
-           errorblock = j;
+           errorblock = (int)j;
        }
     }
 
@@ -787,9 +784,9 @@ rait_read(int fd, void *bufptr, size_t len) {
      * If no errors, check that the xor sum matches
      */
     if ( nerrors == 0 && pr->nfds > 1  ) {
-       for(i = 0; i < maxreadres; i++ ) {
+       for(i = 0; i < (int)maxreadres; i++ ) {
           int sum = 0;
-          for(j = 0; j < pr->nfds - 1; j++) {
+          for(j = 0; (j + 1) < (size_t)pr->nfds; j++) {
               sum ^= (buf + len * j)[i];
            }
           if (sum != pr->xorbuf[i]) {
@@ -798,7 +795,7 @@ rait_read(int fd, void *bufptr, size_t len) {
        }
     }
 
-    /* 
+    /*
     ** now decide what "really" happened --
     ** all n getting eof is a "real" eof
     ** just one getting an error/eof is recoverable if we are doing RAIT
@@ -855,8 +852,8 @@ rait_read(int fd, void *bufptr, size_t len) {
     /* pack together partial reads... */
     total = pr->readres[0];
     for( i = 1; i < data_fds; i++ ) {
-       if (total != len * i) {
-           memmove(buf + total, buf + len*i, pr->readres[i]);
+       if (total != (ssize_t)(len * i)) {
+           memmove(buf + total, buf + len*i, (size_t)pr->readres[i]);
         }
        total += pr->readres[i];
     }
@@ -871,14 +868,19 @@ rait_read(int fd, void *bufptr, size_t len) {
 
 /*\f*/
 
-int rait_ioctl(int fd, int op, void *p) {
+int
+rait_ioctl(
+    int                fd,
+    int                op,
+    void *     p)
+{
     int i, res = 0;
     RAIT *pr;
     int errors = 0;
 
     rait_debug((stderr, "rait_ioctl(%d,%d)\n",fd,op));
 
-    if (fd < 0 || fd >= rait_table_count) {
+    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
        errno = EBADF;
        rait_debug((stderr, "rait_ioctl:returning %d: %s\n",
                            -1,
@@ -896,8 +898,10 @@ int rait_ioctl(int fd, int op, void *p) {
     }
 
     for( i = 0; i < pr->nfds ; i++ ) {
+       /*@ignore@*/
        res = ioctl(pr->fds[i], op, p);
-       if ( res != 0 ) { 
+       /*@end@*/
+       if ( res != 0 ) {
            errors++;
            if (errors > 1) {
                break;
@@ -917,7 +921,11 @@ int rait_ioctl(int fd, int op, void *p) {
 /*
 ** access() all the devices, returning if any fail
 */
-int rait_access(char *devname, int flags) {
+int
+rait_access(
+    char *     devname,
+    int                flags)
+{
     int res = 0;
     char *dev_left;            /* string before { */
     char *dev_right;           /* string after } */
@@ -944,7 +952,7 @@ int rait_access(char *devname, int flags) {
        rait_debug((stderr,"rait_access:access( %s, %d ) yields %d\n",
                dev_real, flags, res ));
        amfree(dev_real);
-       if (res < 0) { 
+       if (res < 0) {
            break;
         }
     }
@@ -961,7 +969,11 @@ int rait_access(char *devname, int flags) {
 /*
 ** stat all the devices, returning the last one unless one fails
 */
-int rait_stat(char *devname, struct stat *buf) {
+int
+rait_stat(
+    char *      devname,
+    struct stat *buf)
+{
     int res = 0;
     char *dev_left;            /* string before { */
     char *dev_right;           /* string after } */
@@ -988,7 +1000,7 @@ int rait_stat(char *devname, struct stat *buf) {
        rait_debug((stderr,"rait_stat:stat( %s ) yields %d (%s)\n",
                dev_real, res, (res != 0) ? strerror(errno) : "no error" ));
        amfree(dev_real);
-       if (res != 0) { 
+       if (res != 0) {
            break;
         }
     }
@@ -1004,9 +1016,15 @@ int rait_stat(char *devname, struct stat *buf) {
 
 /*\f*/
 
-int rait_copy(char *f1, char *f2, int buflen) {
+int
+rait_copy(
+    char *     f1,
+    char *     f2,
+    size_t     buflen)
+{
     int t1, t2;
-    int len, wres;
+    ssize_t len;
+    ssize_t wres;
     char *buf;
     int save_errno;
 
@@ -1021,17 +1039,11 @@ int rait_copy(char *f1, char *f2, int buflen) {
        errno = save_errno;
        return -1;
     }
-    buf = malloc(buflen);
-    if (0 == buf) {
-       (void)rait_close(t1);
-       (void)rait_close(t2);
-       errno = ENOMEM;
-       return -1;
-    }
+    buf = alloc(buflen);
     do {
        len = rait_read(t1,buf,buflen);
        if (len > 0 ) {
-           wres = rait_write(t2, buf, len);
+           wres = rait_write(t2, buf, (size_t)len);
            if (wres < 0) {
                len = -1;
                break;
@@ -1052,19 +1064,22 @@ int rait_copy(char *f1, char *f2, int buflen) {
 ** Amanda Tape API routines:
 */
 
-static int rait_tapefd_ioctl(int (*func0)(int),
-                            int (*func1)(int, int),
-                            int fd,
-                            int count) {
+static int
+rait_tapefd_ioctl(
+    int                (*func0)(int),
+    int                (*func1)(int, off_t),
+    int                fd,
+    off_t      count)
+{
     int i, j, res = 0;
     RAIT *pr;
     int errors = 0;
-    int kid;
-    int stat;
+    pid_t kid;
+    int status = 0;
 
     rait_debug((stderr, "rait_tapefd_ioctl(%d,%d)\n",fd,count));
 
-    if (fd < 0 || fd >= rait_table_count) {
+    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
        errno = EBADF;
        rait_debug((stderr, "rait_tapefd_ioctl:returning %d: %s\n",
                            -1,
@@ -1082,15 +1097,8 @@ static int rait_tapefd_ioctl(int (*func0)(int),
     }
 
     if (0 == pr->readres && 0 < pr->nfds) {
-       pr->readres = (int *) malloc(pr->nfds * sizeof(*pr->readres));
-       if (0 == pr->readres) {
-           errno = ENOMEM;
-           rait_debug((stderr, "rait_tapefd_ioctl:returning %d: %s\n",
-                               -1,
-                               strerror(errno)));
-           return -1;
-       }
-       memset(pr->readres, 0, pr->nfds * sizeof(*pr->readres));
+       pr->readres = alloc(pr->nfds * SIZEOF(*pr->readres));
+       memset(pr->readres, 0, pr->nfds * SIZEOF(*pr->readres));
     }
 
     for( i = 0; i < pr->nfds ; i++ ) {
@@ -1098,21 +1106,22 @@ static int rait_tapefd_ioctl(int (*func0)(int),
             if ((kid = fork()) < 1) {
                rait_debug((stderr, "in kid, fork returned %d\n", kid));
                /* if we are the kid, or fork failed do the action */
-               if (0 != func0) {
+               if (func0 != NULL) {
                    res = (*func0)(pr->fds[i]);
                } else {
                    res = (*func1)(pr->fds[i], count);
                }
-               rait_debug((stderr, "in kid, func ( %d ) returned %d errno %d\n", pr->fds[i], res, errno));
+               rait_debug((stderr, "in kid, func (%d) returned %d errno %s\n",
+                               pr->fds[i], res, strerror(errno)));
                if (kid == 0)
                    exit(res);
             } else {
                rait_debug((stderr, "in parent, fork returned %d\n", kid));
-               pr->readres[i] = kid;
+               pr->readres[i] = (ssize_t)kid;
             }
        }
        else {
-           if(0 != func0) {
+           if(func0 != NULL) {
                j = (*func0)(pr->fds[i]);
            } else {
                j = (*func1)(pr->fds[i], count);
@@ -1126,14 +1135,14 @@ static int rait_tapefd_ioctl(int (*func0)(int),
     for( i = 0; i < pr->nfds ; i++ ) {
        if(tapefd_can_fork(pr->fds[i])) {
             rait_debug((stderr, "in parent, waiting for %d\n", pr->readres[i]));
-           waitpid( pr->readres[i], &stat, 0);
-           if( WEXITSTATUS(stat) != 0 ) {
-               res = WEXITSTATUS(stat);
-               if( res == 255 ) 
+           waitpid((pid_t)pr->readres[i], &status, 0);
+           if( WEXITSTATUS(status) != 0 ) {
+               res = WEXITSTATUS(status);
+               if( res == 255 )
                    res = -1;
             }
             rait_debug((stderr, "in parent, return code was %d\n", res));
-           if ( res != 0 ) { 
+           if ( res != 0 ) {
                errors++;
                res = 0;
            }
@@ -1151,27 +1160,50 @@ static int rait_tapefd_ioctl(int (*func0)(int),
     return res;
 }
 
-int rait_tapefd_fsf(int fd, int count) {
-    return rait_tapefd_ioctl(0, tapefd_fsf, fd, count);
+int
+rait_tapefd_fsf(
+    int                fd,
+    off_t      count)
+{
+    return rait_tapefd_ioctl(NULL, tapefd_fsf, fd, count);
 }
 
-int rait_tapefd_rewind(int fd) {
-    return rait_tapefd_ioctl(tapefd_rewind, 0, fd, -1);
+int
+rait_tapefd_rewind(
+    int                fd)
+{
+    return rait_tapefd_ioctl(tapefd_rewind, NULL, fd, (off_t)-1);
 }
 
-int rait_tapefd_unload(int fd) {
-    return rait_tapefd_ioctl(tapefd_unload, 0, fd, -1);
+int
+rait_tapefd_unload(
+    int                fd)
+{
+    return rait_tapefd_ioctl(tapefd_unload, NULL, fd, (off_t)-1);
 }
 
-int rait_tapefd_weof(int fd, int count) {
-    return rait_tapefd_ioctl(0, tapefd_weof, fd, count);
+int
+rait_tapefd_weof(
+    int                fd,
+    off_t      count)
+{
+    return rait_tapefd_ioctl(NULL, tapefd_weof, fd, count);
 }
 
-int rait_tape_open(char *name, int flags, int mask) {
+int
+rait_tape_open(
+    char *     name,
+    int                flags,
+    mode_t     mask)
+{
     return rait_open(name, flags, mask);
 }
 
-int rait_tapefd_status(int fd, struct am_mt_status *stat) {
+int
+rait_tapefd_status(
+    int                         fd,
+    struct am_mt_status *stat)
+{
     int i;
     RAIT *pr;
     int res = 0;
@@ -1179,7 +1211,7 @@ int rait_tapefd_status(int fd, struct am_mt_status *stat) {
 
     rait_debug((stderr, "rait_tapefd_status(%d)\n",fd));
 
-    if (fd < 0 || fd >= rait_table_count) {
+    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
        errno = EBADF;
        rait_debug((stderr, "rait_tapefd_status:returning %d: %s\n",
                            -1,
@@ -1208,14 +1240,19 @@ int rait_tapefd_status(int fd, struct am_mt_status *stat) {
     return res;
 }
 
-void rait_tapefd_resetofs(int fd) {
-    rait_lseek(fd,  0L, SEEK_SET);
+void
+rait_tapefd_resetofs(
+    int                fd)
+{
+    (void)rait_lseek(fd, (off_t)0, SEEK_SET);
 }
 
-int 
-rait_tapefd_can_fork(fd)
-    int fd;
+int
+rait_tapefd_can_fork(
+    int                fd)
 {
+    (void)fd;  /* Quiet unused parameter warning */
+
     return 0;
 }
 
index 09d890c62312d94773ab730cc970fb67f8f8bb27..21a573a80fa637ffadbf94b0d7725ba95a55bf73 100644 (file)
@@ -5,17 +5,16 @@
 typedef struct {
     int nopen;
     int nfds;
-    int fd_count;
+    size_t fd_count;
     int *fds;
-    int *readres;
-    int xorbuflen;
+    ssize_t *readres;
+    size_t xorbuflen;
     char *xorbuf;
 } RAIT;
 
 #ifdef NO_AMANDA
 
 #define stralloc strdup
-#define P(x)   x                       /* for function prototypes */
 
 /*
  * Tape drive status structure.  This abstracts the things we are
@@ -39,8 +38,8 @@ struct am_mt_status {
     char eot;                          /* true if tape is at end of medium */
     char protected;                    /* true if tape is write protected */
     long flags;                                /* device flags, whatever that is */
-    long fileno;                       /* tape file number */
-    long blkno;                                /* block within file */
+    off_t fileno;                      /* tape file number */
+    off_t blkno;                       /* block within file */
     int device_status_size;            /* size of orig device status field */
     unsigned long device_status;       /* "device status", whatever that is */
     int error_status_size;             /* size of orig error status field */
@@ -48,33 +47,25 @@ struct am_mt_status {
 };
 #endif
 
-extern int rait_open ();
-extern int rait_access P((char *, int));
-extern int rait_stat P((char *, struct stat *));
-extern int rait_close P((int ));
-extern int rait_lseek P((int , long, int));
-extern ssize_t rait_write P((int , const void *, size_t));
-extern ssize_t rait_read P((int , void *, size_t));
-extern int rait_ioctl P((int , int, void *));
-extern int rait_copy P((char *f1, char *f2, int buflen));
-
-extern char *rait_init_namelist P((char * dev,
-                                  char **dev_left,
-                                  char **dev_right,
-                                  char **dev_next));
-extern int rait_next_name P((char * dev_left,
-                                    char * dev_right,
-                                    char **dev_next,
-                                    char * dev_real));
-
-extern int  rait_tape_open ();
-extern int  rait_tapefd_fsf P((int rait_tapefd, int count));
-extern int  rait_tapefd_rewind P((int rait_tapefd));
-extern void rait_tapefd_resetofs P((int rait_tapefd));
-extern int  rait_tapefd_unload P((int rait_tapefd));
-extern int  rait_tapefd_status P((int rait_tapefd, struct am_mt_status *stat));
-extern int  rait_tapefd_weof P((int rait_tapefd, int count));
-extern int  rait_tapefd_can_fork P((int));
+int rait_open(char *dev, int flags, mode_t mask);
+int rait_access(char *, int);
+int rait_stat(char *, struct stat *);
+int rait_close(int);
+off_t rait_lseek(int, off_t, int);
+ssize_t rait_write(int, const void *, size_t);
+ssize_t rait_read(int, void *, size_t);
+int rait_ioctl(int, int, void *);
+int rait_copy(char *f1, char *f2, size_t buflen);
+char *rait_init_namelist(char * dev, char **dev_left, char **dev_right, char **dev_next);
+int rait_next_name(char * dev_left, char * dev_right, char **dev_next, char * dev_real);
+int  rait_tape_open(char *, int, mode_t);
+int  rait_tapefd_fsf(int rait_tapefd, off_t count);
+int  rait_tapefd_rewind(int rait_tapefd);
+void rait_tapefd_resetofs(int rait_tapefd);
+int  rait_tapefd_unload(int rait_tapefd);
+int  rait_tapefd_status(int rait_tapefd, struct am_mt_status *stat);
+int  rait_tapefd_weof(int rait_tapefd, off_t count);
+int  rait_tapefd_can_fork(int);
 
 #ifdef RAIT_REDIRECT
 
index c08aa03ab5e20c4070743ea1f1ac767d35f0b585..a344ac31a2e0f11b7ae7b9cc6264325c58c27cee 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 /*
- * $Id: output-tape.c,v 1.14 2006/03/09 20:06:12 johnfranks Exp $
+ * $Id: output-tape.c,v 1.18 2006/08/22 14:19:39 martinea Exp $
  *
  * tapeio.c virtual tape interface for normal tape drives.
  */
@@ -72,9 +72,9 @@
  */
 
 int
-tape_tapefd_fsf(fd, count)
-    int fd;
-    int count;
+tape_tapefd_fsf(
+    int fd,
+    off_t count)
 {
     size_t buflen;
     char *buffer = NULL;
@@ -102,8 +102,8 @@ tape_tapefd_fsf(fd, count)
  * Rewind a tape to the beginning.
  */
 int
-tape_tapefd_rewind(fd)
-    int fd;
+tape_tapefd_rewind(
+    int fd)
 {
     int st;
 
@@ -114,8 +114,8 @@ tape_tapefd_rewind(fd)
  * Rewind and unload a tape.
  */
 int
-tape_tapefd_unload(fd)
-    int fd;
+tape_tapefd_unload(
+    int fd)
 {
     int st;
 
@@ -126,8 +126,10 @@ tape_tapefd_unload(fd)
 /*
  * Forward space the tape device count files.
  */
-int tape_tapefd_fsf(fd, count)
-    int fd, count;
+int
+tape_tapefd_fsf(
+    int fd,
+    off_t count)
 {
     int st;
     int status;
@@ -146,13 +148,14 @@ int tape_tapefd_fsf(fd, count)
  * Write some number of end of file marks (a.k.a. tape marks).
  */
 int
-tape_tapefd_weof(fd, count)
-    int fd, count;
+tape_tapefd_weof(
+    int fd,
+    off_t count)
 {
     int st;
     int status;
 
-    while (--count >= 0) {
+    while (--count >= (off_t)0) {
         if ((status = ioctl(fd, T_WRFILEM, &st)) != 0) {
             break;
        }
@@ -170,8 +173,8 @@ tape_tapefd_weof(fd, count)
  * Rewind a tape to the beginning.
  */
 int
-tape_tapefd_rewind(fd)
-    int fd;
+tape_tapefd_rewind(
+    int fd)
 {
     struct stop st;
 
@@ -185,8 +188,8 @@ tape_tapefd_rewind(fd)
  * Rewind and unload a tape.
  */
 int
-tape_tapefd_unload(fd)
-    int fd;
+tape_tapefd_unload(
+    int fd)
 {
     struct stop st;
 
@@ -201,13 +204,23 @@ tape_tapefd_unload(fd)
  * Forward space the tape device count files.
  */
 int
-tape_tapefd_fsf(fd, count)
-    int fd, count;
+tape_tapefd_fsf(
+    int fd,
+    off_t count)
 {
     struct stop st;
 
+    if ((count > (off_t)INT_MAX) || (count < (off_t)INT_MIN)) {
+#ifdef EOVERFLOW
+           errno = EOVERFLOW;
+#else
+           errno = EINVAL;
+#endif
+       return -1;
+    }
+
     st.st_op = STFSF;
-    st.st_count = count;
+    st.st_count = (int)count;
 
     return ioctl(fd, STIOCTOP, &st);
 }
@@ -217,13 +230,23 @@ tape_tapefd_fsf(fd, count)
  * Write some number of end of file marks (a.k.a. tape marks).
  */
 int
-tape_tapefd_weof(fd, count)
-    int fd, count;
+tape_tapefd_weof(
+    int fd,
+    off_t count)
 {
     struct stop st;
 
+    if ((count > (off_t)INT_MAX) || (count < (off_t)INT_MIN)) {
+#ifdef EOVERFLOW
+           errno = EOVERFLOW;
+#else
+           errno = EINVAL;
+#endif
+       return -1;
+    }
+
     st.st_op = STWEOF;
-    st.st_count = count;
+    st.st_count = (int)count;
 
     return ioctl(fd, STIOCTOP, &st);
 }
@@ -237,8 +260,8 @@ tape_tapefd_weof(fd, count)
  * Rewind a tape to the beginning.
  */
 int
-tape_tapefd_rewind(fd)
-    int fd;
+tape_tapefd_rewind(
+    int fd)
 {
     int st;
 
@@ -249,8 +272,8 @@ tape_tapefd_rewind(fd)
  * Rewind and unload a tape.
  */
 int
-tape_tapefd_unload(fd)
-    int fd;
+tape_tapefd_unload(
+    int fd)
 {
     int st;
     int f;
@@ -272,8 +295,9 @@ tape_tapefd_unload(fd)
  * Forward space the tape device count files.
  */
 int
-tape_tapefd_fsf(fd, count)
-    int fd, count;
+tape_tapefd_fsf(
+    int fd,
+    off_t count)
 {
     int st;
     int status;
@@ -292,8 +316,9 @@ tape_tapefd_fsf(fd, count)
  * Write some number of end of file marks (a.k.a. tape marks).
  */
 int
-tape_tapefd_weof(fd, count)
-    int fd, count;
+tape_tapefd_weof(
+    int fd,
+    off_t count)
 {
     int st;
     int c;
@@ -316,8 +341,8 @@ tape_tapefd_weof(fd, count)
  * Rewind a tape to the beginning.
  */
 int
-tape_tapefd_rewind(fd)
-    int fd;
+tape_tapefd_rewind(
+    int fd)
 {
     struct mtop mt;
     int rc=-1, cnt;
@@ -344,8 +369,8 @@ tape_tapefd_rewind(fd)
  * Rewind and unload a tape.
  */
 int
-tape_tapefd_unload(fd)
-    int fd;
+tape_tapefd_unload(
+    int fd)
 {
     struct mtop mt;
     int rc=-1, cnt;
@@ -381,13 +406,23 @@ tape_tapefd_unload(fd)
  * Forward space the tape device count files.
  */
 int
-tape_tapefd_fsf(fd, count)
-    int fd, count;
+tape_tapefd_fsf(
+    int fd,
+    off_t count)
 {
     struct mtop mt;
 
+    if ((count > (off_t)INT_MAX) || (count < (off_t)INT_MIN)) {
+#ifdef EOVERFLOW
+           errno = EOVERFLOW;
+#else
+           errno = EINVAL;
+#endif
+       return -1;
+    }
+
     mt.mt_op = MTFSF;
-    mt.mt_count = count;
+    mt.mt_count = (int)count;
 
     return ioctl(fd, MTIOCTOP, &mt);
 }
@@ -395,17 +430,27 @@ tape_tapefd_fsf(fd, count)
 
 /*
  * Write some number of end of file marks (a.k.a. tape marks).
- */
-int tape_tapefd_weof(fd, count)
-int fd, count;
-/*
+ *
  * write <count> filemarks on the tape.
  */
+int
+tape_tapefd_weof(
+    int fd,
+    off_t count)
 {
     struct mtop mt;
 
+    if ((count > (off_t)INT_MAX) || (count < (off_t)INT_MIN)) {
+#ifdef EOVERFLOW
+           errno = EOVERFLOW;
+#else
+           errno = EINVAL;
+#endif
+       return -1;
+    }
+
     mt.mt_op = MTWEOF;
-    mt.mt_count = count;
+    mt.mt_count = (int)count;
 
     return ioctl(fd, MTIOCTOP, &mt);
 }
@@ -424,8 +469,8 @@ int fd, count;
  * is_zftape(filename) checks if filename is a valid ftape device name.
  */
 int
-is_zftape(filename)
-    const char *filename;
+is_zftape(
+    const char *filename)
 {
     if (strncmp(filename, "/dev/nftape", 11) == 0) return(1);
     if (strncmp(filename, "/dev/nqft",    9) == 0) return(1);
@@ -434,51 +479,80 @@ is_zftape(filename)
 }
 #endif /* HAVE_LINUX_ZFTAPE_H */
 
-int tape_tape_open(filename, flags, mask)
-    char *filename;
-    int flags;
-    int mask;
+int
+tape_tape_open(
+    char *filename,
+    int flags,
+    mode_t mask)
 {
-    int ret = 0, delay = 2, timeout = 200;
+    int ret;
+    time_t timeout = 200;
+    unsigned delay = 2;
 
     if ((flags & 3) != O_RDONLY) {
        flags &= ~3;
        flags |= O_RDWR;
     }
-    while (1) {
-       ret = open(filename, flags, mask);
-       /* if tape open fails with errno==EAGAIN, EBUSY or EINTR, it
-        * is worth retrying a few seconds later.  */
-       if (ret >= 0 ||
-           (1
-#ifdef EAGAIN
-            && errno != EAGAIN
-#endif
-#ifdef EBUSY
-            && errno != EBUSY
-#endif
-#ifdef EINTR
-            && errno != EINTR
-#endif
-            )) {
-           break;
+    ret = open(filename, flags, mask);
+    while (ret < 0) {
+       if ((errno != EAGAIN) && (errno != EBUSY) && (errno != EINTR)) {
+           /*
+            * Open failed completely: just return
+            */
+           fprintf(stderr, "Opening tapedev %s: got error %s.\n",
+                       filename, strerror(errno));
+           return -1;
        }
+
+       /*
+        * if tape open fails with errno==EAGAIN, EBUSY or EINTR, it
+        * may be worth retrying a few seconds later.
+        */
        timeout -= delay;
        if (timeout <= 0) {
-           break;
+           /* Open failed: just return */
+           fprintf(stderr, "Opening tapedev %s: not ready.\n", filename);
+           return -1;
        }
-       if (delay < 16) {
+
+       if (delay < 16)
            delay *= 2;
-       }
+
        sleep(delay);
+       ret = open(filename, flags, mask);
     }
+
+#ifdef MTIOCGET
+    /* Now check that we opened a tape device. */
+    {
+       struct mtget mt;
+
+       memset(&mt, 0, SIZEOF(mt));
+       if (ioctl(ret, MTIOCGET, &mt) < 0) {
+           close(ret);
+           fprintf(stderr, "tapedev %s is not a tape device!\n", filename);
+           return -1;
+       }
+
+#ifdef GMT_ONLINE
+       if (!GMT_ONLINE(mt.mt_gstat)) {
+           close(ret);
+           fprintf(stderr, "tapedev %s is offline or has no loaded tape.\n",
+                   filename);
+           return -1;
+       }
+#endif /* GMT_ONLINE */
+    }
+#endif /* MTIOCGET */
+
+
 #ifdef HAVE_LINUX_ZFTAPE_H
     /*
      * switch the block size for the zftape driver (3.04d)
      * (its default is 10kb and not 32kb)
      *        A. Gebhardt <albrecht.gebhardt@uni-klu.ac.at>
      */
-    if (ret >= 0 && is_zftape(filename) == 1) {
+    if (is_zftape(filename) == 1) {
        struct mtop mt;
 
        mt.mt_op = MTSETBLK;
@@ -489,56 +563,63 @@ int tape_tape_open(filename, flags, mask)
     return ret;
 }
 
-ssize_t tape_tapefd_read(fd, buffer, count)
-    int fd;
-    void *buffer;
-    size_t count;
+ssize_t
+tape_tapefd_read(
+    int fd,
+    void *buffer,
+    size_t count)
 {
     return read(fd, buffer, count);
 }
 
-ssize_t tape_tapefd_write(fd, buffer, count)
-    int fd;
-    const void *buffer;
-    size_t count;
+ssize_t
+tape_tapefd_write(
+    int fd,
+    const void *buffer,
+    size_t count)
 {
     return write(fd, buffer, count);
 }
 
-int tape_tapefd_close(fd)
-    int fd;
+int
+tape_tapefd_close(
+    int fd)
 {
     return close(fd);
-}
+} 
 
-void tape_tapefd_resetofs(fd)
-    int fd;
+void
+tape_tapefd_resetofs(
+    int fd)
 {
     /*
      * this *should* be a no-op on the tape, but resets the kernel's view
      * of the file offset, preventing it from barfing should we pass the
      * filesize limit (eg OSes with 2 GB filesize limits) on a long tape.
      */
-    lseek(fd, (off_t) 0L, SEEK_SET);
+    if (lseek(fd, (off_t)0, SEEK_SET) < 0) {
+       dbprintf(("tape_tapefd_resetofs: lseek failed: <%s>\n",
+                 strerror(errno)));
+    }
 }
 
 int
-tape_tapefd_status(fd, stat)
-    int fd;
-    struct am_mt_status *stat;
+tape_tapefd_status(
+    int fd,
+    struct am_mt_status *stat)
 {
-    int res = 0;
+    int res;
     int anything_valid = 0;
 #if defined(MTIOCGET)
     struct mtget buf;
 #endif
 
-    memset((void *)stat, 0, sizeof(*stat));
+    memset((void *)stat, 0, SIZEOF(*stat));
 
 #if defined(MTIOCGET)                                                  /* { */
     res = ioctl(fd,MTIOCGET,&buf);
-
     if (res >= 0) {
+       /*@ignore@*/
 #ifdef MT_ONL                                                          /* { */
         /* IRIX-ish system */
        anything_valid = 1;
@@ -579,12 +660,12 @@ tape_tapefd_status(fd, stat)
        stat->online = 1;                       /* ioctl fails otherwise */
 #ifdef HAVE_MT_DSREG
        stat->device_status_valid = 1;
-       stat->device_status_size = sizeof(buf.mt_dsreg);
+       stat->device_status_size = SIZEOF(buf.mt_dsreg);
        stat->device_status = (unsigned long)buf.mt_dsreg;
 #endif
 #ifdef HAVE_MT_ERREG
        stat->error_status_valid = 1;
-       stat->error_status_size = sizeof(buf.mt_erreg);
+       stat->error_status_size = SIZEOF(buf.mt_erreg);
        stat->error_status = (unsigned long)buf.mt_erreg;
 #endif
 #if defined(HAVE_MT_FLAGS) && defined(MTF_SCSI)                        /* { */
@@ -608,6 +689,7 @@ tape_tapefd_status(fd, stat)
 #endif                                                                 /* } */
 #endif                                                                 /* } */
 #endif                                                                 /* } */
+       /*@end@*/
     }
 #endif                                                                 /* } */
 
@@ -620,30 +702,34 @@ tape_tapefd_status(fd, stat)
 
        res = fstat(fd, &sbuf);
        stat->online_valid = 1;
-       stat->online = (res == 0);
+       stat->online = (char)(res == 0);
     }
 
     return res;
 }
 
-int tape_tape_stat(filename, buf)
-     char *filename;
-     struct stat *buf;
+int
+tape_tape_stat(
+     char *filename,
+     struct stat *buf)
 {
      return stat(filename, buf);
 }
 
-int tape_tape_access(filename, mode)
-     char *filename;
-     int mode;
+int
+tape_tape_access(
+     char *filename,
+     int mode)
 {
      return access(filename, mode);
 }
 
 int 
-tape_tapefd_can_fork(fd)
-    int fd;
+tape_tapefd_can_fork(
+    int fd)
 {
+    (void)fd;  /* Quiet unused parameter warning */
+
     return 1;
 }
 
index 7c43169c41c6b7deb01f70f661d096c1b353e276..3707c0f3cade1f94f41698c28ceed93e5598f00c 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 /*
- * $Id: output-tape.h,v 1.5 2003/03/06 21:43:58 martinea Exp $
+ * $Id: output-tape.h,v 1.6 2006/05/25 01:47:27 johnfranks Exp $
  *
  * tapeio.c virtual tape interface for normal tape drives.
  */
 #include "amanda.h"
 #endif
 
-extern int tape_tape_access P((char *, int));
-extern int tape_tape_open ();
-extern int tape_tape_stat P((char *, struct stat *));
-extern int tape_tapefd_close P((int));
-extern int tape_tapefd_fsf P((int, int));
-extern ssize_t tape_tapefd_read P((int, void *, size_t));
-extern int tape_tapefd_rewind P((int));
-extern void tape_tapefd_resetofs P((int));
-extern int tape_tapefd_unload P((int));
-extern int tape_tapefd_status P((int, struct am_mt_status *));
-extern int tape_tapefd_weof P((int, int));
-extern ssize_t tape_tapefd_write P((int, const void *, size_t));
-extern int tape_tapefd_can_fork P((int));
+int tape_tape_access(char *, int);
+int tape_tape_open(char *, int, mode_t);
+int tape_tape_stat(char *, struct stat *);
+int tape_tapefd_close(int);
+int tape_tapefd_fsf(int, off_t);
+ssize_t tape_tapefd_read(int, void *, size_t);
+int tape_tapefd_rewind(int);
+void tape_tapefd_resetofs(int);
+int tape_tapefd_unload(int);
+int tape_tapefd_status(int, struct am_mt_status *);
+int tape_tapefd_weof(int, off_t);
+ssize_t tape_tapefd_write(int, const void *, size_t);
+int tape_tapefd_can_fork(int);
 
 #endif /* OUTPUT_TAPE_H */
index 54e2aa0c078520533357936641053686b4b1c5e2..97875701389181ad6c8b8df87d0c4a0631a0e22b 100644 (file)
  */
 
 /*
- * $Id: tapeio.c,v 1.53 2006/01/14 04:37:20 paddy_s Exp $
+ * $Id: tapeio.c,v 1.57 2006/07/06 15:04:18 martinea Exp $
  *
  * implements generic tape I/O functions
  */
 
 #include "amanda.h"
-#include <stdarg.h>
-#include <errno.h>
-
 #include "tapeio.h"
 #include "fileheader.h"
+
 #ifndef R_OK
 #define R_OK 4
 #define W_OK 2
 
 static struct virtualtape {
     char *prefix;
-    int (*xxx_tape_access) P((char *, int));
-    int (*xxx_tape_open) (char *, int, int);
-    int (*xxx_tape_stat) P((char *, struct stat *));
-    int (*xxx_tapefd_close) P((int));
-    int (*xxx_tapefd_fsf) P((int, int));
-    ssize_t (*xxx_tapefd_read) P((int, void *, size_t));
-    int (*xxx_tapefd_rewind) P((int));
-    void (*xxx_tapefd_resetofs) P((int));
-    int (*xxx_tapefd_unload) P((int));
-    int (*xxx_tapefd_status) P((int, struct am_mt_status *));
-    int (*xxx_tapefd_weof) P((int, int));
-    ssize_t (*xxx_tapefd_write) P((int, const void *, size_t));
-    int (*xxx_tapefd_can_fork) P((int));
+    int (*xxx_tape_access)(char *, int);
+    int (*xxx_tape_open)(char *, int, mode_t);
+    int (*xxx_tape_stat)(char *, struct stat *);
+    int (*xxx_tapefd_close)(int);
+    int (*xxx_tapefd_fsf)(int, off_t);
+    ssize_t (*xxx_tapefd_read)(int, void *, size_t);
+    int (*xxx_tapefd_rewind)(int);
+    void (*xxx_tapefd_resetofs)(int);
+    int (*xxx_tapefd_unload)(int);
+    int (*xxx_tapefd_status)(int, struct am_mt_status *);
+    int (*xxx_tapefd_weof)(int, off_t);
+    ssize_t (*xxx_tapefd_write)(int, const void *, size_t);
+    int (*xxx_tapefd_can_fork)(int);
 } vtable[] = {
   /* note: "tape" has to be the first entry because it is the
   **        default if no prefix match is found.
@@ -86,7 +84,11 @@ static struct virtualtape {
        file_tapefd_read, file_tapefd_rewind, file_tapefd_resetofs,
        file_tapefd_unload, file_tapefd_status, file_tapefd_weof,
         file_tapefd_write, file_tapefd_can_fork },
-  {NULL,},
+  {NULL, NULL, NULL, NULL,
+        NULL, NULL,
+       NULL, NULL, NULL,
+       NULL, NULL, NULL,
+       NULL, NULL}
 };
 
 static struct tape_info {
@@ -95,23 +97,28 @@ static struct tape_info {
     char *disk;
     int level;
     char *datestamp;
-    long length;
+    off_t length;
     char *tapetype;
     int fake_label;
     int ioctl_fork;
     int master_fd;
 } *tape_info = NULL;
-static int tape_info_count = 0;
+static struct tape_info **tape_info_p = &tape_info;
+
+static size_t tape_info_count = 0;
 
 static char *errstr = NULL;
 
+static void tape_info_init(void *ptr);
+static int name2slot(char *name, char **ntrans);
+
 /*
  * Additional initialization function for tape_info table.
  */
 
 static void
-tape_info_init(ptr)
-    void *ptr;
+tape_info_init(
+    void *ptr)
 {
     struct tape_info *t = ptr;
 
@@ -126,15 +133,16 @@ tape_info_init(ptr)
  */
 
 static int
-name2slot(name, ntrans)
-    char *name;
-    char **ntrans;
+name2slot(
+    char *name,
+    char **ntrans)
 {
     char *pc;
-    int len, i;
+    size_t len;
+    int i;
 
     if(0 != (pc = strchr(name, ':'))) {
-        len = pc - name;
+        len = (size_t)(pc - name);
        for( i = 0 ; vtable[i].prefix && vtable[i].prefix[0]; i++ ) {
            if(0 == strncmp(vtable[i].prefix, name , len)
                && '\0' == vtable[i].prefix[len]) {
@@ -157,10 +165,12 @@ name2slot(name, ntrans)
  */
 
 int
-tapeio_init_devname(char * dev,
-                   char **dev_left,
-                   char **dev_right,
-                   char **dev_next) {
+tapeio_init_devname(
+    char * dev,
+    char **dev_left,
+    char **dev_right,
+    char **dev_next)
+{
     int ch;
     char *p;
     int depth;
@@ -174,7 +184,9 @@ tapeio_init_devname(char * dev,
        depth = 1;
        p++;
        while(depth > 0) {
-           while((ch = *p++) != '\0' && ch != '{' && ch != '}') {}
+           ch = *p++;
+           while((ch != '\0') && (ch != '{') && (ch != '}'))
+               ch = *p++;
            if(ch == '\0') {
                /*
                 * Did not find a matching '}'.
@@ -214,9 +226,11 @@ tapeio_init_devname(char * dev,
  */
 
 char *
-tapeio_next_devname(char * dev_left,
-                   char * dev_right,
-                   char **dev_next) {
+tapeio_next_devname(
+    char * dev_left,
+    char * dev_right,
+    char **dev_next)
+{
     int ch;
     char *next;
     char *p;
@@ -225,7 +239,9 @@ tapeio_next_devname(char * dev_left,
     p = next = *dev_next;                      /* remember the start point */
     depth = 0;
     do {
-       while((ch = *p++) != '\0' && ch != '{' && ch != '}' && ch != ',') {}
+       ch = *p++;
+       while((ch != '\0') && (ch != '{') && (ch != '}') && (ch != ','))
+           ch = *p++;
        if(ch == '\0') {
            /*
             * Found the end of a name.
@@ -258,13 +274,13 @@ tapeio_next_devname(char * dev_left,
  */
 
 char *
-tapefd_getinfo_host(fd)
-    int fd;
+tapefd_getinfo_host(
+    int fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     if(tape_info[fd].master_fd != -1)
@@ -273,14 +289,14 @@ tapefd_getinfo_host(fd)
 }
 
 void
-tapefd_setinfo_host(fd, v)
-    int fd;
-    char *v;
+tapefd_setinfo_host(
+    int fd,
+    char *v)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     amfree(tape_info[fd].host);
@@ -290,13 +306,13 @@ tapefd_setinfo_host(fd, v)
 }
 
 char *
-tapefd_getinfo_disk(fd)
-    int fd;
+tapefd_getinfo_disk(
+    int fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     if(tape_info[fd].master_fd != -1)
@@ -305,14 +321,14 @@ tapefd_getinfo_disk(fd)
 }
 
 void
-tapefd_setinfo_disk(fd, v)
-    int fd;
-    char *v;
+tapefd_setinfo_disk(
+    int fd,
+    char *v)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     amfree(tape_info[fd].disk);
@@ -322,13 +338,13 @@ tapefd_setinfo_disk(fd, v)
 }
 
 int
-tapefd_getinfo_level(fd)
-    int fd;
+tapefd_getinfo_level(
+    int fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     if(tape_info[fd].master_fd != -1)
@@ -337,163 +353,163 @@ tapefd_getinfo_level(fd)
 }
 
 void
-tapefd_setinfo_level(fd, v)
-    int fd;
-    int v;
+tapefd_setinfo_level(
+    int fd,
+    int v)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     tape_info[fd].level = v;
 }
 
 char *
-tapefd_getinfo_datestamp(fd)
-    int fd;
+tapefd_getinfo_datestamp(
+    int fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     return tape_info[fd].datestamp;
 }
 
 void
-tapefd_setinfo_datestamp(fd, v)
-    int fd;
-    char *v;
+tapefd_setinfo_datestamp(
+    int fd,
+    char *v)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     tape_info[fd].datestamp = newstralloc(tape_info[fd].datestamp, v);
 }
 
-long
-tapefd_getinfo_length(fd)
-    int fd;
+off_t
+tapefd_getinfo_length(
+    int fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     return tape_info[fd].length;
 }
 
 void
-tapefd_setinfo_length(fd, v)
-    int fd;
-    long v;
+tapefd_setinfo_length(
+    int fd,
+    off_t v)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     tape_info[fd].length = v;
 }
 
 char *
-tapefd_getinfo_tapetype(fd)
-    int fd;
+tapefd_getinfo_tapetype(
+    int fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     return tape_info[fd].tapetype;
 }
 
 void
-tapefd_setinfo_tapetype(fd, v)
-    int fd;
-    char *v;
+tapefd_setinfo_tapetype(
+    int fd,
+    char *v)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     tape_info[fd].tapetype = newstralloc(tape_info[fd].tapetype, v);
 }
 
 int
-tapefd_getinfo_fake_label(fd)
-    int fd;
+tapefd_getinfo_fake_label(
+    int fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     return tape_info[fd].fake_label;
 }
 
 void
-tapefd_setinfo_fake_label(fd, v)
-    int fd;
-    int v;
+tapefd_setinfo_fake_label(
+    int fd,
+    int v)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     tape_info[fd].fake_label = v;
 }
 
 int
-tapefd_getinfo_ioctl_fork(fd)
-    int fd;
+tapefd_getinfo_ioctl_fork(
+    int fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     return tape_info[fd].ioctl_fork;
 }
 
 void
-tapefd_setinfo_ioctl_fork(fd, v)
-    int fd;
-    int v;
+tapefd_setinfo_ioctl_fork(
+    int fd,
+    int v)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     tape_info[fd].ioctl_fork = v;
 }
 
 void
-tapefd_set_master_fd(fd, master_fd)
-    int fd;
-    int master_fd;
+tapefd_set_master_fd(
+    int fd,
+    int master_fd)
 {
-    amtable_alloc((void **)&tape_info,
+    amtable_alloc((void **)tape_info_p,
                  &tape_info_count,
-                 sizeof(*tape_info),
-                 fd + 1,
+                 SIZEOF(*tape_info),
+                 (size_t)fd + 1,
                  10,
                  tape_info_init);
     tape_info[fd].master_fd = master_fd;
@@ -505,9 +521,9 @@ tapefd_set_master_fd(fd, master_fd)
  */
 
 int
-tape_access(filename, mode)
-    char *filename;
-    int mode;
+tape_access(
+    char *filename,
+    int mode)
 {
     char *tname;
     int vslot;
@@ -517,9 +533,9 @@ tape_access(filename, mode)
 }
 
 int
-tape_stat(filename, buf)
-    char *filename;
-    struct stat *buf;
+tape_stat(
+    char *filename,
+    struct stat *buf)
 {
     char *tname;
     int vslot;
@@ -529,24 +545,26 @@ tape_stat(filename, buf)
 }
 
 int
-tape_open(char *filename, int mode, ...)
+tape_open(
+    char *filename,
+    int mode, ...)
 {
     char *tname;
     int vslot;
     int fd;
-    int mask;
+    mode_t mask;
     va_list ap;
 
     va_start(ap, mode);
-    mask = va_arg(ap, int);
+    mask = (mode_t)va_arg(ap, int);
     va_end(ap);
 
     vslot = name2slot(filename, &tname);
     if((fd = vtable[vslot].xxx_tape_open(tname, mode, mask)) >= 0) {
-       amtable_alloc((void **)&tape_info,
+       amtable_alloc((void **)tape_info_p,
                      &tape_info_count,
-                     sizeof(*tape_info),
-                     fd + 1,
+                     SIZEOF(*tape_info),
+                     (size_t)(fd + 1),
                      10,
                      tape_info_init);
        /*
@@ -562,175 +580,185 @@ tape_open(char *filename, int mode, ...)
 }
 
 int
-tapefd_close(fd)
-    int fd;
+tapefd_close(
+    int fd)
 {
-    int vslot, res = -1;
+    int        res;
+    int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || ((vslot = tape_info[fd].vtape_index) < 0)) {
        errno = EBADF;
        return -1;
     }
+
+    vslot = tape_info[fd].vtape_index;
     if((res = vtable[vslot].xxx_tapefd_close(fd)) == 0) {
        amfree(tape_info[fd].host);
        amfree(tape_info[fd].disk);
        amfree(tape_info[fd].datestamp);
        amfree(tape_info[fd].tapetype);
-       memset(tape_info + fd, 0, sizeof(*tape_info));
+       memset(tape_info + fd, 0, SIZEOF(*tape_info));
         tape_info_init((void *)(tape_info + fd));
     }
     return res;
 }
 
 int
-tapefd_can_fork(fd)
-    int fd;
+tapefd_can_fork(
+    int fd)
 {
-    int vslot, res = -1;
+    int        vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;
        return -1;
     }
-    res = vtable[vslot].xxx_tapefd_can_fork(fd);
 
-    return res;
+    vslot = tape_info[fd].vtape_index;
+    return vtable[vslot].xxx_tapefd_can_fork(fd);
 }
 
 int
-tapefd_fsf(fd, count)
-    int fd;
-    int count;
+tapefd_fsf(
+    int fd,
+    off_t count)
 {
     int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;
        return -1;
     }
+
+    vslot = tape_info[fd].vtape_index;
     return vtable[vslot].xxx_tapefd_fsf(fd, count);
 }
 
 int
-tapefd_rewind(fd)
-    int fd;
+tapefd_rewind(
+    int fd)
 {
     int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;
        return -1;
     }
+
+    vslot = tape_info[fd].vtape_index;
     return vtable[vslot].xxx_tapefd_rewind(fd);
 }
 
 void
-tapefd_resetofs(fd)
-    int fd;
+tapefd_resetofs(
+    int fd)
 {
     int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;                          /* not that it matters */
        return;
     }
+
+    vslot = tape_info[fd].vtape_index;
     vtable[vslot].xxx_tapefd_resetofs(fd);
 }
 
 int
-tapefd_unload(fd)
-    int fd;
+tapefd_unload(
+    int fd)
 {
     int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;
        return -1;
     }
+
+    vslot = tape_info[fd].vtape_index;
     return vtable[vslot].xxx_tapefd_unload(fd);
 }
 
 int
-tapefd_status(fd, stat)
-    int fd;
-    struct am_mt_status *stat;
+tapefd_status(
+    int fd,
+    struct am_mt_status *stat)
 {
     int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;
        return -1;
     }
+
+    vslot = tape_info[fd].vtape_index;
     return vtable[vslot].xxx_tapefd_status(fd, stat);
 }
 
 int
-tapefd_weof(fd, count)
-    int fd;
-    int count;
+tapefd_weof(
+    int fd,
+    off_t count)
 {
     int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;
        return -1;
     }
+
+    vslot = tape_info[fd].vtape_index;
     return vtable[vslot].xxx_tapefd_weof(fd, count);
-}
+} 
+
 
 ssize_t
-tapefd_read(fd, buffer, count)
-    int fd;
-    void *buffer;
-    size_t count;
+tapefd_read(
+    int fd,
+    void *buffer,
+    size_t count)
 {
     int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;
        return -1;
     }
+
+    vslot = tape_info[fd].vtape_index;
     return vtable[vslot].xxx_tapefd_read(fd, buffer, count);
 }
 
 ssize_t
-tapefd_write(fd, buffer, count)
-    int fd;
-    const void *buffer;
-    size_t count;
+tapefd_write(
+    int fd,
+    const void *buffer,
+    size_t count)
 {
     int vslot;
 
-    if(fd < 0
-       || fd >= tape_info_count
-       || (vslot = tape_info[fd].vtape_index) < 0) {
+    if ((fd < 0) || ((size_t)fd >= tape_info_count)
+       || (tape_info[fd].vtape_index < 0)) {
        errno = EBADF;
        return -1;
     }
+
+    vslot = tape_info[fd].vtape_index;
     return vtable[vslot].xxx_tapefd_write(fd, buffer, count);
 }
 
 char *
-tape_rewind(devname)
-    char *devname;
+tape_rewind(
+    char *devname)
 {
     int fd;
     char *r = NULL;
@@ -757,8 +785,8 @@ tape_rewind(devname)
 }
 
 char *
-tape_unload(devname)
-    char *devname;
+tape_unload(
+    char *devname)
 {
     int fd;
     char *r = NULL;
@@ -785,9 +813,9 @@ tape_unload(devname)
 }
 
 char *
-tape_fsf(devname, count)
-    char *devname;
-    int count;
+tape_fsf(
+    char *devname,
+    off_t count)
 {
     int fd;
     char count_str[NUM_STR_SIZE];
@@ -801,7 +829,8 @@ tape_fsf(devname, count)
                                  strerror(errno),
                                  NULL);
     } else if(tapefd_fsf(fd, count) == -1) {
-       snprintf(count_str, sizeof(count_str), "%d", count);
+       snprintf(count_str, SIZEOF(count_str), OFF_T_FMT,
+                                (OFF_T_FMT_TYPE)count);
        r = errstr = newvstralloc(errstr,
                                  "tape_fsf: fsf ",
                                  count_str,
@@ -821,12 +850,12 @@ tape_fsf(devname, count)
    string will start with NOT_AMANDA_TAPE_MSG. */
 
 char *
-tapefd_rdlabel(fd, datestamp, label)
-    int fd;
-    char **datestamp;
-    char **label;
+tapefd_rdlabel(
+    int fd,
+    char **datestamp,
+    char **label)
 {
-    int rc;
+    ssize_t rc;
     size_t buflen;
     char *buffer = NULL;
     dumpfile_t file;
@@ -851,7 +880,7 @@ tapefd_rdlabel(fd, datestamp, label)
        /* make sure buffer is null-terminated */
        buffer[rc] = '\0';
 
-       parse_file_header(buffer, &file, rc);
+       parse_file_header(buffer, &file, (size_t)rc);
        if(file.type != F_TAPESTART) {
            r = stralloc(NOT_AMANDA_TAPE_MSG);
        } else {
@@ -860,15 +889,16 @@ tapefd_rdlabel(fd, datestamp, label)
        }
     }
     amfree(buffer);
-    errstr = newvstralloc(errstr, r, NULL);
+    if (r)
+       errstr = newvstralloc(errstr, r, NULL);
     return r;
 }
 
 char *
-tape_rdlabel(devname, datestamp, label)
-    char *devname;
-    char **datestamp;
-    char **label;
+tape_rdlabel(
+    char *devname,
+    char **datestamp,
+    char **label)
 {
     int fd;
     char *r = NULL;
@@ -885,18 +915,19 @@ tape_rdlabel(devname, datestamp, label)
     if(fd >= 0) {
         tapefd_close(fd);
     }
-    errstr = newvstralloc(errstr, r, NULL);
+    if (r)
+       errstr = newvstralloc(errstr, r, NULL);
     return r;
 }
 
 char *
-tapefd_wrlabel(fd, datestamp, label, size)
-    int fd;
-    char *datestamp;
-    char *label;
-    unsigned int size;
+tapefd_wrlabel(
+    int fd,
+    char *datestamp,
+    char *label,
+    size_t size)
 {
-    int rc;
+    ssize_t rc;
     char *buffer = NULL;
     dumpfile_t file;
     char *r = NULL;
@@ -906,17 +937,17 @@ tapefd_wrlabel(fd, datestamp, label, size)
     } else {
        fh_init(&file);
        file.type = F_TAPESTART;
-       strncpy(file.datestamp, datestamp, sizeof(file.datestamp) - 1);
-       file.datestamp[sizeof(file.datestamp) - 1] = '\0';
-       strncpy(file.name, label, sizeof(file.name) - 1);
-       file.name[sizeof(file.name) - 1] = '\0';
+       strncpy(file.datestamp, datestamp, SIZEOF(file.datestamp) - 1);
+       file.datestamp[SIZEOF(file.datestamp) - 1] = '\0';
+       strncpy(file.name, label, SIZEOF(file.name) - 1);
+       file.name[SIZEOF(file.name) - 1] = '\0';
        buffer = alloc(size);
        file.blocksize = size;
        build_header(buffer, &file, size);
        tapefd_setinfo_host(fd, NULL);
        tapefd_setinfo_disk(fd, label);
        tapefd_setinfo_level(fd, -1);
-       if((rc = tapefd_write(fd, buffer, size)) != size) {
+       if((rc = tapefd_write(fd, buffer, size)) != (ssize_t)size) {
            r = errstr = newstralloc2(errstr,
                                      "writing label: ",
                                      (rc != -1) ? "short write"
@@ -928,11 +959,11 @@ tapefd_wrlabel(fd, datestamp, label, size)
 }
 
 char *
-tape_wrlabel(devname, datestamp, label, size)
-    char *devname;
-    char *datestamp;
-    char *label;
-    unsigned int size;
+tape_wrlabel(
+    char *devname,
+    char *datestamp,
+    char *label,
+    size_t size)
 {
     int fd;
     char *r = NULL;
@@ -952,20 +983,20 @@ tape_wrlabel(devname, datestamp, label, size)
 }
 
 char *
-tapefd_wrendmark(fd, datestamp, size)
-    int fd;
-    char *datestamp;
-    unsigned int size;
+tapefd_wrendmark(
+    int fd,
+    char *datestamp,
+    size_t size)
 {
-    int rc;
+    ssize_t rc;
     char *buffer = NULL;
     dumpfile_t file;
     char *r = NULL;
 
     fh_init(&file);
     file.type = F_TAPEEND;
-    strncpy(file.datestamp, datestamp, sizeof(file.datestamp) - 1);
-    file.datestamp[sizeof(file.datestamp) - 1] = '\0';
+    strncpy(file.datestamp, datestamp, SIZEOF(file.datestamp) - 1);
+    file.datestamp[SIZEOF(file.datestamp) - 1] = '\0';
     buffer = alloc(size);
     file.blocksize = size;
     build_header(buffer, &file, size);
@@ -973,7 +1004,7 @@ tapefd_wrendmark(fd, datestamp, size)
     tapefd_setinfo_disk(fd, "TAPEEND");
     tapefd_setinfo_level(fd, -1);
 
-    if((rc = tapefd_write(fd, buffer, size)) != size) {
+    if((rc = tapefd_write(fd, buffer, size)) != (ssize_t)size) {
        r = errstr = newstralloc2(errstr, "writing endmark: ",
                                  (rc != -1) ? "short write" : strerror(errno));
     }
@@ -983,10 +1014,10 @@ tapefd_wrendmark(fd, datestamp, size)
 }
 
 char *
-tape_wrendmark(devname, datestamp, size)
-    char *devname;
-    char *datestamp;
-    unsigned int size;
+tape_wrendmark(
+    char *devname,
+    char *datestamp,
+    size_t size)
 {
     int fd;
     char *r = NULL;
@@ -1006,8 +1037,8 @@ tape_wrendmark(devname, datestamp, size)
 }
 
 char *
-tape_writable(devname)
-    char *devname;
+tape_writable(
+    char *devname)
 {
     int fd = -1;
     char *r = NULL;
@@ -1049,7 +1080,7 @@ tape_writable(devname)
 static char *pgm;
 
 static void
-do_help()
+do_help(void)
 {
     fprintf(stderr, "  ?|help\n");
     fprintf(stderr, "  open [\"file\"|$TAPE [\"mode\":O_RDONLY]]\n");
@@ -1062,7 +1093,7 @@ do_help()
 }
 
 static void
-usage()
+usage(void)
 {
     fprintf(stderr, "usage: %s [-c cmd [args] [%% cmd [args] ...]]\n", pgm);
     do_help();
@@ -1079,20 +1110,20 @@ static char **token;
 static int token_count;
 
 static int fd = -1;
-static int current_file = 0;
-static int current_record = 0;
+static off_t current_file = (off_t)0;
+static off_t current_record = (off_t)0;
 
 static int have_length = 0;
-static int length = 0;
+static int length = (off_t)0;
 
 static int show_timestamp = 0;
 
 char write_buf[TEST_BLOCKSIZE];
 
 static void
-do_open()
+do_open(void)
 {
-    int mode;
+    mode_t mode;
     char *file;
 
     if(token_count < 2
@@ -1122,9 +1153,9 @@ do_open()
 }
 
 static void
-do_close()
+do_close(void)
 {
-    int result;
+    int        result;
 
     fprintf(stderr, "tapefd_close(): ");
     if((result = tapefd_close(fd)) < 0) {
@@ -1135,31 +1166,31 @@ do_close()
 }
 
 static void
-do_read()
+do_read(void)
 {
-    int result;
-    int count = 0;
+    ssize_t    result;
+    off_t count = (off_t)0;
     int have_count = 0;
-    char buf[sizeof(write_buf)];
+    char buf[SIZEOF(write_buf)];
     int *p;
-    int i;
+    off_t i;
     char *s;
     time_t then;
     struct tm *tm;
 
     if(token_count > 1 && strcmp(token[1], "all") != 0) {
-       count = atoi(token[1]);
+       count = OFF_T_ATOI(token[1]);
        have_count = 1;
     }
 
     p = (int *)buf;
     for(i = 0; (! have_count) || (i < count); i++) {
-       fprintf(stderr, "tapefd_read(%d): ", i);
-       if((result = tapefd_read(fd, buf, sizeof(buf))) < 0) {
+       fprintf(stderr, "tapefd_read(" OFF_T_FMT "): ", (OFF_T_FMT_TYPE)i);
+       if((result = tapefd_read(fd, buf, SIZEOF(buf))) < 0) {
            perror("");
            break;
        } else if(result == 0) {
-           fprintf(stderr, "%d (EOF)\n", result);
+           fprintf(stderr,  SSIZE_T_FMT" (EOF)\n", result);
            /*
             * If we were not given a count, EOF breaks the loop, otherwise
             * we keep trying (to test read after EOF handling).
@@ -1168,7 +1199,7 @@ do_read()
                break;
            }
        } else {
-           if(result == sizeof(buf)) {
+           if(result == (ssize_t)sizeof(buf)) {
                s = "OK";
            } else {
                s = "short read";
@@ -1181,7 +1212,7 @@ do_read()
             * the effort to deal with.
             */
            fprintf(stderr,
-                   "%d (%s): file %d: record %d",
+                   SSIZE_T_FMT " (%s): file %d: record %d",
                    result,
                    s,
                    p[0],
@@ -1204,28 +1235,28 @@ do_read()
 }
 
 static void
-do_write()
+do_write(void)
 {
-    int result;
-    int count;
-    int *p;
-    int i;
+    int        result;
+    off_t count;
+    off_t *p;
+    off_t i;
     char *s;
     time_t now;
     struct tm *tm;
 
     if(token_count > 1) {
-       count = atoi(token[1]);
+       count = OFF_T_ATOI(token[1]);
     } else {
-       count = 1;
+       count = (off_t)1;
     }
 
     if(token_count > 2 && strcmp(token[2], "+") != 0) {
-       current_file = atoi(token[2]);
+       current_file = OFF_T_ATOI(token[2]);
     }
 
     if(token_count > 3 && strcmp(token[3], "+") != 0) {
-       current_record = atoi(token[3]);
+       current_record = OFF_T_ATOI(token[3]);
     }
 
     if(token_count > 4 && token[4][0] != '\0') {
@@ -1240,25 +1271,25 @@ do_write()
        tapefd_setinfo_level(fd, atoi(token[6]));
     }
 
-    p = (int *)write_buf;
+    p = (off_t *)write_buf;
     time(&now);
     p[2] = now;
     tm = localtime(&now);
-    for(i = 0; i < count; i++, current_record++) {
+    for(i = 0; i < count; i++, (current_record += (off_t)1)) {
        p[0] = current_file;
        p[1] = current_record;
-       fprintf(stderr, "tapefd_write(%d): ", i);
-       if((result = tapefd_write(fd, write_buf, sizeof(write_buf))) < 0) {
+       fprintf(stderr, "tapefd_write(" OFF_T_FMT "): ", i);
+       if((result = tapefd_write(fd, write_buf, SIZEOF(write_buf))) < 0) {
            perror("");
            break;
        } else {
-           if(result == sizeof(write_buf)) {
+           if(result == (ssize_t)sizeof(write_buf)) {
                s = "OK";
            } else {
                s = "short write";
            }
            fprintf(stderr,
-                   "%d (%s): file %d: record %d",
+                   "%d (%s): file " OFF_T_FMT ": record " OFF_T_FMT,
                    result,
                    s,
                    p[0],
@@ -1279,83 +1310,83 @@ do_write()
 }
 
 static void
-do_fsf()
+do_fsf(void)
 {
-    int result;
-    int count;
+    int        result;
+    off_t count;
 
     if(token_count > 1) {
-       count = atoi(token[1]);
+       count = OFF_T_ATOI(token[1]);
     } else {
-       count = 1;
+       count = (off_t)1;
     }
 
-    fprintf(stderr, "tapefd_fsf(%d): ", count);
+    fprintf(stderr, "tapefd_fsf(" OFF_T_FMT "): ", (OFF_T_FMT_TYPE)count);
     if((result = tapefd_fsf(fd, count)) < 0) {
        perror("");
     } else {
        fprintf(stderr, "%d (OK)\n", result);
        current_file += count;
-       current_record = 0;
+       current_record = (off_t)0;
     }
 }
 
 static void
-do_weof()
+do_weof(void)
 {
-    int result;
-    int count;
+    int        result;
+    off_t count;
 
     if(token_count > 1) {
-       count = atoi(token[1]);
+       count = OFF_T_ATOI(token[1]);
     } else {
-       count = 1;
+       count = (off_t)1;
     }
 
-    fprintf(stderr, "tapefd_weof(%d): ", count);
+    fprintf(stderr, "tapefd_weof(" OFF_T_FMT "): ", count);
     if((result = tapefd_weof(fd, count)) < 0) {
        perror("");
     } else {
        fprintf(stderr, "%d (OK)\n", result);
        current_file += count;
-       current_record = 0;
+       current_record = (off_t)0;
     }
 }
 
 static void
-do_rewind()
+do_rewind(void)
 {
-    int result;
+    int        result;
 
     fprintf(stderr, "tapefd_rewind(): ");
     if((result = tapefd_rewind(fd)) < 0) {
        perror("");
     } else {
        fprintf(stderr, "%d (OK)\n", result);
-       current_file = 0;
-       current_record = 0;
+       current_file = (off_t)0;
+       current_record = (off_t)0;
     }
 }
 
 static void
-do_unload()
+do_unload(void)
 {
-    int result;
+    int        result;
 
     fprintf(stderr, "tapefd_unload(): ");
     if((result = tapefd_unload(fd)) < 0) {
        perror("");
     } else {
        fprintf(stderr, "%d (OK)\n", result);
-       current_file = -1;
-       current_record = -1;
+       current_file = (off_t)-1;
+       current_record = (off_t)-1;
     }
 }
 
 struct cmd {
     char *name;
     int min_chars;
-    void (*func)();
+    void (*func)(void);
 } cmd[] = {
     { "?",             0,      do_help },
     { "help",          0,      do_help },
@@ -1372,9 +1403,9 @@ struct cmd {
 };
 
 int
-main(argc, argv)
-    int argc;
-    char **argv;
+main(
+    int argc,
+    char **argv)
 {
     int ch;
     int cmdline = 0;
@@ -1424,17 +1455,17 @@ main(argc, argv)
            break;
        case 'l':
            have_length = 1;
-           length = atoi(optarg);
+           length = OFF_T_ATOI(optarg);
            j = strlen(optarg);
            if(j > 0) {
                switch(optarg[j-1] ) {
                case 'k':                               break;
-               case 'b': length /= 2;                  break;
-               case 'M': length *= 1024;               break;
-               default:  length /= 1024;               break;
+               case 'b': length /= (off_t)2;           break;
+               case 'M': length *= (off_t)1024;        break;
+               default:  length /= (off_t)1024;        break;
                }
            } else {
-               length /= 1024;
+               length /= (off_t)1024;
            }
            break;
        case 't':
@@ -1452,7 +1483,7 @@ main(argc, argv)
      */
     time(&now);
     srandom(now);
-    for(j = 0; j < sizeof(write_buf); j++) {
+    for(j = 0; j < (int)SIZEOF(write_buf); j++) {
        write_buf[j] = (char)random();
     }
 
@@ -1464,7 +1495,7 @@ main(argc, argv)
     while(1) {
        if(cmdline) {
            for(token_count = 1;
-               token_count < (sizeof(token_area) / sizeof(token_area[0]))
+               token_count < (int)(SIZEOF(token_area) / SIZEOF(token_area[0]))
                && optind < argc;
                token_count++, optind++) {
                if(strcmp(argv[optind], "%") == 0) {
@@ -1490,7 +1521,7 @@ main(argc, argv)
            }
            token_count = split(line,
                                token_area,
-                               sizeof(token_area) / sizeof(token_area[0]),
+                               SIZEOF(token_area) / SIZEOF(token_area[0]),
                                " ");
        }
        amfree(line);
index 564ab99d1cecc9554ff64afbf8e64a346f3aa778..5111d5aedd5c9d26d1c4b47665754ba788054ff2 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: tapeio.h,v 1.20 2005/12/21 19:07:51 paddy_s Exp $
+ * $Id: tapeio.h,v 1.21 2006/05/25 01:47:27 johnfranks Exp $
  *
  * interface for tapeio.c
  */
@@ -68,82 +68,82 @@ struct am_mt_status {
 #define        FAKE_LABEL      "[fake-label]"
 #define NO_LABEL        "[no-label-yet]"
 
-int tape_open (char *, int, ...);
+int tape_open(char *, int, ...);
 
-int tapefd_rewind P((int tapefd));
-int tapefd_unload P((int tapefd));
-int tapefd_fsf P((int tapefd, int count));
-int tapefd_weof P((int tapefd, int count));
+int tapefd_rewind(int tapefd);
+int tapefd_unload(int tapefd);
+int tapefd_fsf(int tapefd, off_t count);
+int tapefd_weof(int tapefd, off_t count);
 
-int tapefd_status P((int tapefd, struct am_mt_status *));
+int tapefd_status(int tapefd, struct am_mt_status *);
 
-void tapefd_resetofs P((int tapefd));
+void tapefd_resetofs(int tapefd);
 
-ssize_t tapefd_read P((int tapefd, void *buffer, size_t count));
-ssize_t tapefd_write P((int tapefd, const void *buffer, size_t count));
+ssize_t tapefd_read(int, void *, size_t);
+ssize_t tapefd_write(int tapefd, const void *buffer, size_t count);
 
-char *tapefd_rdlabel P((int tapefd, char **datestamp, char **label));
-char *tapefd_wrlabel P((int tapefd,
+char *tapefd_rdlabel(int tapefd, char **datestamp, char **label);
+char *tapefd_wrlabel(int tapefd,
                        char  *datestamp,
                        char  *label,
-                       unsigned int s));
+                       size_t s);
 
-char *auto_tapefd_label P((int tapefd, char **datestamp, char **label));
-char *auto_tape_label P((char *dev, char **datestamp, char **label));
+char *auto_tapefd_label(int tapefd, char **datestamp, char **label);
+char *auto_tape_label(char *dev, char **datestamp, char **label);
 
-char *tapefd_wrendmark P((int tapefd, char *datestamp, unsigned int s));
+char *tapefd_wrendmark(int tapefd, char *datestamp, size_t s);
 
-int tapefd_eof P((int tapefd));                /* just used in tapeio-test */
-int tapefd_close P((int tapefd));
-int tapefd_can_fork P((int tapefd));
+int tapefd_eof(int tapefd);            /* just used in tapeio-test */
+int tapefd_close(int tapefd);
+int tapefd_can_fork(int tapefd);
 
-char *tape_unload P((char *dev));
-char *tape_rewind P((char *dev));
-char *tape_fsf P((char *dev, int count));
-char *tape_rdlabel P((char *dev, char **datestamp, char **label));
-char *tape_wrlabel P((char *dev,
+char *tape_unload(char *dev);
+char *tape_rewind(char *dev);
+char *tape_fsf(char *dev, off_t count);
+char *tape_rdlabel(char *dev, char **datestamp, char **label);
+char *tape_wrlabel(char *dev,
                      char  *datestamp,
                      char  *label,
-                     unsigned int size));
-char *tape_wrendmark P((char *dev,
+                     size_t size);
+char *tape_wrendmark(char *dev,
                        char *datestamp,
-                       unsigned int size));
-char *tape_writable P((char *dev));
-
-int tape_access P((char *dev, int mode));
-int tape_stat P((char *filename, struct stat *buf));
-
-char *tapefd_getinfo_label P((int fd));
-void tapefd_setinfo_label P((int fd, char *v));
-char *tapefd_getinfo_host P((int fd));
-void tapefd_setinfo_host P((int fd, char *v));
-char *tapefd_getinfo_disk P((int fd));
-void tapefd_setinfo_disk P((int fd, char *v));
-int tapefd_getinfo_level P((int fd));
-void tapefd_setinfo_level P((int fd, int v));
-char *tapefd_getinfo_datestamp P((int fd));
-void tapefd_setinfo_datestamp P((int fd, char *v));
-long tapefd_getinfo_length P((int fd));
-void tapefd_setinfo_length P((int fd, long v));
-char *tapefd_getinfo_tapetype P((int fd));
-void tapefd_setinfo_tapetype P((int fd, char *v));
-int tapefd_getinfo_fake_label P((int fd));
-void tapefd_setinfo_fake_label P((int fd, int v));
-int tapefd_getinfo_ioctl_fork P((int fd));
-void tapefd_setinfo_ioctl_fork P((int fd, int v));
-void tapefd_set_master_fd P((int tapefd, int master_fd));
+                       size_t size);
+char *tape_writable(char *dev);
+
+int tape_access(char *dev, int mode);
+int tape_stat(char *filename, struct stat *buf);
+
+char *tapefd_getinfo_label(int fd);
+void tapefd_setinfo_label(int fd, char *v);
+char *tapefd_getinfo_host(int fd);
+void tapefd_setinfo_host(int fd, char *v);
+char *tapefd_getinfo_disk(int fd);
+void tapefd_setinfo_disk(int fd, char *v);
+int tapefd_getinfo_level(int fd);
+void tapefd_setinfo_level(int fd, int v);
+char *tapefd_getinfo_datestamp(int fd);
+void tapefd_setinfo_datestamp(int fd, char *v);
+off_t tapefd_getinfo_length(int fd);
+void tapefd_setinfo_length(int fd, off_t v);
+char *tapefd_getinfo_tapetype(int fd);
+void tapefd_setinfo_tapetype(int fd, char *v);
+int tapefd_getinfo_fake_label(int fd);
+void tapefd_setinfo_fake_label(int fd, int v);
+int tapefd_getinfo_ioctl_fork(int fd);
+void tapefd_setinfo_ioctl_fork(int fd, int v);
+void tapefd_set_master_fd(int tapefd, int master_fd);
 
 #ifdef HAVE_LINUX_ZFTAPE_H
-int is_zftape P((const char *filename));
+int is_zftape(const char *filename);
 #endif
 
-int tapeio_init_devname P((char * dev,
+int tapeio_init_devname(char * dev,
                           char **dev_left,
                           char **dev_right,
-                          char **dev_next));
-char *tapeio_next_devname P((char * dev_left,
+                          char **dev_next);
+char *tapeio_next_devname(char * dev_left,
                             char * dev_right,
-                            char **dev_next));
+                            char **dev_next);
 
 #define NOT_AMANDA_TAPE_MSG "not an amanda tape"
 #define CHECK_NOT_AMANDA_TAPE_MSG(x) (!BSTRNCMP(x, NOT_AMANDA_TAPE_MSG))
index dd4758187b91b398b3cb48265c3bc71dcefbe222..bf3673771fd209142602e9bee7f6e3be94c0ba2a 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: tapetype.c,v 1.24 2006/03/10 11:56:06 martinea Exp $
+ * $Id: tapetype.c,v 1.27 2006/08/24 01:57:16 paddy_s Exp $
  *
  * tests a tape in a given tape unit and prints a tapetype entry for
  * it.  */
@@ -41,11 +41,10 @@ static char *sProgName;
 static char *tapedev;
 static int fd;
 
-static int blockkb = 32;
-static int blocksize;
+static size_t blockkb = 32;
+static size_t blocksize;
 
 static char *randombytes = (char *) NULL;
-static char *prandombytes = (char *) NULL;
 
 #if USE_RAND
 /* If the C library does not define random(), try to use rand() by
@@ -56,43 +55,65 @@ static char *prandombytes = (char *) NULL;
 #define srandom(seed) srand(seed)
 #endif
 
-static void allocrandombytes() {
-  int i, j, page_size;
-  char *p;
+static char *getrandombytes(void);
+static int writeblock(int fd);
+static off_t writeblocks(int fd, off_t nblks);
+static void allocrandombytes(void);
+static void do_pass0(off_t size, time_t *seconds, int dorewind);
+static void do_pass(off_t size, off_t *blocks, off_t *files, time_t *seconds);
+static void help(void);
+static void initnotrandombytes(void);
+static void initrandombytes(void);
+static void show_progress(off_t *blocks, off_t *files);
+static void usage(void);
+
+int main(int argc, char **argv);
+
+static void
+allocrandombytes(void)
+{
+  size_t i;
+  size_t j;
+  size_t page_size;
+  char   *p;
 
   if (randombytes == (char *)NULL) {
 #if defined(HAVE_GETPAGESIZE)
-    page_size = getpagesize();
+    page_size = (size_t)getpagesize();
 #else
-    page_size = 1024;
+    page_size = (size_t)1024;
 #endif
     j = (NBLOCKS * blocksize) + page_size;     /* buffer space plus one page */
     j = am_round(j, page_size);                        /* even number of pages */
-    p = alloc(j);
-    i = (p - (char *)0) & (page_size - 1);     /* page boundary offset */
+    p = (char *)alloc(j);
+    i = (size_t)(p - (char *)0) & (page_size - 1);/* page boundary offset */
     if(i != 0) {
-      randombytes = p + page_size - i;         /* round up to page boundary */
+      randombytes = p + (page_size - i);       /* round up to page boundary */
     } else {
       randombytes = p;                         /* alloc already on boundary */
     }
-    prandombytes = p;
   }
 }
 
-static void initnotrandombytes() {
-  int i, j;
+static void
+initnotrandombytes(void)
+{
+  unsigned long i;
+  unsigned long j;
   char *p;
 
   allocrandombytes();
-  j =NBLOCKS * blocksize;
+  j = NBLOCKS * blocksize;
   p = randombytes;
   for(i=0; i < j; ++i) {
     *p++ = (char) (i % 256);
   }
 }
 
-static void initrandombytes() {
-  int i, j;
+static void
+initrandombytes(void)
+{
+  unsigned long i, j;
   char *p;
 
   allocrandombytes();
@@ -103,20 +124,23 @@ static void initrandombytes() {
   }
 }
 
-static char *getrandombytes() {
-  static int counter = 0;
+static char *
+getrandombytes(void)
+{
+  static unsigned long counter = 0;
 
   return randombytes + ((counter++ % NBLOCKS) * blocksize);
 }
 
 static int short_write;
 
-int writeblock(fd)
-     int fd;
+static int
+writeblock(
+    int                fd)
 {
-  size_t w;
+  ssize_t w;
 
-  if ((w = tapefd_write(fd, getrandombytes(), blocksize)) == blocksize) {
+  if ((w = tapefd_write(fd, getrandombytes(), blocksize)) == (ssize_t)blocksize) {
     return 1;
   }
   if (w >= 0) {
@@ -129,22 +153,26 @@ int writeblock(fd)
 
 
 /* returns number of blocks actually written */
-size_t writeblocks(int fd, size_t nblks)
+static off_t
+writeblocks(
+    int                fd,
+    off_t      nblks)
 {
-  size_t blks = 0;
+  off_t blks = (off_t)0;
 
   while (blks < nblks) {
     if (! writeblock(fd)) {
-      return 0;
+      return (off_t)0;
     }
-    blks++;
+    blks += (off_t)1;
   }
 
   return blks;
 }
 
 
-void usage()
+static void
+usage(void)
 {
   fputs("usage: ", stderr);
   fputs(sProgName, stderr);
@@ -152,45 +180,51 @@ void usage()
   fputs(" [-c]", stderr);
   fputs(" [-o]", stderr);
   fputs(" [-b blocksize]", stderr);
-  fputs(" [-e estsize]", stderr);
+  fputs(" -e estsize", stderr);
   fputs(" [-f tapedev]", stderr);
   fputs(" [-t typename]", stderr);
   fputc('\n', stderr);
 }
 
-void help()
+static void
+help(void)
 {
   usage();
-  fputs("\
-  -h                   display this message\n\
-  -c                   run hardware compression detection test only\n\
-  -o                   overwrite amanda tape\n\
-  -b blocksize         record block size (default: 32k)\n\
-  -e estsize           estimated tape size (default: 1g == 1024m)\n\
-  -f tapedev           tape device name (default: $TAPE)\n\
-  -t typename          tapetype name (default: unknown-tapetype)\n\
-\n\
-Note: disable hardware compression when running this program.\n\
-", stderr);
+  fputs("-h                    display this message\n"
+       "-c                     run hardware compression detection test only\n"
+       "-o                     overwrite amanda tape\n"
+       "-b blocksize           record block size (default: 32k)\n"
+       "-e estsize             estimated tape size (No default!)\n"
+       "-f tapedev             tape device name (default: $TAPE)\n"
+       "-t typename            tapetype name (default: unknown-tapetype)\n"
+       "\n"
+       "Note: disable hardware compression when running this program.\n",
+       stderr);
 }
 
 
 int do_tty;
 
-void show_progress(blocks, files)
-  size_t *blocks, *files;
+static void
+show_progress(
+    off_t *    blocks,
+    off_t *    files)
 {
-  fprintf(stderr, "wrote %ld %dKb block%s in %ld file%s",
-         (long)*blocks, blockkb, (*blocks == 1) ? "" : "s",
-         (long)*files, (*files == 1) ? "" : "s");
+  fprintf(stderr, "wrote " OFF_T_FMT " " SIZE_T_FMT "Kb block%s in " OFF_T_FMT " file%s",
+         (OFF_T_FMT_TYPE)*blocks,
+         (SIZE_T_FMT_TYPE)blockkb, (*blocks == (off_t)1) ? "" : "s",
+         (OFF_T_FMT_TYPE)*files, (*files == (off_t)1) ? "" : "s");
 }
 
 
-void do_pass(size, blocks, files, seconds)
-  size_t size, *blocks, *files;
-  time_t *seconds;
+static void
+do_pass(
+    off_t      size,
+    off_t *    blocks,
+    off_t *    files,
+    time_t *   seconds)
 {
-  size_t blks;
+  off_t blks;
   time_t start, end;
   int save_errno;
 
@@ -204,10 +238,10 @@ void do_pass(size, blocks, files, seconds)
 
   while(1) {
 
-    if ((blks = writeblocks(fd, size)) <= 0 || tapefd_weof(fd, 1) != 0)
+    if ((blks = writeblocks(fd, size)) <= (off_t)0 || tapefd_weof(fd, (off_t)1) != 0)
       break;
     *blocks += blks;
-    (*files)++;
+    *files += (off_t)1;
     if(do_tty) {
       putc('\r', stderr);
       show_progress(blocks, files);
@@ -217,7 +251,7 @@ void do_pass(size, blocks, files, seconds)
 
   time(&end);
 
-  if (*blocks == 0) {
+  if (*blocks == (off_t)0) {
     fprintf(stderr, "%s: could not write any data in this pass: %s\n",
            sProgName, short_write ? "short write" : strerror(save_errno));
     exit(1);
@@ -236,18 +270,19 @@ void do_pass(size, blocks, files, seconds)
     putc('\r', stderr);
   }
   show_progress(blocks, files);
-  fprintf(stderr, " in %ld second%s (%s)\n",
-         (long)*seconds, ((long)*seconds == 1) ? "" : "s",
+  fprintf(stderr, " in " TIME_T_FMT " second%s (%s)\n",
+         (TIME_T_FMT_TYPE)*seconds, (*seconds == 1) ? "" : "s",
          short_write ? "short write" : strerror(save_errno));
 }
 
 
-void do_pass0(size, seconds, dorewind)
-  size_t size;
-  time_t *seconds;
-  int dorewind;
+static void
+do_pass0(
+    off_t      size,
+    time_t *   seconds,
+    int                dorewind)
 {
-  size_t blks;
+  off_t blks;
   time_t start, end;
   int save_errno;
 
@@ -260,13 +295,13 @@ void do_pass0(size, seconds, dorewind)
   time(&start);
 
   blks = writeblocks(fd, size);
-  tapefd_weof(fd, 1);
+  tapefd_weof(fd, (off_t)1);
 
   save_errno = errno;
 
   time(&end);
 
-  if (blks <= 0) {
+  if (blks <= (off_t)0) {
     fprintf(stderr, "%s: could not write any data in this pass: %s\n",
            sProgName, short_write ? "short write" : strerror(save_errno));
     exit(1);
@@ -284,29 +319,30 @@ void do_pass0(size, seconds, dorewind)
 }
 
 
-int main(argc, argv)
-     int argc;
-     char *argv[];
+int
+main(
+    int                argc,
+    char **    argv)
 {
-  size_t pass1blocks = 0;
-  size_t pass2blocks = 0;
+  off_t pass1blocks = (off_t)0;
+  off_t pass2blocks = (off_t)0;
   time_t pass1time;
   time_t pass2time;
   time_t timediff;
-  size_t pass1files = 0;
-  size_t pass2files = 0;
-  size_t estsize;
-  size_t pass0size;
-  size_t pass1size;
-  size_t pass2size;
-  size_t blockdiff;
-  size_t filediff;
-  long filemark;
-  long speed;
-  size_t size;
+  off_t pass1files = (off_t)0;
+  off_t pass2files = (off_t)0;
+  off_t estsize;
+  off_t pass0size;
+  off_t pass1size;
+  off_t pass2size;
+  off_t blockdiff;
+  off_t filediff;
+  size_t filemark;
+  unsigned long speed;
+  off_t size;
   char *sizeunits;
   int ch;
-  char *suffix;
+  char *suffix = NULL;
   char *typename;
   time_t now;
   int hwcompr = 0;
@@ -327,72 +363,97 @@ int main(argc, argv)
   /* Don't die when child closes pipe */
   signal(SIGPIPE, SIG_IGN);
 
-  estsize = 1024 * 1024;                       /* assume 1 GByte for now */
+  estsize = (off_t)0;
   tapedev = getenv("TAPE");
   typename = "unknown-tapetype";
 
   while ((ch = getopt(argc, argv, "b:e:f:t:hco")) != EOF) {
     switch (ch) {
     case 'b':
-      blockkb = strtol(optarg, &suffix, 0);
-      if (*suffix == '\0' || *suffix == 'k' || *suffix == 'K') {
-      } else if (*suffix == 'm' || *suffix == 'M') {
-       blockkb *= 1024;
-      } else if (*suffix == 'g' || *suffix == 'G') {
-       blockkb *= 1024 * 1024;
-      } else {
-       fprintf(stderr, "%s: unknown size suffix \'%c\'\n", sProgName, *suffix);
-       return 1;
+      blockkb = (size_t)strtol(optarg, &suffix, 0);
+      if (!(*suffix == '\0' || *suffix == 'k' || *suffix == 'K')) {
+       if (*suffix == 'm' || *suffix == 'M') {
+         blockkb *= 1024;
+       } else if (*suffix == 'g' || *suffix == 'G') {
+         blockkb *= (1024 * 1024);
+       } else {
+         fprintf(stderr, "%s: unknown size suffix \'%c\'\n",
+                 sProgName, *suffix);
+         return 1;
+       }
       }
       break;
     case 'e':
-      estsize = strtol(optarg, &suffix, 0);
-      if (*suffix == '\0' || *suffix == 'k' || *suffix == 'K') {
-      } else if (*suffix == 'm' || *suffix == 'M') {
-       estsize *= 1024;
-      } else if (*suffix == 'g' || *suffix == 'G') {
-       estsize *= 1024 * 1024;
-      } else {
-       fprintf(stderr, "%s: unknown size suffix \'%c\'\n", sProgName, *suffix);
-       return 1;
+      estsize = OFF_T_STRTOL(optarg, &suffix, 0);
+      if (!(*suffix == '\0' || *suffix == 'k' || *suffix == 'K')) {
+       if (*suffix == 'm' || *suffix == 'M') {
+         estsize *= (off_t)1024;
+       } else if (*suffix == 'g' || *suffix == 'G') {
+         estsize *= (off_t)(1024 * 1024);
+       } else {
+         fprintf(stderr, "%s: unknown size suffix \'%c\'\n",
+                 sProgName, *suffix);
+         return 1;
+       }
       }
       break;
+
     case 'f':
       tapedev = stralloc(optarg);
       break;
+
     case 't':
       typename = stralloc(optarg);
       break;
+
     case 'c':
       comprtstonly = 1;
       break;
+
     case 'h':
       help();
       return 1;
-      break;
+
     case 'o':
       overwrite_label=1;
       break;
+
     default:
       fprintf(stderr, "%s: unknown option \'%c\'\n", sProgName, ch);
-      /* fall through to ... */
+      /*FALLTHROUGH*/
+
     case '?':
       usage();
       return 1;
-      break;
     }
   }
   blocksize = blockkb * 1024;
 
-  if (tapedev == NULL || optind < argc) {
+  if (tapedev == NULL) {
+    fprintf(stderr, "%s: No tapedev specified\n", sProgName);
+    usage();
+    return 1;
+  }
+  if (optind < argc) {
     usage();
     return 1;
   }
 
+  if (estsize == 0) {
+    if (comprtstonly) {
+      estsize = (off_t)(1024 * 1024);          /* assume 1 GByte for now */
+    } else {
+      fprintf(stderr, "%s: please specify estimated tape capacity (e.g. '-e 4g')\n", sProgName);
+      usage();
+      return 1;
+    }
+  }
+
+
 /* verifier tape */
 
 
-  fd = tape_open(tapedev, O_RDONLY);
+  fd = tape_open(tapedev, O_RDONLY, 0);
   if (fd == -1) {
     fprintf(stderr, "%s: could not open %s: %s\n",
            sProgName, tapedev, strerror(errno));
@@ -426,7 +487,7 @@ int main(argc, argv)
     return 1;
   }
 
-  fd = tape_open(tapedev, O_RDWR);
+  fd = tape_open(tapedev, O_RDWR, 0);
   if (fd == -1) {
     fprintf(stderr, "%s: could not open %s: %s\n",
            sProgName, tapedev, strerror(errno));
@@ -446,7 +507,7 @@ int main(argc, argv)
   initnotrandombytes();
 
   fprintf(stderr, "Estimate phase 1...");
-  pass0size = 8 * 1024 / blockkb;
+  pass0size = (off_t)(8 * 1024 / blockkb);
   pass1time = 0;
   pass2time = 0;
   /*
@@ -459,11 +520,11 @@ int main(argc, argv)
    */ 
   while (pass1time < 25 || ((100*(pass2time-pass1time)/pass2time) >= 10) ) {
     if (pass1time != 0) {
-      int i = pass1time;
+      time_t t = pass1time;
       do {
-         pass0size *= 2;
-         i *= 2;
-      } while (i < 25);
+         pass0size *= (off_t)2;
+         t *= 2;
+      } while (t < 25);
     }
     /*
      * first a dummy pass to rewind, stop, start and
@@ -471,27 +532,32 @@ int main(argc, argv)
      */
     do_pass0(pass0size, &pass2time, 1);
     do_pass0(pass0size, &pass1time, 0);
-    if (pass0size >= 10 * 1024 * 1024) {
+    if (pass0size >= (off_t)(10 * 1024 * 1024)) {
       fprintf(stderr,
        "\rTape device is too fast to detect hardware compression...\n");
       break;   /* avoid loops if tape is superfast or broken */
     }
   }
-  fprintf(stderr, "\rWriting %d Mbyte   compresseable data:  %d sec\n",
-       (int)(blockkb * pass0size / 1024), (int)pass1time);
+  fprintf(stderr,
+       "\rWriting " OFF_T_FMT " Mbyte   compresseable data:  "
+       TIME_T_FMT " sec\n",
+       (OFF_T_FMT_TYPE)((off_t)blockkb * pass0size / (off_t)1024),
+       (TIME_T_FMT_TYPE)pass1time);
 
   /*
    * now generate uncompressable data and try again
    */
   time(&now);
-  srandom(now);
+  srandom((unsigned)now);
   initrandombytes();
 
   fprintf(stderr, "Estimate phase 2...");
   do_pass0(pass0size, &pass2time, 1);  /* rewind and get drive streaming */
   do_pass0(pass0size, &pass2time, 0);
-  fprintf(stderr, "\rWriting %d Mbyte uncompresseable data:  %d sec\n",
-       (int)(blockkb * pass0size / 1024), (int)pass2time);
+  fprintf(stderr, "\rWriting " OFF_T_FMT
+       " Mbyte uncompresseable data:  " TIME_T_FMT " sec\n",
+       (OFF_T_FMT_TYPE)((off_t)blockkb * pass0size / (off_t)1024),
+       (TIME_T_FMT_TYPE)pass2time);
 
   /*
    * Compute the time difference between writing the compressable and
@@ -515,11 +581,15 @@ int main(argc, argv)
   /*
    * Inform about estimated time needed to run the remaining of this program
    */
-  fprintf(stderr, "Estimated time to write 2 * %lu Mbyte: ", (unsigned long) (estsize / 1024));
-  pass1time = (time_t)(2.0 * pass2time * estsize / (1.0 * pass0size * blockkb));
+  fprintf(stderr, "Estimated time to write 2 * %lu Mbyte: ", (unsigned long) (estsize / (off_t)1024));
+  pass1time = (time_t)(2.0 * (double)pass2time * (double)estsize /
+               (1.0 * (double)pass0size * (double)blockkb));
        /* avoid overflow and underflow by doing math in floating point */
-  fprintf(stderr, "%ld sec = ", pass1time);
-  fprintf(stderr, "%ld h %ld min\n", (pass1time/3600), ((pass1time%3600) / 60));
+  fprintf(stderr, TIME_T_FMT " sec = ",
+         (TIME_T_FMT_TYPE)pass1time);
+  fprintf(stderr, TIME_T_FMT " h " TIME_T_FMT " min\n",
+         (TIME_T_FMT_TYPE)(pass1time/(time_t)3600),
+         (TIME_T_FMT_TYPE)((pass1time%(time_t)3600) / (time_t)60));
 
   if (comprtstonly) {
        exit(hwcompr);
@@ -529,16 +599,16 @@ int main(argc, argv)
   /*
    * Do pass 1 -- write files that are 1% of the estimated size until error.
    */
-  pass1size = (estsize * 0.01) / blockkb;      /* 1% of estimate */
-  if(pass1size <= 0) {
-    pass1size = 2;                             /* strange end case */
+  pass1size = (off_t)(((double)estsize * 0.01) / (double)blockkb); /* 1% of estimate */
+  if(pass1size <= (off_t)0) {
+    pass1size = (off_t)2;                              /* strange end case */
   }
   do_pass(pass1size, &pass1blocks, &pass1files, &pass1time);
 
   /*
    * Do pass 2 -- write smaller files until error.
    */
-  pass2size = pass1size / 2;
+  pass2size = pass1size / (off_t)2;
   do_pass(pass2size, &pass2blocks, &pass2files, &pass2time);
 
   /*
@@ -554,7 +624,7 @@ int main(argc, argv)
      * 2 than in pass 1 since we wrote twice as many tape marks.  But
      * odd things happen, so make sure the result does not go negative.
      */
-    blockdiff = 0;
+    blockdiff = (off_t)0;
   } else {
     blockdiff = pass1blocks - pass2blocks;
   }
@@ -562,23 +632,24 @@ int main(argc, argv)
     /*
      * This should not happen, but just in case ...
      */
-    filediff = 1;
+    filediff = (off_t)1;
   } else {
     filediff = pass2files - pass1files;
   }
-  filemark = blockdiff * blockkb / filediff;
+  filemark = (size_t)((blockdiff * (off_t)blockkb) / filediff);
 
   /*
    * Compute the length as the average of the two pass sizes including
    * tape marks.
    */
-  size = ((pass1blocks * blockkb + filemark * pass1files)
-           + (pass2blocks * blockkb + filemark * pass2files)) / 2;
-  if (size >= 1024 * 1024 * 1000) {
-    size /= 1024 * 1024;
+  size = ((pass1blocks * (off_t)blockkb + (off_t)filemark * pass1files)
+           + (pass2blocks * (off_t)blockkb + (off_t)filemark * pass2files))
+          / (off_t)2;
+  if (size >= (off_t)(1024 * 1024 * 1000)) {
+    size /= (off_t)(1024 * 1024);
     sizeunits = "gbytes";
-  } else if (size >= 1024 * 1000) {
-    size /= 1024;
+  } else if (size >= (off_t)(1024 * 1000)) {
+    size /= (off_t)1024;
     sizeunits = "mbytes";
   } else {
     sizeunits = "kbytes";
@@ -587,8 +658,9 @@ int main(argc, argv)
   /*
    * Compute the speed as the average of the two passes.
    */
-  speed = (((double)pass1blocks * blockkb / pass1time)
-           + ((double)pass2blocks * blockkb / pass2time)) / 2;
+  speed = (unsigned long)((((double)pass1blocks
+          * (double)blockkb / (double)pass1time)
+           + ((double)pass2blocks * (double)blockkb / (double)pass2time)) / 2.0);
 
   /*
    * Dump the tapetype.
@@ -596,25 +668,22 @@ int main(argc, argv)
   printf("define tapetype %s {\n", typename);
   printf("    comment \"just produced by tapetype prog (hardware compression %s)\"\n",
        hwcompr ? "on" : "off");
-  printf("    length %ld %s\n", (long)size, sizeunits);
-  printf("    filemark %ld kbytes\n", filemark);
-  printf("    speed %ld kps\n", speed);
+  printf("    length " OFF_T_FMT " %s\n", (OFF_T_FMT_TYPE)size, sizeunits);
+  printf("    filemark " SIZE_T_FMT " kbytes\n", (SIZE_T_FMT_TYPE)filemark);
+  printf("    speed %lu kps\n", speed);
   printf("}\n");
 
   if (tapefd_rewind(fd) == -1) {
     fprintf(stderr, "%s: could not rewind %s: %s\n",
            sProgName, tapedev, strerror(errno));
-    free(randombytes);
     return 1;
   }
 
   if (tapefd_close(fd) == -1) {
     fprintf(stderr, "%s: could not close %s: %s\n",
            sProgName, tapedev, strerror(errno));
-    free(randombytes);
     return 1;
   }
 
-  free(randombytes);
   return 0;
 }